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

Unified Diff: media/formats/mpeg/mpeg1_audio_stream_parser.cc

Issue 506943003: Support MPEG1 audio in the MPEG2-TS stream parser. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rename MP3StreamParser to MPEG1AudioStreamParser. Created 6 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: media/formats/mpeg/mpeg1_audio_stream_parser.cc
diff --git a/media/formats/mpeg/mp3_stream_parser.cc b/media/formats/mpeg/mpeg1_audio_stream_parser.cc
similarity index 68%
rename from media/formats/mpeg/mp3_stream_parser.cc
rename to media/formats/mpeg/mpeg1_audio_stream_parser.cc
index f5b743824233afc8dc080209cb90c290075ae114..afcba1cd7980586904083c6ec037f43c8cec708f 100644
--- a/media/formats/mpeg/mp3_stream_parser.cc
+++ b/media/formats/mpeg/mpeg1_audio_stream_parser.cc
@@ -2,10 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "media/formats/mpeg/mp3_stream_parser.h"
+#include "media/formats/mpeg/mpeg1_audio_stream_parser.h"
namespace media {
+// static
+const int MPEG1AudioStreamParser::kHeaderSize = 4u;
acolwell GONE FROM CHROMIUM 2014/09/04 22:20:53 nit: drop the u?
DaleCurtis 2014/09/04 23:01:14 Just make this an enum?
damienv1 2014/09/05 20:06:13 Done.
damienv1 2014/09/05 20:06:13 Done.
+
static const uint32 kMP3StartCodeMask = 0xffe00000;
// Map that determines which bitrate_index & channel_mode combinations
@@ -92,26 +95,12 @@ static const int kBitrateBad = 0xf;
static const int kSampleRateReserved = 3;
static const int kCodecDelay = 529;
-MP3StreamParser::MP3StreamParser()
- : MPEGAudioStreamParserBase(kMP3StartCodeMask, kCodecMP3, kCodecDelay) {}
-
-MP3StreamParser::~MP3StreamParser() {}
-
-int MP3StreamParser::ParseFrameHeader(const uint8* data,
- int size,
- int* frame_size,
- int* sample_rate,
- ChannelLayout* channel_layout,
- int* sample_count,
- bool* metadata_frame) const {
- DCHECK(data);
- DCHECK_GE(size, 0);
- DCHECK(frame_size);
-
- if (size < 4)
- return 0;
-
- BitReader reader(data, size);
+// static
+bool MPEG1AudioStreamParser::ParseHeader(
+ const LogCB& log_cb,
+ const uint8* data,
+ Header* header) {
+ BitReader reader(data, kHeaderSize);
int sync;
int version;
int layer;
@@ -133,7 +122,7 @@ int MP3StreamParser::ParseFrameHeader(const uint8* data,
!reader.ReadBits(1, &is_private) ||
!reader.ReadBits(2, &channel_mode) ||
!reader.ReadBits(6, &other_flags)) {
- return -1;
+ return false;
}
DVLOG(2) << "Header data :" << std::hex
@@ -149,46 +138,44 @@ int MP3StreamParser::ParseFrameHeader(const uint8* data,
layer == kLayerReserved ||
bitrate_index == kBitrateFree || bitrate_index == kBitrateBad ||
sample_rate_index == kSampleRateReserved) {
- MEDIA_LOG(log_cb()) << "Invalid header data :" << std::hex
- << " sync 0x" << sync
- << " version 0x" << version
- << " layer 0x" << layer
- << " bitrate_index 0x" << bitrate_index
- << " sample_rate_index 0x" << sample_rate_index
- << " channel_mode 0x" << channel_mode;
- return -1;
+ MEDIA_LOG(log_cb) << "Invalid header data :" << std::hex
+ << " sync 0x" << sync
+ << " version 0x" << version
+ << " layer 0x" << layer
+ << " bitrate_index 0x" << bitrate_index
+ << " sample_rate_index 0x" << sample_rate_index
+ << " channel_mode 0x" << channel_mode;
+ return false;
}
if (layer == kLayer2 && kIsAllowed[bitrate_index][channel_mode]) {
- MEDIA_LOG(log_cb()) << "Invalid (bitrate_index, channel_mode) combination :"
- << std::hex
- << " bitrate_index " << bitrate_index
- << " channel_mode " << channel_mode;
- return -1;
+ MEDIA_LOG(log_cb) << "Invalid (bitrate_index, channel_mode) combination :"
+ << std::hex
+ << " bitrate_index " << bitrate_index
+ << " channel_mode " << channel_mode;
+ return false;
}
int bitrate = kBitrateMap[bitrate_index][kVersionLayerMap[version][layer]];
if (bitrate == 0) {
- MEDIA_LOG(log_cb()) << "Invalid bitrate :" << std::hex
- << " version " << version
- << " layer " << layer
- << " bitrate_index " << bitrate_index;
- return -1;
+ MEDIA_LOG(log_cb) << "Invalid bitrate :" << std::hex
+ << " version " << version
+ << " layer " << layer
+ << " bitrate_index " << bitrate_index;
+ return false;
}
DVLOG(2) << " bitrate " << bitrate;
int frame_sample_rate = kSampleRateMap[sample_rate_index][version];
if (frame_sample_rate == 0) {
- MEDIA_LOG(log_cb()) << "Invalid sample rate :" << std::hex
- << " version " << version
- << " sample_rate_index " << sample_rate_index;
- return -1;
+ MEDIA_LOG(log_cb) << "Invalid sample rate :" << std::hex
+ << " version " << version
+ << " sample_rate_index " << sample_rate_index;
+ return false;
}
-
- if (sample_rate)
- *sample_rate = frame_sample_rate;
+ header->sample_rate = frame_sample_rate;
// http://teslabs.com/openplayer/docs/docs/specs/mp3_structure2.pdf
// Table 2.1.5
@@ -210,11 +197,9 @@ int MP3StreamParser::ParseFrameHeader(const uint8* data,
break;
default:
- return -1;
+ return false;
}
-
- if (sample_count)
- *sample_count = samples_per_frame;
+ header->sample_count = samples_per_frame;
// http://teslabs.com/openplayer/docs/docs/specs/mp3_structure2.pdf
// Text just below Table 2.1.5.
@@ -223,33 +208,68 @@ int MP3StreamParser::ParseFrameHeader(const uint8* data,
// but has slightly different truncation characteristics to deal
// with the fact that Layer 1 has 4 byte "slots" instead of single
// byte ones.
- *frame_size = 4 * (12 * bitrate * 1000 / frame_sample_rate);
+ header->frame_size = 4 * (12 * bitrate * 1000 / frame_sample_rate);
} else {
- *frame_size =
+ header->frame_size =
((samples_per_frame / 8) * bitrate * 1000) / frame_sample_rate;
}
if (has_padding)
- *frame_size += (layer == kLayer1) ? 4 : 1;
+ header->frame_size += (layer == kLayer1) ? 4 : 1;
- if (channel_layout) {
- // Map Stereo(0), Joint Stereo(1), and Dual Channel (2) to
- // CHANNEL_LAYOUT_STEREO and Single Channel (3) to CHANNEL_LAYOUT_MONO.
- *channel_layout =
- (channel_mode == 3) ? CHANNEL_LAYOUT_MONO : CHANNEL_LAYOUT_STEREO;
- }
+ // Map Stereo(0), Joint Stereo(1), and Dual Channel (2) to
+ // CHANNEL_LAYOUT_STEREO and Single Channel (3) to CHANNEL_LAYOUT_MONO.
+ header->channel_layout =
+ (channel_mode == 3) ? CHANNEL_LAYOUT_MONO : CHANNEL_LAYOUT_STEREO;
+
+ header->version = version;
+ header->layer = layer;
+ header->channel_mode = channel_mode;
+ return true;
+}
+
+
+MPEG1AudioStreamParser::MPEG1AudioStreamParser()
+ : MPEGAudioStreamParserBase(kMP3StartCodeMask, kCodecMP3, kCodecDelay) {}
+
+MPEG1AudioStreamParser::~MPEG1AudioStreamParser() {}
+
+int MPEG1AudioStreamParser::ParseFrameHeader(const uint8* data,
+ int size,
+ int* frame_size,
+ int* sample_rate,
+ ChannelLayout* channel_layout,
+ int* sample_count,
+ bool* metadata_frame) const {
+ DCHECK(data);
+ DCHECK_GE(size, 0);
+ DCHECK(frame_size);
+
+ if (size < static_cast<int>(kHeaderSize))
acolwell GONE FROM CHROMIUM 2014/09/04 22:20:53 I don't think you need the cast here since kHeader
damienv1 2014/09/05 20:06:13 Done.
+ return 0;
+ Header header;
+ if (!ParseHeader(log_cb(), data, &header))
+ return -1;
+
+ *frame_size = header.frame_size;
+ if (sample_rate)
+ *sample_rate = header.sample_rate;
+ if (sample_count)
+ *sample_count = header.sample_count;
+ if (channel_layout)
+ *channel_layout = header.channel_layout;
if (metadata_frame)
*metadata_frame = false;
- const int header_bytes_read = reader.bits_read() / 8;
- if (layer != kLayer3)
+ const int header_bytes_read = kHeaderSize;
+ if (header.layer != kLayer3)
return header_bytes_read;
// Check if this is a XING frame and tell the base parser to skip it if so.
const int xing_header_index =
- kXingHeaderMap[version == kVersion2 ||
- version == kVersion2_5][channel_mode == 3];
+ kXingHeaderMap[header.version == kVersion2 ||
+ header.version == kVersion2_5][header.channel_mode == 3];
uint32_t tag = 0;
// It's not a XING frame if the frame isn't big enough to be one.
@@ -260,6 +280,7 @@ int MP3StreamParser::ParseFrameHeader(const uint8* data,
// If we don't have enough data available to check, return 0 so frame parsing
// will be retried once more data is available.
+ BitReader reader(data + header_bytes_read, size - header_bytes_read);
if (!reader.SkipBits(xing_header_index * 8) ||
!reader.ReadBits(sizeof(tag) * 8, &tag)) {
return 0;
@@ -270,7 +291,7 @@ int MP3StreamParser::ParseFrameHeader(const uint8* data,
MEDIA_LOG(log_cb()) << "Skipping XING header.";
if (metadata_frame)
*metadata_frame = true;
- return reader.bits_read() / 8;
+ return header_bytes_read + reader.bits_read() / 8;
}
// If it wasn't a XING frame, just return the number consumed bytes.

Powered by Google App Engine
This is Rietveld 408576698