OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/formats/mpeg/mp3_stream_parser.h" | 5 #include "media/formats/mpeg/mpeg1_audio_stream_parser.h" |
6 | 6 |
7 namespace media { | 7 namespace media { |
8 | 8 |
9 static const uint32 kMP3StartCodeMask = 0xffe00000; | 9 static const uint32 kMPEG1StartCodeMask = 0xffe00000; |
10 | 10 |
11 // Map that determines which bitrate_index & channel_mode combinations | 11 // Map that determines which bitrate_index & channel_mode combinations |
12 // are allowed. | 12 // are allowed. |
13 // Derived from: http://mpgedit.org/mpgedit/mpeg_format/MP3Format.html | 13 // Derived from: http://mpgedit.org/mpgedit/mpeg_format/MP3Format.html |
14 static const bool kIsAllowed[17][4] = { | 14 static const bool kIsAllowed[17][4] = { |
15 { true, true, true, true }, // free | 15 { true, true, true, true }, // free |
16 { true, false, false, false }, // 32 | 16 { true, false, false, false }, // 32 |
17 { true, false, false, false }, // 48 | 17 { true, false, false, false }, // 48 |
18 { true, false, false, false }, // 56 | 18 { true, false, false, false }, // 56 |
19 { true, true, true, true }, // 64 | 19 { true, true, true, true }, // 64 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 { 12000, 0, 24000, 48000 }, | 73 { 12000, 0, 24000, 48000 }, |
74 { 8000, 0, 16000, 32000 }, | 74 { 8000, 0, 16000, 32000 }, |
75 { 0, 0, 0, 0 } | 75 { 0, 0, 0, 0 } |
76 }; | 76 }; |
77 | 77 |
78 // Offset in bytes from the end of the MP3 header to "Xing" or "Info" tags which | 78 // Offset in bytes from the end of the MP3 header to "Xing" or "Info" tags which |
79 // indicate a frame is silent metadata frame. Values taken from FFmpeg. | 79 // indicate a frame is silent metadata frame. Values taken from FFmpeg. |
80 static const int kXingHeaderMap[2][2] = {{32, 17}, {17, 9}}; | 80 static const int kXingHeaderMap[2][2] = {{32, 17}, {17, 9}}; |
81 | 81 |
82 // Frame header field constants. | 82 // Frame header field constants. |
83 static const int kVersion2 = 2; | |
84 static const int kVersionReserved = 1; | |
85 static const int kVersion2_5 = 0; | |
86 static const int kLayerReserved = 0; | |
87 static const int kLayer1 = 3; | |
88 static const int kLayer2 = 2; | |
89 static const int kLayer3 = 1; | |
90 static const int kBitrateFree = 0; | 83 static const int kBitrateFree = 0; |
91 static const int kBitrateBad = 0xf; | 84 static const int kBitrateBad = 0xf; |
92 static const int kSampleRateReserved = 3; | 85 static const int kSampleRateReserved = 3; |
93 static const int kCodecDelay = 529; | 86 static const int kCodecDelay = 529; |
94 | 87 |
95 MP3StreamParser::MP3StreamParser() | 88 // static |
96 : MPEGAudioStreamParserBase(kMP3StartCodeMask, kCodecMP3, kCodecDelay) {} | 89 bool MPEG1AudioStreamParser::ParseHeader( |
97 | 90 const LogCB& log_cb, |
98 MP3StreamParser::~MP3StreamParser() {} | 91 const uint8* data, |
99 | 92 Header* header) { |
100 int MP3StreamParser::ParseFrameHeader(const uint8* data, | 93 BitReader reader(data, kHeaderSize); |
101 int size, | |
102 int* frame_size, | |
103 int* sample_rate, | |
104 ChannelLayout* channel_layout, | |
105 int* sample_count, | |
106 bool* metadata_frame) const { | |
107 DCHECK(data); | |
108 DCHECK_GE(size, 0); | |
109 DCHECK(frame_size); | |
110 | |
111 if (size < 4) | |
112 return 0; | |
113 | |
114 BitReader reader(data, size); | |
115 int sync; | 94 int sync; |
116 int version; | 95 int version; |
117 int layer; | 96 int layer; |
118 int is_protected; | 97 int is_protected; |
119 int bitrate_index; | 98 int bitrate_index; |
120 int sample_rate_index; | 99 int sample_rate_index; |
121 int has_padding; | 100 int has_padding; |
122 int is_private; | 101 int is_private; |
123 int channel_mode; | 102 int channel_mode; |
124 int other_flags; | 103 int other_flags; |
125 | 104 |
126 if (!reader.ReadBits(11, &sync) || | 105 if (!reader.ReadBits(11, &sync) || |
127 !reader.ReadBits(2, &version) || | 106 !reader.ReadBits(2, &version) || |
128 !reader.ReadBits(2, &layer) || | 107 !reader.ReadBits(2, &layer) || |
129 !reader.ReadBits(1, &is_protected) || | 108 !reader.ReadBits(1, &is_protected) || |
130 !reader.ReadBits(4, &bitrate_index) || | 109 !reader.ReadBits(4, &bitrate_index) || |
131 !reader.ReadBits(2, &sample_rate_index) || | 110 !reader.ReadBits(2, &sample_rate_index) || |
132 !reader.ReadBits(1, &has_padding) || | 111 !reader.ReadBits(1, &has_padding) || |
133 !reader.ReadBits(1, &is_private) || | 112 !reader.ReadBits(1, &is_private) || |
134 !reader.ReadBits(2, &channel_mode) || | 113 !reader.ReadBits(2, &channel_mode) || |
135 !reader.ReadBits(6, &other_flags)) { | 114 !reader.ReadBits(6, &other_flags)) { |
136 return -1; | 115 return false; |
137 } | 116 } |
138 | 117 |
139 DVLOG(2) << "Header data :" << std::hex | 118 DVLOG(2) << "Header data :" << std::hex |
140 << " sync 0x" << sync | 119 << " sync 0x" << sync |
141 << " version 0x" << version | 120 << " version 0x" << version |
142 << " layer 0x" << layer | 121 << " layer 0x" << layer |
143 << " bitrate_index 0x" << bitrate_index | 122 << " bitrate_index 0x" << bitrate_index |
144 << " sample_rate_index 0x" << sample_rate_index | 123 << " sample_rate_index 0x" << sample_rate_index |
145 << " channel_mode 0x" << channel_mode; | 124 << " channel_mode 0x" << channel_mode; |
146 | 125 |
147 if (sync != 0x7ff || | 126 if (sync != 0x7ff || |
148 version == kVersionReserved || | 127 version == kVersionReserved || |
149 layer == kLayerReserved || | 128 layer == kLayerReserved || |
150 bitrate_index == kBitrateFree || bitrate_index == kBitrateBad || | 129 bitrate_index == kBitrateFree || bitrate_index == kBitrateBad || |
151 sample_rate_index == kSampleRateReserved) { | 130 sample_rate_index == kSampleRateReserved) { |
152 MEDIA_LOG(log_cb()) << "Invalid header data :" << std::hex | 131 MEDIA_LOG(log_cb) << "Invalid header data :" << std::hex |
153 << " sync 0x" << sync | 132 << " sync 0x" << sync |
154 << " version 0x" << version | 133 << " version 0x" << version |
155 << " layer 0x" << layer | 134 << " layer 0x" << layer |
156 << " bitrate_index 0x" << bitrate_index | 135 << " bitrate_index 0x" << bitrate_index |
157 << " sample_rate_index 0x" << sample_rate_index | 136 << " sample_rate_index 0x" << sample_rate_index |
158 << " channel_mode 0x" << channel_mode; | 137 << " channel_mode 0x" << channel_mode; |
159 return -1; | 138 return false; |
160 } | 139 } |
161 | 140 |
162 if (layer == kLayer2 && kIsAllowed[bitrate_index][channel_mode]) { | 141 if (layer == kLayer2 && kIsAllowed[bitrate_index][channel_mode]) { |
163 MEDIA_LOG(log_cb()) << "Invalid (bitrate_index, channel_mode) combination :" | 142 MEDIA_LOG(log_cb) << "Invalid (bitrate_index, channel_mode) combination :" |
164 << std::hex | 143 << std::hex |
165 << " bitrate_index " << bitrate_index | 144 << " bitrate_index " << bitrate_index |
166 << " channel_mode " << channel_mode; | 145 << " channel_mode " << channel_mode; |
167 return -1; | 146 return false; |
168 } | 147 } |
169 | 148 |
170 int bitrate = kBitrateMap[bitrate_index][kVersionLayerMap[version][layer]]; | 149 int bitrate = kBitrateMap[bitrate_index][kVersionLayerMap[version][layer]]; |
171 | 150 |
172 if (bitrate == 0) { | 151 if (bitrate == 0) { |
173 MEDIA_LOG(log_cb()) << "Invalid bitrate :" << std::hex | 152 MEDIA_LOG(log_cb) << "Invalid bitrate :" << std::hex |
174 << " version " << version | 153 << " version " << version |
175 << " layer " << layer | 154 << " layer " << layer |
176 << " bitrate_index " << bitrate_index; | 155 << " bitrate_index " << bitrate_index; |
177 return -1; | 156 return false; |
178 } | 157 } |
179 | 158 |
180 DVLOG(2) << " bitrate " << bitrate; | 159 DVLOG(2) << " bitrate " << bitrate; |
181 | 160 |
182 int frame_sample_rate = kSampleRateMap[sample_rate_index][version]; | 161 int frame_sample_rate = kSampleRateMap[sample_rate_index][version]; |
183 if (frame_sample_rate == 0) { | 162 if (frame_sample_rate == 0) { |
184 MEDIA_LOG(log_cb()) << "Invalid sample rate :" << std::hex | 163 MEDIA_LOG(log_cb) << "Invalid sample rate :" << std::hex |
185 << " version " << version | 164 << " version " << version |
186 << " sample_rate_index " << sample_rate_index; | 165 << " sample_rate_index " << sample_rate_index; |
187 return -1; | 166 return false; |
188 } | 167 } |
189 | 168 header->sample_rate = frame_sample_rate; |
190 if (sample_rate) | |
191 *sample_rate = frame_sample_rate; | |
192 | 169 |
193 // http://teslabs.com/openplayer/docs/docs/specs/mp3_structure2.pdf | 170 // http://teslabs.com/openplayer/docs/docs/specs/mp3_structure2.pdf |
194 // Table 2.1.5 | 171 // Table 2.1.5 |
195 int samples_per_frame; | 172 int samples_per_frame; |
196 switch (layer) { | 173 switch (layer) { |
197 case kLayer1: | 174 case kLayer1: |
198 samples_per_frame = 384; | 175 samples_per_frame = 384; |
199 break; | 176 break; |
200 | 177 |
201 case kLayer2: | 178 case kLayer2: |
202 samples_per_frame = 1152; | 179 samples_per_frame = 1152; |
203 break; | 180 break; |
204 | 181 |
205 case kLayer3: | 182 case kLayer3: |
206 if (version == kVersion2 || version == kVersion2_5) | 183 if (version == kVersion2 || version == kVersion2_5) |
207 samples_per_frame = 576; | 184 samples_per_frame = 576; |
208 else | 185 else |
209 samples_per_frame = 1152; | 186 samples_per_frame = 1152; |
210 break; | 187 break; |
211 | 188 |
212 default: | 189 default: |
213 return -1; | 190 return false; |
214 } | 191 } |
215 | 192 header->sample_count = samples_per_frame; |
216 if (sample_count) | |
217 *sample_count = samples_per_frame; | |
218 | 193 |
219 // http://teslabs.com/openplayer/docs/docs/specs/mp3_structure2.pdf | 194 // http://teslabs.com/openplayer/docs/docs/specs/mp3_structure2.pdf |
220 // Text just below Table 2.1.5. | 195 // Text just below Table 2.1.5. |
221 if (layer == kLayer1) { | 196 if (layer == kLayer1) { |
222 // This formulation is a slight variation on the equation below, | 197 // This formulation is a slight variation on the equation below, |
223 // but has slightly different truncation characteristics to deal | 198 // but has slightly different truncation characteristics to deal |
224 // with the fact that Layer 1 has 4 byte "slots" instead of single | 199 // with the fact that Layer 1 has 4 byte "slots" instead of single |
225 // byte ones. | 200 // byte ones. |
226 *frame_size = 4 * (12 * bitrate * 1000 / frame_sample_rate); | 201 header->frame_size = 4 * (12 * bitrate * 1000 / frame_sample_rate); |
227 } else { | 202 } else { |
228 *frame_size = | 203 header->frame_size = |
229 ((samples_per_frame / 8) * bitrate * 1000) / frame_sample_rate; | 204 ((samples_per_frame / 8) * bitrate * 1000) / frame_sample_rate; |
230 } | 205 } |
231 | 206 |
232 if (has_padding) | 207 if (has_padding) |
233 *frame_size += (layer == kLayer1) ? 4 : 1; | 208 header->frame_size += (layer == kLayer1) ? 4 : 1; |
234 | 209 |
235 if (channel_layout) { | 210 // Map Stereo(0), Joint Stereo(1), and Dual Channel (2) to |
236 // Map Stereo(0), Joint Stereo(1), and Dual Channel (2) to | 211 // CHANNEL_LAYOUT_STEREO and Single Channel (3) to CHANNEL_LAYOUT_MONO. |
237 // CHANNEL_LAYOUT_STEREO and Single Channel (3) to CHANNEL_LAYOUT_MONO. | 212 header->channel_layout = |
238 *channel_layout = | 213 (channel_mode == 3) ? CHANNEL_LAYOUT_MONO : CHANNEL_LAYOUT_STEREO; |
239 (channel_mode == 3) ? CHANNEL_LAYOUT_MONO : CHANNEL_LAYOUT_STEREO; | |
240 } | |
241 | 214 |
| 215 header->version = static_cast<Version>(version); |
| 216 header->layer = static_cast<Layer>(layer); |
| 217 header->channel_mode = channel_mode; |
| 218 return true; |
| 219 } |
| 220 |
| 221 |
| 222 MPEG1AudioStreamParser::MPEG1AudioStreamParser() |
| 223 : MPEGAudioStreamParserBase(kMPEG1StartCodeMask, kCodecMP3, kCodecDelay) {} |
| 224 |
| 225 MPEG1AudioStreamParser::~MPEG1AudioStreamParser() {} |
| 226 |
| 227 int MPEG1AudioStreamParser::ParseFrameHeader(const uint8* data, |
| 228 int size, |
| 229 int* frame_size, |
| 230 int* sample_rate, |
| 231 ChannelLayout* channel_layout, |
| 232 int* sample_count, |
| 233 bool* metadata_frame) const { |
| 234 DCHECK(data); |
| 235 DCHECK_GE(size, 0); |
| 236 DCHECK(frame_size); |
| 237 |
| 238 if (size < kHeaderSize) |
| 239 return 0; |
| 240 |
| 241 Header header; |
| 242 if (!ParseHeader(log_cb(), data, &header)) |
| 243 return -1; |
| 244 |
| 245 *frame_size = header.frame_size; |
| 246 if (sample_rate) |
| 247 *sample_rate = header.sample_rate; |
| 248 if (sample_count) |
| 249 *sample_count = header.sample_count; |
| 250 if (channel_layout) |
| 251 *channel_layout = header.channel_layout; |
242 if (metadata_frame) | 252 if (metadata_frame) |
243 *metadata_frame = false; | 253 *metadata_frame = false; |
244 | 254 |
245 const int header_bytes_read = reader.bits_read() / 8; | 255 const int header_bytes_read = kHeaderSize; |
246 if (layer != kLayer3) | 256 if (header.layer != kLayer3) |
247 return header_bytes_read; | 257 return header_bytes_read; |
248 | 258 |
249 // Check if this is a XING frame and tell the base parser to skip it if so. | 259 // Check if this is a XING frame and tell the base parser to skip it if so. |
250 const int xing_header_index = | 260 const int xing_header_index = |
251 kXingHeaderMap[version == kVersion2 || | 261 kXingHeaderMap[header.version == kVersion2 || |
252 version == kVersion2_5][channel_mode == 3]; | 262 header.version == kVersion2_5][header.channel_mode == 3]; |
253 uint32_t tag = 0; | 263 uint32_t tag = 0; |
254 | 264 |
255 // It's not a XING frame if the frame isn't big enough to be one. | 265 // It's not a XING frame if the frame isn't big enough to be one. |
256 if (*frame_size < | 266 if (*frame_size < |
257 header_bytes_read + xing_header_index + static_cast<int>(sizeof(tag))) { | 267 header_bytes_read + xing_header_index + static_cast<int>(sizeof(tag))) { |
258 return header_bytes_read; | 268 return header_bytes_read; |
259 } | 269 } |
260 | 270 |
261 // If we don't have enough data available to check, return 0 so frame parsing | 271 // If we don't have enough data available to check, return 0 so frame parsing |
262 // will be retried once more data is available. | 272 // will be retried once more data is available. |
| 273 BitReader reader(data + header_bytes_read, size - header_bytes_read); |
263 if (!reader.SkipBits(xing_header_index * 8) || | 274 if (!reader.SkipBits(xing_header_index * 8) || |
264 !reader.ReadBits(sizeof(tag) * 8, &tag)) { | 275 !reader.ReadBits(sizeof(tag) * 8, &tag)) { |
265 return 0; | 276 return 0; |
266 } | 277 } |
267 | 278 |
268 // Check to see if the tag contains 'Xing' or 'Info' | 279 // Check to see if the tag contains 'Xing' or 'Info' |
269 if (tag == 0x496e666f || tag == 0x58696e67) { | 280 if (tag == 0x496e666f || tag == 0x58696e67) { |
270 MEDIA_LOG(log_cb()) << "Skipping XING header."; | 281 MEDIA_LOG(log_cb()) << "Skipping XING header."; |
271 if (metadata_frame) | 282 if (metadata_frame) |
272 *metadata_frame = true; | 283 *metadata_frame = true; |
273 return reader.bits_read() / 8; | 284 return header_bytes_read + reader.bits_read() / 8; |
274 } | 285 } |
275 | 286 |
276 // If it wasn't a XING frame, just return the number consumed bytes. | 287 // If it wasn't a XING frame, just return the number consumed bytes. |
277 return header_bytes_read; | 288 return header_bytes_read; |
278 } | 289 } |
279 | 290 |
280 } // namespace media | 291 } // namespace media |
OLD | NEW |