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

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: Remove unused entry from media.gyp 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
« no previous file with comments | « media/mp4/aac.h ('k') | media/mp4/aac_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // ADTS header uses 13 bits for packet size.
153 if (size > (1 << 13) - 1)
154 return false;
155
156 std::vector<uint8>& adts = *buffer;
157
158 adts.insert(buffer->begin(), 7, 0);
159 adts[0] = 0xff;
160 adts[1] = 0xf1;
161 adts[2] = ((profile_ - 1) << 6) + (frequency_index_ << 2) +
162 (channel_config_ >> 2);
163 adts[3] = ((channel_config_ & 0x3) << 6) + (size >> 11);
164 adts[4] = (size & 0x7ff) >> 3;
165 adts[5] = ((size & 7) << 5) + 0x1f;
166 adts[6] = 0xfc;
167
168 return true;
169 }
170
171 // Currently this function only support GASpecificConfig defined in
172 // ISO 14496 Part 3 Table 4.1 - Syntax of GASpecificConfig()
173 bool AAC::SkipDecoderGASpecificConfig(BitReader* bit_reader) const {
174 switch (profile_) {
175 case 1:
176 case 2:
177 case 3:
178 case 4:
179 case 6:
180 case 7:
181 case 17:
182 case 19:
183 case 20:
184 case 21:
185 case 22:
186 case 23:
187 return SkipGASpecificConfig(bit_reader);
188 default:
189 break;
190 }
191
192 return false;
193 }
194
195 bool AAC::SkipErrorSpecificConfig() const {
196 switch (profile_) {
197 case 17:
198 case 19:
199 case 20:
200 case 21:
201 case 22:
202 case 23:
203 case 24:
204 case 25:
205 case 26:
206 case 27:
207 return false;
208 default:
209 break;
210 }
211
212 return true;
213 }
214
215 // The following code is written according to ISO 14496 part 3 Table 4.1 -
216 // GASpecificConfig.
217 bool AAC::SkipGASpecificConfig(BitReader* bit_reader) const {
218 uint8 extension_flag = 0;
219 uint8 depends_on_core_coder;
220
221 RCHECK(bit_reader->SkipBits(1)); // frameLengthFlag
222 RCHECK(bit_reader->ReadBits(1, &depends_on_core_coder));
223 if (depends_on_core_coder == 1)
224 RCHECK(bit_reader->SkipBits(14)); // coreCoderDelay
225
226 RCHECK(bit_reader->ReadBits(1, &extension_flag));
227 RCHECK(channel_config_ != 0);
228
229 if (profile_ == 6 || profile_ == 20)
230 RCHECK(bit_reader->SkipBits(3));
231
232 if (extension_flag) {
233 if (profile_ == 22) {
234 RCHECK(bit_reader->SkipBits(5));
235 RCHECK(bit_reader->SkipBits(11));
236 }
237
238 if (profile_ == 17 || profile_ == 19 || profile_ == 20 || profile_ == 23) {
239 RCHECK(bit_reader->SkipBits(1));
240 RCHECK(bit_reader->SkipBits(1));
241 RCHECK(bit_reader->SkipBits(1));
242 }
243
244 RCHECK(bit_reader->SkipBits(1));
245 }
246
247 return true;
248 }
249
250 } // namespace mp4
251
252 } // namespace media
OLDNEW
« no previous file with comments | « 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