diff options
author | acolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-23 02:56:17 +0000 |
---|---|---|
committer | acolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-23 02:56:17 +0000 |
commit | 4fddfa542c2d826e8833df1c56dd862142e3f122 (patch) | |
tree | fb2445ef21aa430e4c6ba0670a43ad8c20b7cbd3 /media | |
parent | 03c5d9daab3ba6260fb8e65da8c9433480d349f1 (diff) | |
download | chromium_src-4fddfa542c2d826e8833df1c56dd862142e3f122.zip chromium_src-4fddfa542c2d826e8833df1c56dd862142e3f122.tar.gz chromium_src-4fddfa542c2d826e8833df1c56dd862142e3f122.tar.bz2 |
Allow ChunkDemuxer to accept audio object types with leading zeros.
BUG=177354
TEST=ChunkDemuxerTest.TestCodecIDsThatAreNotRFC6381Compliant
Review URL: https://chromiumcodereview.appspot.com/12321034
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@184269 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/filters/chunk_demuxer.cc | 61 | ||||
-rw-r--r-- | media/filters/chunk_demuxer_unittest.cc | 30 |
2 files changed, 67 insertions, 24 deletions
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc index f4cb474..d56f835b 100644 --- a/media/filters/chunk_demuxer.cc +++ b/media/filters/chunk_demuxer.cc @@ -12,6 +12,7 @@ #include "base/location.h" #include "base/logging.h" #include "base/message_loop_proxy.h" +#include "base/string_number_conversions.h" #include "base/string_util.h" #include "media/base/audio_decoder_config.h" #include "media/base/stream_parser_buffer.h" @@ -32,7 +33,7 @@ struct CodecInfo { }; typedef StreamParser* (*ParserFactoryFunction)( - const std::vector<std::string>& codecs); + const std::vector<std::string>& codecs, const LogCB& log_cb); struct SupportedTypeInfo { const char* type; @@ -54,18 +55,15 @@ static const CodecInfo* kAudioWebMCodecs[] = { NULL }; -static StreamParser* BuildWebMParser(const std::vector<std::string>& codecs) { +static StreamParser* BuildWebMParser(const std::vector<std::string>& codecs, + const LogCB& log_cb) { return new WebMStreamParser(); } #if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS) static const CodecInfo kH264CodecInfo = { "avc1.*", DemuxerStream::VIDEO }; -static const CodecInfo kMPEG4AACLCCodecInfo = { - "mp4a.40.2", DemuxerStream::AUDIO -}; - -static const CodecInfo kMPEG4AACSBRCodecInfo = { - "mp4a.40.5", DemuxerStream::AUDIO +static const CodecInfo kMPEG4AACCodecInfo = { + "mp4a.40.*", DemuxerStream::AUDIO }; static const CodecInfo kMPEG2AACLCCodecInfo = { @@ -74,35 +72,51 @@ static const CodecInfo kMPEG2AACLCCodecInfo = { static const CodecInfo* kVideoMP4Codecs[] = { &kH264CodecInfo, - &kMPEG4AACLCCodecInfo, - &kMPEG4AACSBRCodecInfo, + &kMPEG4AACCodecInfo, &kMPEG2AACLCCodecInfo, NULL }; static const CodecInfo* kAudioMP4Codecs[] = { - &kMPEG4AACLCCodecInfo, - &kMPEG4AACSBRCodecInfo, + &kMPEG4AACCodecInfo, &kMPEG2AACLCCodecInfo, NULL }; -// Mimetype codec string that indicates the content contains AAC SBR frames. -static const char kSBRCodecId[] = "mp4a.40.5"; +// AAC Object Type IDs that Chrome supports. +static const int kAACLCObjectType = 2; +static const int kAACSBRObjectType = 5; -static StreamParser* BuildMP4Parser(const std::vector<std::string>& codecs) { +static StreamParser* BuildMP4Parser(const std::vector<std::string>& codecs, + const LogCB& log_cb) { std::set<int> audio_object_types; bool has_sbr = false; for (size_t i = 0; i < codecs.size(); ++i) { if (MatchPattern(codecs[i], kMPEG2AACLCCodecInfo.pattern)) { audio_object_types.insert(mp4::kISO_13818_7_AAC_LC); - } else { + } else if (MatchPattern(codecs[i], kMPEG4AACCodecInfo.pattern)) { + std::vector<std::string> tokens; + int audio_object_type; + if (Tokenize(codecs[i], ".", &tokens) != 3 || + !base::HexStringToInt(tokens[2], &audio_object_type)) { + MEDIA_LOG(log_cb) << "Malformed mimetype codec '" << codecs[i] << "'"; + return NULL; + } + + if (audio_object_type != kAACLCObjectType && + audio_object_type != kAACSBRObjectType) { + MEDIA_LOG(log_cb) << "Unsupported audio object type " + << "0x" << std::hex << audio_object_type + << " in codec '" << codecs[i] << "'"; + return NULL; + } + audio_object_types.insert(mp4::kISO_14496_3); - } - if (codecs[i] == kSBRCodecId) { - has_sbr = true; - break; + if (audio_object_type == kAACSBRObjectType) { + has_sbr = true; + break; + } } } @@ -717,6 +731,10 @@ ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id, StreamParser::NewBuffersCB audio_cb; StreamParser::NewBuffersCB video_cb; + scoped_ptr<StreamParser> stream_parser(factory_function(codecs, log_cb_)); + if (!stream_parser) + return kNotSupported; + if (has_audio) { source_id_audio_ = id; audio_cb = base::Bind(&ChunkDemuxer::OnAudioBuffers, @@ -729,9 +747,6 @@ ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id, base::Unretained(this)); } - scoped_ptr<StreamParser> stream_parser(factory_function(codecs)); - CHECK(stream_parser.get()); - stream_parser->Init( base::Bind(&ChunkDemuxer::OnStreamParserInitDone, base::Unretained(this)), base::Bind(&ChunkDemuxer::OnNewConfigs, base::Unretained(this), diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc index bfdc761..81c906b 100644 --- a/media/filters/chunk_demuxer_unittest.cc +++ b/media/filters/chunk_demuxer_unittest.cc @@ -2041,11 +2041,39 @@ TEST_F(ChunkDemuxerTest, TestCodecPrefixMatching) { std::vector<std::string> codecs; codecs.push_back("avc1.4D4041"); - codecs.push_back("mp4a.40.2"); EXPECT_EQ(demuxer_->AddId("source_id", "video/mp4", codecs), expected); } +// Test codec ID's that are not compliant with RFC6381, but have been +// seen in the wild. +TEST_F(ChunkDemuxerTest, TestCodecIDsThatAreNotRFC6381Compliant) { + ChunkDemuxer::Status expected = ChunkDemuxer::kNotSupported; + +#if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS) + expected = ChunkDemuxer::kOk; +#endif + const char* codec_ids[] = { + // GPAC places leading zeros on the audio object type. + "mp4a.40.02", + "mp4a.40.05" + }; + + for (size_t i = 0; i < arraysize(codec_ids); ++i) { + std::vector<std::string> codecs; + codecs.push_back(codec_ids[i]); + + ChunkDemuxer::Status result = + demuxer_->AddId("source_id", "audio/mp4", codecs); + + EXPECT_EQ(result, expected) + << "Fail to add codec_id '" << codec_ids[i] << "'"; + + if (result == ChunkDemuxer::kOk) + demuxer_->RemoveId("source_id"); + } +} + TEST_F(ChunkDemuxerTest, TestEndOfStreamFailures) { std::string audio_id = "audio"; std::string video_id = "video"; |