| 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 |