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

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 unused functions and variables. 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(&data[0], data.size());
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 // 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 && reader.NumBitsLeft() >= 16) {
Ami GONE FROM CHROMIUM 2012/07/17 23:22:18 What does it mean if extension_type != 5 but NumBi
xiaomings 2012/07/19 00:16:32 Remove the check and let the underlying code to ch
91 uint16 sync_extension_type;
92 uint8 sbr_present_flag;
93 uint8 ps_present_flag;
94
95 RCHECK(reader.ReadBits(11, &sync_extension_type));
96
97 if (sync_extension_type == 0x2b7) {
98 RCHECK(reader.ReadBits(5, &extension_type));
99
100 if (extension_type == 5) {
101 RCHECK(reader.ReadBits(1, &sbr_present_flag));
102
103 if (sbr_present_flag) {
104 RCHECK(reader.ReadBits(4, &extension_frequency_index));
105
106 if (extension_frequency_index == 0xf)
107 RCHECK(reader.ReadBits(24, &frequency_));
108
109 RCHECK(reader.ReadBits(11, &sync_extension_type));
110
111 if (sync_extension_type == 0x548) {
112 RCHECK(reader.ReadBits(1, &ps_present_flag));
113 ps_present = ps_present_flag != 0;
114 }
115 }
116 }
117 }
118 }
119
120 if (frequency_ == 0) {
121 RCHECK(extension_frequency_index < arraysize(kFrequencyMap));
122 frequency_ = kFrequencyMap[extension_frequency_index];
123 }
124
125 // When Parametric Stereo is on, mono will be played as stereo.
126 if (ps_present && channel_config_ == 1)
127 channel_layout_ = GetChannelLayout(channel_config_ + 1);
128 else
129 channel_layout_ = GetChannelLayout(channel_config_);
130
131 return frequency_ != 0 && channel_layout_ != CHANNEL_LAYOUT_UNSUPPORTED &&
132 profile_ >= 1 && profile_ <= 4 && frequency_index_ != 0xf &&
133 channel_config_ <= 7;
134 }
135
136 uint32 AAC::frequency() const {
137 return frequency_;
138 }
139
140 ChannelLayout AAC::channel_layout() const {
141 return channel_layout_;
142 }
143
144 bool AAC::ConvertEsdsToADTS(std::vector<uint8>* buffer) const {
145 size_t size = buffer->size() + 7;
146
147 DCHECK(profile_ >= 1 && profile_ <= 4 && frequency_index_ != 0xf &&
148 channel_config_ <= 7);
149
150 // ADTS header uses 13 bits for packet size.
151 if (size > (1 << 13) - 1)
152 return false;
153
154 std::vector<uint8>& adts = *buffer;
155
156 adts.insert(buffer->begin(), 7, 0);
157 adts[0] = 0xff;
158 adts[1] = 0xf1;
159 adts[2] = ((profile_ - 1) << 6) + (frequency_index_ << 2) +
160 (channel_config_ >> 2);
161 adts[3] = ((channel_config_ & 0x3) << 6) + (size >> 11);
162 adts[4] = (size & 0x7ff) >> 3;
163 adts[5] = ((size & 7) << 5) + 0x1f;
164 adts[6] = 0xfc;
165
166 return true;
167 }
168
169 // Currently this function only support GASpecificConfig defined in
170 // ISO 14496 Part 3 Table 4.1 - Syntax of GASpecificConfig()
171 bool AAC::SkipDecoderGASpecificConfig(BitReader* bit_reader) const {
172 switch (profile_) {
173 case 1:
174 case 2:
175 case 3:
176 case 4:
177 case 6:
178 case 7:
179 case 17:
180 case 19:
181 case 20:
182 case 21:
183 case 22:
184 case 23:
185 return SkipGASpecificConfig(bit_reader);
186 default:
187 break;
188 }
189
190 return false;
191 }
192
193 bool AAC::SkipErrorSpecificConfig() const {
194 switch (profile_) {
195 case 17:
196 case 19:
197 case 20:
198 case 21:
199 case 22:
200 case 23:
201 case 24:
202 case 25:
203 case 26:
204 case 27:
205 return false;
206 default:
207 break;
208 }
209
210 return true;
211 }
212
213 // The following code is written according to ISO 14496 part 3 Table 4.1 -
214 // GASpecificConfig.
215 bool AAC::SkipGASpecificConfig(BitReader* bit_reader) const {
216 uint8 extension_flag = 0;
217 uint8 depends_on_core_coder;
218
219 RCHECK(bit_reader->SkipBits(1)); // frameLengthFlag
220 RCHECK(bit_reader->ReadBits(1, &depends_on_core_coder));
221 if (depends_on_core_coder == 1)
222 RCHECK(bit_reader->SkipBits(14)); // coreCoderDelay
223
224 RCHECK(bit_reader->ReadBits(1, &extension_flag));
225 RCHECK(channel_config_ != 0);
226
227 if (profile_ == 6 || profile_ == 20)
228 RCHECK(bit_reader->SkipBits(3));
229
230 if (extension_flag) {
231 if (profile_ == 22) {
232 RCHECK(bit_reader->SkipBits(5));
233 RCHECK(bit_reader->SkipBits(11));
234 }
235
236 if (profile_ == 17 || profile_ == 19 || profile_ == 20 || profile_ == 23) {
237 RCHECK(bit_reader->SkipBits(1));
238 RCHECK(bit_reader->SkipBits(1));
239 RCHECK(bit_reader->SkipBits(1));
240 }
241
242 RCHECK(bit_reader->SkipBits(1));
243 }
244
245 return true;
246 }
247
248 } // namespace mp4
249
250 } // namespace media
OLDNEW
« media/base/bit_reader.cc ('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