Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(502)

Side by Side Diff: media/mp4/aac.cc

Issue 10710002: Add HE AAC support to ISO BMFF. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Explicitly check if audio is AAC. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
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/mp4/aac.h"
6
7 #include "base/logging.h"
8 #include "media/base/bit_reader.h"
9 #include "media/mp4/rcheck.h"
10
11 // The following conversion table is extracted from ISO 14496 Part 3 -
12 // Table 1.16 — Sampling Frequency Index.
13 static const uint32 kFrequencyMap[] = {
14 96000, 88200, 64000, 48000, 44100, 32000, 24000,
15 22050, 16000, 12000, 11025, 8000, 7350
16 };
17
18 static ChannelLayout GetChannelLayout(uint8 channel_config) {
19 switch (channel_config) {
20 case 1:
21 return CHANNEL_LAYOUT_MONO;
22 case 2:
23 return CHANNEL_LAYOUT_STEREO;
24 case 3:
25 return CHANNEL_LAYOUT_SURROUND;
26 case 4:
27 return CHANNEL_LAYOUT_4_0;
28 case 5:
29 return CHANNEL_LAYOUT_5_0;
30 case 6:
31 return CHANNEL_LAYOUT_5_1;
32 case 8:
33 return CHANNEL_LAYOUT_7_1;
34 default:
35 break;
36 }
37
38 return CHANNEL_LAYOUT_UNSUPPORTED;
39 }
40
41 namespace media {
42
43 namespace mp4 {
44
45 AAC::AAC()
46 : profile_(0), frequency_index_(0), channel_config_(0), frequency_(0),
47 channel_layout_(CHANNEL_LAYOUT_UNSUPPORTED) {
48 }
49
50 AAC::~AAC() {
51 }
52
53 bool AAC::Parse(const std::vector<uint8>& data) {
54 BitReader reader;
55 uint8 extension_type = 0;
56 bool ps_present = false;
57 uint8 extension_frequency_index;
58
59 profile_ = 0;
60 frequency_index_ = 0;
61 frequency_ = 0;
62 channel_config_ = 0;
63
64 reader.Initialize(&data[0], data.size());
65
66 // The following code is written according to ISO 14496 Part 3 Table 1.13 -
67 // Syntax of AudioSpecificConfig.
68
69 // Read base configuration
70 RCHECK(reader.ReadBits(5, &profile_));
71 RCHECK(reader.ReadBits(4, &frequency_index_));
72 if (frequency_index_ == 0xf)
73 RCHECK(reader.ReadBits(24, &frequency_));
74 RCHECK(reader.ReadBits(4, &channel_config_));
75
76 extension_frequency_index = frequency_index_;
77
78 // Read extension configuration
79 if (profile_ == 5 || profile_ == 29) {
80 ps_present = (profile_ == 29);
81 extension_type = 5;
82 RCHECK(reader.ReadBits(4, &extension_frequency_index));
83 if (extension_frequency_index == 0xf)
84 RCHECK(reader.ReadBits(24, &frequency_));
85 RCHECK(reader.ReadBits(5, &profile_));
86 }
87
88 RCHECK(SkipDecoderGASpecificConfig(&reader));
89 RCHECK(SkipErrorSpecificConfig());
90
91 // Read extension configuration again
92 if (extension_type != 5 && reader.NumBitsLeft() >= 16) {
93 uint16 sync_extension_type;
94 uint8 sbr_present_flag;
95 uint8 ps_present_flag;
96
97 RCHECK(reader.ReadBits(11, &sync_extension_type));
98
99 if (sync_extension_type == 0x2b7) {
100 RCHECK(reader.ReadBits(5, &extension_type));
101
102 if (extension_type == 5) {
103 RCHECK(reader.ReadBits(1, &sbr_present_flag));
104
105 if (sbr_present_flag) {
106 RCHECK(reader.ReadBits(4, &extension_frequency_index));
107
108 if (extension_frequency_index == 0xf)
109 RCHECK(reader.ReadBits(24, &frequency_));
110
111 RCHECK(reader.ReadBits(11, &sync_extension_type));
112
113 if (sync_extension_type == 0x548) {
114 RCHECK(reader.ReadBits(1, &ps_present_flag));
115 ps_present = ps_present_flag != 0;
116 }
117 }
118 }
119 }
120 }
121
122 if (frequency_ == 0) {
123 RCHECK(extension_frequency_index < arraysize(kFrequencyMap));
124 frequency_ = kFrequencyMap[extension_frequency_index];
125 }
126
127 // When Parametric Stereo is on, mono will be played as stereo.
128 if (ps_present && channel_config_ == 1)
129 channel_layout_ = GetChannelLayout(channel_config_ + 1);
130 else
131 channel_layout_ = GetChannelLayout(channel_config_);
132
133 return frequency_ != 0 && channel_layout_ != CHANNEL_LAYOUT_UNSUPPORTED &&
134 profile_ >= 1 && profile_ <= 4 && frequency_index_ != 0xf &&
135 channel_config_ <= 7;
136 }
137
138 uint32 AAC::frequency() const {
139 return frequency_;
140 }
141
142 ChannelLayout AAC::channel_layout() const {
143 return channel_layout_;
144 }
145
146 bool AAC::ConvertEsdsToADTS(std::vector<uint8>* buffer) const {
147 size_t size = buffer->size() + 7;
148
149 DCHECK(profile_ >= 1 && profile_ <= 4 && frequency_index_ != 0xf &&
150 channel_config_ <= 7);
151
152 if (size > 8192)
acolwell GONE FROM CHROMIUM 2012/07/03 01:00:12 nit: Add a comment indicating what the significanc
153 return false;
154
155 std::vector<uint8>& adts = *buffer;
156
157 adts.insert(buffer->begin(), 7, 0);
158 adts[0] = 0xff;
159 adts[1] = 0xf1;
160 adts[2] = ((profile_ - 1) << 6) + (frequency_index_ << 2) +
161 (channel_config_ >> 2);
162 adts[3] = ((channel_config_ & 0x3) << 6) + (size >> 11);
163 adts[4] = (size & 0x7ff) >> 3;
164 adts[5] = ((size & 7) << 5) + 0x1f;
165 adts[6] = 0xfc;
166
167 return true;
168 }
169
170 // Currently this function only support GASpecificConfig defined in
171 // ISO 14496 Part 3 Table 4.1 – Syntax of GASpecificConfig()
172 bool AAC::SkipDecoderGASpecificConfig(BitReader* bit_reader) const {
173 switch (profile_) {
174 case 1:
175 case 2:
176 case 3:
177 case 4:
178 case 6:
179 case 7:
180 case 17:
181 case 19:
182 case 20:
183 case 21:
184 case 22:
185 case 23:
186 return SkipGASpecificConfig(bit_reader);
187 default:
188 break;
189 }
190
191 return false;
192 }
193
194 bool AAC::SkipErrorSpecificConfig() const {
195 switch (profile_) {
196 case 17:
197 case 19:
198 case 20:
199 case 21:
200 case 22:
201 case 23:
202 case 24:
203 case 25:
204 case 26:
205 case 27:
206 return false;
207 default:
208 break;
209 }
210
211 return true;
212 }
213
214 // The following code is written according to ISO 14496 part 3 Table 4.1 -
215 // GASpecificConfig.
216 bool AAC::SkipGASpecificConfig(BitReader* bit_reader) const {
217 uint8 extension_flag = 0;
218 uint8 depends_on_core_coder;
219
220 RCHECK(bit_reader->SkipBits(1)); // frameLengthFlag
221 RCHECK(bit_reader->ReadBits(1, &depends_on_core_coder));
222 if (depends_on_core_coder == 1)
223 RCHECK(bit_reader->SkipBits(14)); // coreCoderDelay
224
225 RCHECK(bit_reader->ReadBits(1, &extension_flag));
226 RCHECK(channel_config_ != 0);
227
228 if (profile_ == 6 || profile_ == 20)
229 RCHECK(bit_reader->SkipBits(3));
230
231 if (extension_flag) {
232 if (profile_ == 22) {
233 RCHECK(bit_reader->SkipBits(5));
234 RCHECK(bit_reader->SkipBits(11));
235 }
236
237 if (profile_ == 17 || profile_ == 19 || profile_ == 20 || profile_ == 23) {
238 RCHECK(bit_reader->SkipBits(1));
239 RCHECK(bit_reader->SkipBits(1));
240 RCHECK(bit_reader->SkipBits(1));
241 }
242
243 RCHECK(bit_reader->SkipBits(1));
244 }
245
246 return true;
247 }
248
249 } // namespace mp4
250
251 } // namespace media
OLDNEW
« media/mp4/aac.h ('K') | « media/mp4/aac.h ('k') | media/mp4/aac_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698