Upload upstream chromium 108.0.5359.1
[platform/framework/web/chromium-efl.git] / media / filters / ffmpeg_aac_bitstream_converter.cc
1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/filters/ffmpeg_aac_bitstream_converter.h"
6
7 #include "base/logging.h"
8 #include "media/ffmpeg/ffmpeg_common.h"
9
10 namespace media {
11
12 namespace {
13
14 // Creates an ADTS header and stores in |hdr|
15 // Assumes |hdr| points to an array of length |kAdtsHeaderSize|
16 // Returns false if parameter values are for an unsupported configuration.
17 bool GenerateAdtsHeader(int codec,
18                         int layer,
19                         int audio_profile,
20                         int sample_rate_index,
21                         int private_stream,
22                         int channel_configuration,
23                         int originality,
24                         int home,
25                         int copyrighted_stream,
26                         int copyright_start,
27                         int frame_length,
28                         int buffer_fullness,
29                         int number_of_frames_minus_one,
30                         uint8_t* hdr) {
31   DCHECK_EQ(codec, AV_CODEC_ID_AAC);
32
33   memset(reinterpret_cast<void *>(hdr), 0,
34          FFmpegAACBitstreamConverter::kAdtsHeaderSize);
35   // Ref: http://wiki.multimedia.cx/index.php?title=ADTS
36   // ADTS header structure is the following
37   // AAAAAAAA  AAAABCCD  EEFFFFGH  HHIJKLMM  MMMMMMMM  MMMOOOOO  OOOOOOPP
38   //
39   // A    Syncword 0xFFF, all bits must be 1
40   // B    MPEG Version: 0 for MPEG-4, 1 for MPEG-2
41   // C    Layer: always 0
42   // D    Protection absent: Set to 1 if no CRC and 0 if there is CRC.
43   // E    Profile: the MPEG-4 Audio Object Type minus 1.
44   // F    MPEG-4 Sampling Frequency Index (15 is forbidden)
45   // G    Private stream:
46   // H    MPEG-4 Channel Configuration
47   // I    Originality
48   // J    Home
49   // K    Copyrighted Stream
50   // L    Copyright_ start
51   // M    Frame length. This must include the ADTS header length.
52   // O    Buffer fullness
53   // P    Number of AAC frames in ADTS frame minus 1.
54   //      For maximum compatibility always use 1 AAC frame per ADTS frame.
55
56   // Syncword
57   hdr[0] = 0xFF;
58   hdr[1] = 0xF0;
59
60   // Layer is always 0. No further action required.
61
62   // Protection absent (no CRC) is always 1.
63   hdr[1] |= 1;
64
65   switch (audio_profile) {
66     case FF_PROFILE_AAC_MAIN:
67       break;
68     case FF_PROFILE_AAC_HE:
69     case FF_PROFILE_AAC_HE_V2:
70     case FF_PROFILE_AAC_LOW:
71       hdr[2] |= (1 << 6);
72       break;
73     case FF_PROFILE_AAC_SSR:
74       hdr[2] |= (2 << 6);
75       break;
76     case FF_PROFILE_AAC_LTP:
77       hdr[2] |= (3 << 6);
78       break;
79     default:
80       DLOG(ERROR) << "[" << __func__ << "] "
81                   << "unsupported audio profile:" << audio_profile;
82       return false;
83   }
84
85   hdr[2] |= ((sample_rate_index & 0xf) << 2);
86
87   if (private_stream)
88     hdr[2] |= (1 << 1);
89
90   switch (channel_configuration) {
91     case 1:
92       // front-center
93       hdr[3] |= (1 << 6);
94       break;
95     case 2:
96       // front-left, front-right
97       hdr[3] |= (2 << 6);
98       break;
99     case 3:
100       // front-center, front-left, front-right
101       hdr[3] |= (3 << 6);
102       break;
103     case 4:
104       // front-center, front-left, front-right, back-center
105       hdr[2] |= 1;
106       break;
107     case 5:
108       // front-center, front-left, front-right, back-left, back-right
109       hdr[2] |= 1;
110       hdr[3] |= (1 << 6);
111       break;
112     case 6:
113       // front-center, front-left, front-right, back-left, back-right,
114       // LFE-channel
115       hdr[2] |= 1;
116       hdr[3] |= (2 << 6);
117       break;
118     case 8:
119       // front-center, front-left, front-right, side-left, side-right,
120       // back-left, back-right, LFE-channel
121       hdr[2] |= 1;
122       hdr[3] |= (3 << 6);
123       break;
124     default:
125       DLOG(ERROR) << "[" << __func__ << "] "
126                   << "unsupported number of audio channels:"
127                   << channel_configuration;
128       return false;
129   }
130
131   if (originality)
132     hdr[3] |= (1 << 5);
133
134   if (home)
135     hdr[3] |= (1 << 4);
136
137   if (copyrighted_stream)
138     hdr[3] |= (1 << 3);
139
140   if (copyright_start)
141     hdr[3] |= (1 << 2);
142
143   // frame length
144   hdr[3] |= (frame_length >> 11) & 0x03;
145   hdr[4] = (frame_length >> 3) & 0xFF;
146   hdr[5] |= (frame_length & 7) << 5;
147
148   // buffer fullness
149   hdr[5] |= (buffer_fullness >> 6) & 0x1F;
150   hdr[6] |= (buffer_fullness & 0x3F) << 2;
151
152   hdr[6] |= number_of_frames_minus_one & 0x3;
153
154   return true;
155 }
156
157 }
158
159 FFmpegAACBitstreamConverter::FFmpegAACBitstreamConverter(
160     AVCodecParameters* stream_codec_parameters)
161     : stream_codec_parameters_(stream_codec_parameters),
162       header_generated_(false),
163       codec_(),
164       audio_profile_(),
165       sample_rate_index_(),
166       channel_configuration_(),
167       frame_length_() {
168   CHECK(stream_codec_parameters_);
169 }
170
171 FFmpegAACBitstreamConverter::~FFmpegAACBitstreamConverter() = default;
172
173 bool FFmpegAACBitstreamConverter::ConvertPacket(AVPacket* packet) {
174   if (packet == NULL || !packet->data) {
175     return false;
176   }
177
178   int header_plus_packet_size =
179       packet->size + kAdtsHeaderSize;
180   if (!stream_codec_parameters_->extradata) {
181     DLOG(ERROR) << "extradata is null";
182     return false;
183   }
184   if (stream_codec_parameters_->extradata_size < 2) {
185     DLOG(ERROR) << "extradata too small to contain MP4A header";
186     return false;
187   }
188   int sample_rate_index =
189       ((stream_codec_parameters_->extradata[0] & 0x07) << 1) |
190       ((stream_codec_parameters_->extradata[1] & 0x80) >> 7);
191   if (sample_rate_index > 12) {
192     sample_rate_index = 4;
193   }
194
195   if (!header_generated_ || codec_ != stream_codec_parameters_->codec_id ||
196       audio_profile_ != stream_codec_parameters_->profile ||
197       sample_rate_index_ != sample_rate_index ||
198       channel_configuration_ !=
199           stream_codec_parameters_->ch_layout.nb_channels ||
200       frame_length_ != header_plus_packet_size) {
201     header_generated_ =
202         GenerateAdtsHeader(stream_codec_parameters_->codec_id,
203                            0,  // layer
204                            stream_codec_parameters_->profile, sample_rate_index,
205                            0,  // private stream
206                            stream_codec_parameters_->ch_layout.nb_channels,
207                            0,  // originality
208                            0,  // home
209                            0,  // copyrighted_stream
210                            0,  // copyright_ start
211                            header_plus_packet_size,
212                            0x7FF,  // buffer fullness
213                            0,      // one frame per packet
214                            hdr_);
215     codec_ = stream_codec_parameters_->codec_id;
216     audio_profile_ = stream_codec_parameters_->profile;
217     sample_rate_index_ = sample_rate_index;
218     channel_configuration_ = stream_codec_parameters_->ch_layout.nb_channels;
219     frame_length_ = header_plus_packet_size;
220   }
221
222   // Inform caller if the header generation failed.
223   if (!header_generated_)
224     return false;
225
226   // Allocate new packet for the output.
227   AVPacket dest_packet;
228   if (av_new_packet(&dest_packet, header_plus_packet_size) != 0)
229     return false;  // Memory allocation failure.
230
231   memcpy(dest_packet.data, hdr_, kAdtsHeaderSize);
232   memcpy(reinterpret_cast<void*>(dest_packet.data + kAdtsHeaderSize),
233          reinterpret_cast<void*>(packet->data), packet->size);
234
235   // This is a bit tricky: since the interface does not allow us to replace
236   // the pointer of the old packet with a new one, we will initially copy the
237   // metadata from old packet to new bigger packet.
238   av_packet_copy_props(&dest_packet, packet);
239
240   // Release the old packet.
241   av_packet_unref(packet);
242
243   // Finally, replace the values in the input packet.
244   memcpy(packet, &dest_packet, sizeof(*packet));
245   return true;
246 }
247
248 }  // namespace media