summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoracolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-18 10:29:55 +0000
committeracolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-18 10:29:55 +0000
commit6ce837cc5935728fa8d506aa1ef502ae758ac745 (patch)
tree8df98d88089d9dacc0588f7c99e6133a1bed466f
parentabafff342a1565ca70e05e8799abb6cdc80608b5 (diff)
downloadchromium_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.cc28
-rw-r--r--chrome/renderer/media/chrome_key_systems.cc9
-rw-r--r--content/renderer/media/crypto/key_systems.cc4
-rw-r--r--media/filters/pipeline_integration_test.cc21
-rw-r--r--media/filters/stream_parser_factory.cc9
-rw-r--r--media/mp4/box_definitions.cc11
-rw-r--r--media/mp4/box_definitions.h2
-rw-r--r--media/mp4/fourccs.h1
-rw-r--r--media/mp4/mp4_stream_parser.cc4
-rw-r--r--media/test/data/bear-1280x720-v_frag-avc3.mp4bin0 -> 689173 bytes
-rw-r--r--net/base/mime_util.cc1
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
new file mode 100644
index 0000000..25970ac
--- /dev/null
+++ b/media/test/data/bear-1280x720-v_frag-avc3.mp4
Binary files differ
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"
};