diff options
author | acolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-18 10:29:55 +0000 |
---|---|---|
committer | acolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-18 10:29:55 +0000 |
commit | 6ce837cc5935728fa8d506aa1ef502ae758ac745 (patch) | |
tree | 8df98d88089d9dacc0588f7c99e6133a1bed466f | |
parent | abafff342a1565ca70e05e8799abb6cdc80608b5 (diff) | |
download | chromium_src-6ce837cc5935728fa8d506aa1ef502ae758ac745.zip chromium_src-6ce837cc5935728fa8d506aa1ef502ae758ac745.tar.gz chromium_src-6ce837cc5935728fa8d506aa1ef502ae758ac745.tar.bz2 |
Add support for avc3 codec string.
The avc3 codec string is used for H.264 content where the SPS & PPS are
included at the beginning of each access point instead of in the file
headers. This change just allows these streams to be played since our
decoders already support this. In fact, our avc1 code essentially creates
avc3 style streams for the decoder anyways.
BUG=306545
TEST=PipelineIntegrationTest.BasicPlayback_MediaSource_VideoOnly_MP4_AVC3
Review URL: https://codereview.chromium.org/27374002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@229347 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/media/encrypted_media_istypesupported_browsertest.cc | 28 | ||||
-rw-r--r-- | chrome/renderer/media/chrome_key_systems.cc | 9 | ||||
-rw-r--r-- | content/renderer/media/crypto/key_systems.cc | 4 | ||||
-rw-r--r-- | media/filters/pipeline_integration_test.cc | 21 | ||||
-rw-r--r-- | media/filters/stream_parser_factory.cc | 9 | ||||
-rw-r--r-- | media/mp4/box_definitions.cc | 11 | ||||
-rw-r--r-- | media/mp4/box_definitions.h | 2 | ||||
-rw-r--r-- | media/mp4/fourccs.h | 1 | ||||
-rw-r--r-- | media/mp4/mp4_stream_parser.cc | 4 | ||||
-rw-r--r-- | media/test/data/bear-1280x720-v_frag-avc3.mp4 | bin | 0 -> 689173 bytes | |||
-rw-r--r-- | net/base/mime_util.cc | 1 |
11 files changed, 75 insertions, 15 deletions
diff --git a/chrome/browser/media/encrypted_media_istypesupported_browsertest.cc b/chrome/browser/media/encrypted_media_istypesupported_browsertest.cc index 647fdaa..1006a2f 100644 --- a/chrome/browser/media/encrypted_media_istypesupported_browsertest.cc +++ b/chrome/browser/media/encrypted_media_istypesupported_browsertest.cc @@ -112,6 +112,10 @@ class EncryptedMediaIsTypeSupportedTest : public InProcessBrowserTest { avc2_codec_.push_back("avc2"); + avc3_codec_.push_back("avc3"); + + avc3_extended_codec_.push_back("avc3.64001f"); + aac_codec_.push_back("mp4a"); avc1_and_aac_codecs_.push_back("avc1"); @@ -138,6 +142,10 @@ class EncryptedMediaIsTypeSupportedTest : public InProcessBrowserTest { } const CodecVector& avc1_dot_codec() const { return avc1_dot_codec_; } const CodecVector& avc2_codec() const { return avc2_codec_; } + const CodecVector& avc3_codec() const { return avc3_codec_; } + const CodecVector& avc3_extended_codec() const { + return avc3_extended_codec_; + } const CodecVector& aac_codec() const { return aac_codec_; } const CodecVector& avc1_and_aac_codecs() const { return avc1_and_aac_codecs_; @@ -243,6 +251,8 @@ class EncryptedMediaIsTypeSupportedTest : public InProcessBrowserTest { CodecVector avc1_extended_codec_; CodecVector avc1_dot_codec_; CodecVector avc2_codec_; + CodecVector avc3_codec_; + CodecVector avc3_extended_codec_; CodecVector aac_codec_; CodecVector avc1_and_aac_codecs_; CodecVector unknown_codec_; @@ -444,11 +454,15 @@ IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedTest, EXPECT_PROPRIETARY(IsSupportedKeySystemWithMediaMimeType( "video/mp4", avc1_and_aac_codecs(), kPrefixedClearKey)); EXPECT_PROPRIETARY(IsSupportedKeySystemWithMediaMimeType( + "video/mp4", avc3_codec(), kPrefixedClearKey)); + EXPECT_PROPRIETARY(IsSupportedKeySystemWithMediaMimeType( "video/mp4", aac_codec(), kPrefixedClearKey)); // Extended codecs. EXPECT_PROPRIETARY(IsSupportedKeySystemWithMediaMimeType( "video/mp4", avc1_extended_codec(), kPrefixedClearKey)); + EXPECT_PROPRIETARY(IsSupportedKeySystemWithMediaMimeType( + "video/mp4", avc3_extended_codec(), kPrefixedClearKey)); // Invalid codec format, but canPlayType() strips away the period. EXPECT_PROPRIETARY(IsSupportedKeySystemWithMediaMimeType( @@ -475,6 +489,8 @@ IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedTest, "audio/mp4", avc1_codec(), kPrefixedClearKey)); EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( "audio/mp4", avc1_and_aac_codecs(), kPrefixedClearKey)); + EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( + "audio/mp4", avc3_codec(), kPrefixedClearKey)); // Non-MP4 codec. EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( @@ -614,11 +630,15 @@ IN_PROC_BROWSER_TEST_F( EXPECT_ECKPROPRIETARY(IsSupportedKeySystemWithMediaMimeType( "video/mp4", avc1_and_aac_codecs(), kExternalClearKey)); EXPECT_ECKPROPRIETARY(IsSupportedKeySystemWithMediaMimeType( + "video/mp4", avc3_codec(), kExternalClearKey)); + EXPECT_ECKPROPRIETARY(IsSupportedKeySystemWithMediaMimeType( "video/mp4", aac_codec(), kExternalClearKey)); // Extended codecs. EXPECT_ECKPROPRIETARY(IsSupportedKeySystemWithMediaMimeType( "video/mp4", avc1_extended_codec(), kExternalClearKey)); + EXPECT_ECKPROPRIETARY(IsSupportedKeySystemWithMediaMimeType( + "video/mp4", avc3_extended_codec(), kExternalClearKey)); // Invalid codec format, but canPlayType() strips away the period. EXPECT_ECKPROPRIETARY(IsSupportedKeySystemWithMediaMimeType( @@ -645,6 +665,8 @@ IN_PROC_BROWSER_TEST_F( "audio/mp4", avc1_codec(), kExternalClearKey)); EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( "audio/mp4", avc1_and_aac_codecs(), kExternalClearKey)); + EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( + "audio/mp4", avc3_codec(), kExternalClearKey)); // Non-MP4 codec. EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( @@ -792,6 +814,8 @@ IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedWidevineTest, "video/mp4", avc1_codec(), kWidevineAlpha)); EXPECT_WVAVC1AAC(IsSupportedKeySystemWithMediaMimeType( "video/mp4", avc1_and_aac_codecs(), kWidevineAlpha)); + EXPECT_WVAVC1(IsSupportedKeySystemWithMediaMimeType( + "video/mp4", avc3_codec(), kWidevineAlpha)); EXPECT_WVAVC1AAC(IsSupportedKeySystemWithMediaMimeType( "video/mp4", aac_codec(), kWidevineAlpha)); @@ -808,6 +832,8 @@ IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedWidevineTest, // Extended codecs. EXPECT_WVAVC1(IsSupportedKeySystemWithMediaMimeType( "video/mp4", avc1_extended_codec(), kWidevineAlpha)); + EXPECT_WVAVC1(IsSupportedKeySystemWithMediaMimeType( + "video/mp4", avc3_extended_codec(), kWidevineAlpha)); // Invalid codec format, but canPlayType() strips away the period. EXPECT_WVAVC1(IsSupportedKeySystemWithMediaMimeType( @@ -840,6 +866,8 @@ IN_PROC_BROWSER_TEST_F(EncryptedMediaIsTypeSupportedWidevineTest, "audio/mp4", avc1_codec(), kWidevineAlpha)); EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( "audio/mp4", avc1_and_aac_codecs(), kWidevineAlpha)); + EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( + "audio/mp4", avc3_codec(), kWidevineAlpha)); // Non-MP4 codec. EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType( diff --git a/chrome/renderer/media/chrome_key_systems.cc b/chrome/renderer/media/chrome_key_systems.cc index 12dfa92..c169d53 100644 --- a/chrome/renderer/media/chrome_key_systems.cc +++ b/chrome/renderer/media/chrome_key_systems.cc @@ -36,8 +36,8 @@ const char kVorbisVP8[] = "vorbis,vp8,vp8.0"; const char kAudioMp4[] = "audio/mp4"; const char kVideoMp4[] = "video/mp4"; const char kMp4a[] = "mp4a"; -const char kAvc1[] = "avc1"; -const char kMp4aAvc1[] = "mp4a,avc1"; +const char kAvc1Avc3[] = "avc1,avc3"; +const char kMp4aAvc1Avc3[] = "mp4a,avc1,avc3"; #endif // defined(USE_PROPRIETARY_CODECS) #if defined(ENABLE_PEPPER_CDMS) @@ -67,7 +67,7 @@ static void AddExternalClearKey( info.supported_types.push_back(std::make_pair(kVideoWebM, kVorbisVP8)); #if defined(USE_PROPRIETARY_CODECS) info.supported_types.push_back(std::make_pair(kAudioMp4, kMp4a)); - info.supported_types.push_back(std::make_pair(kVideoMp4, kMp4aAvc1)); + info.supported_types.push_back(std::make_pair(kVideoMp4, kMp4aAvc1Avc3)); #endif // defined(USE_PROPRIETARY_CODECS) info.pepper_type = kExternalClearKeyPepperType; @@ -163,7 +163,8 @@ static void AddWidevineWithCodecs( info.supported_types.push_back(std::make_pair(kAudioMp4, kMp4a)); if (supported_codecs & MP4_AVC1) { - const char* video_codecs = (supported_codecs & MP4_AAC) ? kMp4aAvc1 : kAvc1; + const char* video_codecs = + (supported_codecs & MP4_AAC) ? kMp4aAvc1Avc3 : kAvc1Avc3; info.supported_types.push_back(std::make_pair(kVideoMp4, video_codecs)); } #endif // defined(USE_PROPRIETARY_CODECS) diff --git a/content/renderer/media/crypto/key_systems.cc b/content/renderer/media/crypto/key_systems.cc index 5b63971..3cd9385 100644 --- a/content/renderer/media/crypto/key_systems.cc +++ b/content/renderer/media/crypto/key_systems.cc @@ -36,7 +36,7 @@ const char kVorbisVP8[] = "vorbis,vp8,vp8.0"; const char kAudioMp4[] = "audio/mp4"; const char kVideoMp4[] = "video/mp4"; const char kMp4a[] = "mp4a"; -const char kMp4aAvc1[] = "mp4a,avc1"; +const char kMp4aAvc1Avc3[] = "mp4a,avc1,avc3"; #endif // defined(USE_PROPRIETARY_CODECS) static void AddClearKey(std::vector<KeySystemInfo>* concrete_key_systems) { @@ -46,7 +46,7 @@ static void AddClearKey(std::vector<KeySystemInfo>* concrete_key_systems) { info.supported_types.push_back(std::make_pair(kVideoWebM, kVorbisVP8)); #if defined(USE_PROPRIETARY_CODECS) info.supported_types.push_back(std::make_pair(kAudioMp4, kMp4a)); - info.supported_types.push_back(std::make_pair(kVideoMp4, kMp4aAvc1)); + info.supported_types.push_back(std::make_pair(kVideoMp4, kMp4aAvc1Avc3)); #endif // defined(USE_PROPRIETARY_CODECS) info.use_aes_decryptor = true; diff --git a/media/filters/pipeline_integration_test.cc b/media/filters/pipeline_integration_test.cc index 698367fa..6f38923 100644 --- a/media/filters/pipeline_integration_test.cc +++ b/media/filters/pipeline_integration_test.cc @@ -34,6 +34,7 @@ const char kMP4AudioType[] = "audio/mp4"; #if defined(USE_PROPRIETARY_CODECS) const char kMP4[] = "video/mp4; codecs=\"avc1.4D4041,mp4a.40.2\""; const char kMP4Video[] = "video/mp4; codecs=\"avc1.4D4041\""; +const char kMP4VideoAVC3[] = "video/mp4; codecs=\"avc3.64001f\""; const char kMP4Audio[] = "audio/mp4; codecs=\"mp4a.40.2\""; const char kMP3[] = "audio/mpeg"; #endif // defined(USE_PROPRIETARY_CODECS) @@ -69,6 +70,7 @@ const char kBenchmarkAudioFile[] = "benchmark-audio-file"; const int k640IsoFileDurationMs = 2737; const int k640IsoCencFileDurationMs = 2736; const int k1280IsoFileDurationMs = 2736; +const int k1280IsoAVC3FileDurationMs = 2735; #endif // defined(USE_PROPRIETARY_CODECS) // Note: Tests using this class only exercise the DecryptingDemuxerStream path. @@ -963,6 +965,25 @@ TEST_F(PipelineIntegrationTest, source.Abort(); Stop(); } + +TEST_F(PipelineIntegrationTest, BasicPlayback_MediaSource_VideoOnly_MP4_AVC3) { + MockMediaSource source("bear-1280x720-v_frag-avc3.mp4", kMP4VideoAVC3, + kAppendWholeFile); + StartPipelineWithMediaSource(&source); + source.EndOfStream(); + + EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); + EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); + EXPECT_EQ(k1280IsoAVC3FileDurationMs, + pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); + + Play(); + + ASSERT_TRUE(WaitUntilOnEnded()); + source.Abort(); + Stop(); +} + #endif // TODO(acolwell): Fix flakiness http://crbug.com/117921 diff --git a/media/filters/stream_parser_factory.cc b/media/filters/stream_parser_factory.cc index c41164b..b743688 100644 --- a/media/filters/stream_parser_factory.cc +++ b/media/filters/stream_parser_factory.cc @@ -130,8 +130,10 @@ bool ValidateMP4ACodecID(const std::string& codec_id, const LogCB& log_cb) { return false; } -static const CodecInfo kH264CodecInfo = { "avc1.*", CodecInfo::VIDEO, NULL, - CodecInfo::HISTOGRAM_H264 }; +static const CodecInfo kH264AVC1CodecInfo = { "avc1.*", CodecInfo::VIDEO, NULL, + CodecInfo::HISTOGRAM_H264 }; +static const CodecInfo kH264AVC3CodecInfo = { "avc3.*", CodecInfo::VIDEO, NULL, + CodecInfo::HISTOGRAM_H264 }; static const CodecInfo kMPEG4AACCodecInfo = { "mp4a.40.*", CodecInfo::AUDIO, &ValidateMP4ACodecID, CodecInfo::HISTOGRAM_MPEG4AAC }; @@ -145,7 +147,8 @@ static const CodecInfo kEAC3CodecInfo = { "mp4a.a6", CodecInfo::AUDIO, NULL, #endif static const CodecInfo* kVideoMP4Codecs[] = { - &kH264CodecInfo, + &kH264AVC1CodecInfo, + &kH264AVC3CodecInfo, &kMPEG4AACCodecInfo, &kMPEG2AACLCCodecInfo, NULL diff --git a/media/mp4/box_definitions.cc b/media/mp4/box_definitions.cc index e7f1693..218e5bb 100644 --- a/media/mp4/box_definitions.cc +++ b/media/mp4/box_definitions.cc @@ -399,13 +399,18 @@ bool VideoSampleEntry::Parse(BoxReader* reader) { } } - if (format == FOURCC_AVC1 || - (format == FOURCC_ENCV && sinf.format.format == FOURCC_AVC1)) { + if (IsFormatValid()) RCHECK(reader->ReadChild(&avcc)); - } + return true; } +bool VideoSampleEntry::IsFormatValid() const { + return format == FOURCC_AVC1 || format == FOURCC_AVC3 || + (format == FOURCC_ENCV && (sinf.format.format == FOURCC_AVC1 || + sinf.format.format == FOURCC_AVC3)); +} + ElementaryStreamDescriptor::ElementaryStreamDescriptor() : object_type(kForbidden) {} diff --git a/media/mp4/box_definitions.h b/media/mp4/box_definitions.h index eab8c4f..d2af86d 100644 --- a/media/mp4/box_definitions.h +++ b/media/mp4/box_definitions.h @@ -183,6 +183,8 @@ struct MEDIA_EXPORT VideoSampleEntry : Box { // Currently expected to be present regardless of format. AVCDecoderConfigurationRecord avcc; + + bool IsFormatValid() const; }; struct MEDIA_EXPORT ElementaryStreamDescriptor : Box { diff --git a/media/mp4/fourccs.h b/media/mp4/fourccs.h index b71d2ff3..01cce2b 100644 --- a/media/mp4/fourccs.h +++ b/media/mp4/fourccs.h @@ -13,6 +13,7 @@ namespace mp4 { enum FourCC { FOURCC_NULL = 0, FOURCC_AVC1 = 0x61766331, + FOURCC_AVC3 = 0x61766333, FOURCC_AVCC = 0x61766343, FOURCC_BLOC = 0x626C6F63, FOURCC_CENC = 0x63656e63, diff --git a/media/mp4/mp4_stream_parser.cc b/media/mp4/mp4_stream_parser.cc index 26cee44..19855ab 100644 --- a/media/mp4/mp4_stream_parser.cc +++ b/media/mp4/mp4_stream_parser.cc @@ -268,9 +268,7 @@ bool MP4StreamParser::ParseMoov(BoxReader* reader) { desc_idx = 0; const VideoSampleEntry& entry = samp_descr.video_entries[desc_idx]; - if (!(entry.format == FOURCC_AVC1 || - (entry.format == FOURCC_ENCV && - entry.sinf.format.format == FOURCC_AVC1))) { + if (!entry.IsFormatValid()) { MEDIA_LOG(log_cb_) << "Unsupported video format 0x" << std::hex << entry.format << " in stsd box."; return false; diff --git a/media/test/data/bear-1280x720-v_frag-avc3.mp4 b/media/test/data/bear-1280x720-v_frag-avc3.mp4 Binary files differnew file mode 100644 index 0000000..25970ac --- /dev/null +++ b/media/test/data/bear-1280x720-v_frag-avc3.mp4 diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc index 70dd353..3d34428 100644 --- a/net/base/mime_util.cc +++ b/net/base/mime_util.cc @@ -315,6 +315,7 @@ static const char* const common_media_codecs[] = { // List of proprietary codecs only supported by Google Chrome. static const char* const proprietary_media_codecs[] = { "avc1", + "avc3", "mp4a" }; |