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

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

Issue 10780026: Add HE AAC support to ISO BMFF. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Remove aac.h. 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 if (data.empty())
55 return false;
56
57 BitReader reader(&data[0], data.size());
58 uint8 extension_type = 0;
59 bool ps_present = false;
60 uint8 extension_frequency_index;
61
62 frequency_ = 0;
63
64 // The following code is written according to ISO 14496 Part 3 Table 1.13 -
65 // Syntax of AudioSpecificConfig.
66
67 // Read base configuration
68 RCHECK(reader.ReadBits(5, &profile_));
69 RCHECK(reader.ReadBits(4, &frequency_index_));
70 if (frequency_index_ == 0xf)
71 RCHECK(reader.ReadBits(24, &frequency_));
72 RCHECK(reader.ReadBits(4, &channel_config_));
73
74 extension_frequency_index = frequency_index_;
75
76 // Read extension configuration
77 if (profile_ == 5 || profile_ == 29) {
78 ps_present = (profile_ == 29);
79 extension_type = 5;
80 RCHECK(reader.ReadBits(4, &extension_frequency_index));
81 if (extension_frequency_index == 0xf)
82 RCHECK(reader.ReadBits(24, &frequency_));
83 RCHECK(reader.ReadBits(5, &profile_));
84 }
85
86 RCHECK(SkipDecoderGASpecificConfig(&reader));
87 RCHECK(SkipErrorSpecificConfig());
88
89 // Read extension configuration again
90 if (extension_type != 5) {
91 uint16 sync_extension_type;
92 uint8 sbr_present_flag;
93 uint8 ps_present_flag;
94
95 if (reader.ReadBits(11, &sync_extension_type) &&
96 sync_extension_type == 0x2b7) {
97 if (reader.ReadBits(5, &extension_type) && extension_type == 5) {
98 RCHECK(reader.ReadBits(1, &sbr_present_flag));
99
100 if (sbr_present_flag) {
101 RCHECK(reader.ReadBits(4, &extension_frequency_index));
102
103 if (extension_frequency_index == 0xf)
104 RCHECK(reader.ReadBits(24, &frequency_));
105
106 RCHECK(reader.ReadBits(11, &sync_extension_type));
107
108 if (sync_extension_type == 0x548) {
109 RCHECK(reader.ReadBits(1, &ps_present_flag));
110 ps_present = ps_present_flag != 0;
111 }
112 }
113 }
114 }
115 }
116
117 if (frequency_ == 0) {
118 RCHECK(extension_frequency_index < arraysize(kFrequencyMap));
119 frequency_ = kFrequencyMap[extension_frequency_index];
120 }
121
122 // When Parametric Stereo is on, mono will be played as stereo.
123 if (ps_present && channel_config_ == 1)
124 channel_layout_ = GetChannelLayout(2);
125 else
126 channel_layout_ = GetChannelLayout(channel_config_);
127
128 return frequency_ != 0 && channel_layout_ != CHANNEL_LAYOUT_UNSUPPORTED &&
129 profile_ >= 1 && profile_ <= 4 && frequency_index_ != 0xf &&
130 channel_config_ <= 7;
131 }
132
133 uint32 AAC::frequency() const {
134 return frequency_;
135 }
136
137 ChannelLayout AAC::channel_layout() const {
138 return channel_layout_;
139 }
140
141 bool AAC::ConvertEsdsToADTS(std::vector<uint8>* buffer) const {
142 size_t size = buffer->size() + 7;
143
144 DCHECK(profile_ >= 1 && profile_ <= 4 && frequency_index_ != 0xf &&
145 channel_config_ <= 7);
146
147 // ADTS header uses 13 bits for packet size.
148 if (size >= (1 << 13))
149 return false;
150
151 std::vector<uint8>& adts = *buffer;
152
153 adts.insert(buffer->begin(), 7, 0);
154 adts[0] = 0xff;
155 adts[1] = 0xf1;
156 adts[2] = ((profile_ - 1) << 6) + (frequency_index_ << 2) +
157 (channel_config_ >> 2);
158 adts[3] = ((channel_config_ & 0x3) << 6) + (size >> 11);
159 adts[4] = (size & 0x7ff) >> 3;
160 adts[5] = ((size & 7) << 5) + 0x1f;
161 adts[6] = 0xfc;
162
163 return true;
164 }
165
166 // Currently this function only support GASpecificConfig defined in
167 // ISO 14496 Part 3 Table 4.1 - Syntax of GASpecificConfig()
168 bool AAC::SkipDecoderGASpecificConfig(BitReader* bit_reader) const {
169 switch (profile_) {
170 case 1:
171 case 2:
172 case 3:
173 case 4:
174 case 6:
175 case 7:
176 case 17:
177 case 19:
178 case 20:
179 case 21:
180 case 22:
181 case 23:
182 return SkipGASpecificConfig(bit_reader);
183 default:
184 break;
185 }
186
187 return false;
188 }
189
190 bool AAC::SkipErrorSpecificConfig() const {
191 switch (profile_) {
192 case 17:
193 case 19:
194 case 20:
195 case 21:
196 case 22:
197 case 23:
198 case 24:
199 case 25:
200 case 26:
201 case 27:
202 return false;
203 default:
204 break;
205 }
206
207 return true;
208 }
209
210 // The following code is written according to ISO 14496 part 3 Table 4.1 -
211 // GASpecificConfig.
212 bool AAC::SkipGASpecificConfig(BitReader* bit_reader) const {
213 uint8 extension_flag = 0;
214 uint8 depends_on_core_coder;
215 uint16 dummy;
216
217 RCHECK(bit_reader->ReadBits(1, &dummy)); // frameLengthFlag
218 RCHECK(bit_reader->ReadBits(1, &depends_on_core_coder));
219 if (depends_on_core_coder == 1)
220 RCHECK(bit_reader->ReadBits(14, &dummy)); // coreCoderDelay
221
222 RCHECK(bit_reader->ReadBits(1, &extension_flag));
223 RCHECK(channel_config_ != 0);
224
225 if (profile_ == 6 || profile_ == 20)
226 RCHECK(bit_reader->ReadBits(3, &dummy)); // layerNr
227
228 if (extension_flag) {
229 if (profile_ == 22) {
230 RCHECK(bit_reader->ReadBits(5, &dummy)); // numOfSubFrame
231 RCHECK(bit_reader->ReadBits(11, &dummy)); // layer_length
232 }
233
234 if (profile_ == 17 || profile_ == 19 || profile_ == 20 || profile_ == 23) {
235 RCHECK(bit_reader->ReadBits(3, &dummy)); // resilience flags
236 }
237
238 RCHECK(bit_reader->ReadBits(1, &dummy)); // extensionFlag3
239 }
240
241 return true;
242 }
243
244 } // namespace mp4
245
246 } // 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