Bug 1330284 - Use MediaContentType in WebMDecoder - r=jya
authorGerald Squelart <gsquelart@mozilla.com>
Sun, 01 Jan 2017 12:16:38 +1100
changeset 374467 571b1d64748c01fe7c6b014bacc31187bd4b6f66
parent 374466 45673c5c9e207343e9cb41a93350665c38261d04
child 374468 f65d9b2df6eedbca013adc4112b8ee3fb7e7a0b8
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1330284
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1330284 - Use MediaContentType in WebMDecoder - r=jya MozReview-Commit-ID: 5tcc9of73WR
dom/media/DecoderTraits.cpp
dom/media/DecoderTraits.h
dom/media/eme/MediaKeySystemAccess.cpp
dom/media/gtest/TestMediaDataDecoder.cpp
dom/media/webm/WebMDecoder.cpp
dom/media/webm/WebMDecoder.h
--- a/dom/media/DecoderTraits.cpp
+++ b/dom/media/DecoderTraits.cpp
@@ -57,35 +57,16 @@ CodecListContains(char const *const * aC
 {
   for (int32_t i = 0; aCodecs[i]; ++i) {
     if (aCodec.EqualsASCII(aCodecs[i]))
       return true;
   }
   return false;
 }
 
-static bool
-IsWebMSupportedType(const nsACString& aType,
-                    const nsAString& aCodecs = EmptyString())
-{
-  return WebMDecoder::CanHandleMediaType(aType, aCodecs);
-}
-
-/* static */ bool
-DecoderTraits::IsWebMTypeAndEnabled(const nsACString& aType)
-{
-  return IsWebMSupportedType(aType);
-}
-
-/* static */ bool
-DecoderTraits::IsWebMAudioType(const nsACString& aType)
-{
-  return aType.EqualsASCII("audio/webm");
-}
-
 static char const *const gHttpLiveStreamingTypes[] = {
   // For m3u8.
   // https://tools.ietf.org/html/draft-pantos-http-live-streaming-19#section-10
   "application/vnd.apple.mpegurl",
   // Some sites serve these as the informal m3u type.
   "application/x-mpegurl",
   "audio/x-mpegurl",
   nullptr
@@ -205,19 +186,18 @@ CanHandleCodecsType(const MediaContentTy
       return CANPLAY_YES;
     } else {
       // We can only reach this position if a particular codec was requested,
       // ogg is supported and working: the codec must be invalid.
       return CANPLAY_NO;
     }
   }
 #if !defined(MOZ_OMX_WEBM_DECODER)
-  if (DecoderTraits::IsWebMTypeAndEnabled(mimeType.Type().AsString())) {
-    if (IsWebMSupportedType(aType.Type().AsString(),
-                            aType.ExtendedType().Codecs().AsString())) {
+  if (WebMDecoder::IsSupportedType(mimeType)) {
+    if (WebMDecoder::IsSupportedType(aType)) {
       return CANPLAY_YES;
     } else {
       // We can only reach this position if a particular codec was requested,
       // webm is supported and working: the codec must be invalid.
       return CANPLAY_NO;
     }
   }
 #endif
@@ -305,17 +285,17 @@ CanHandleMediaType(const MediaContentTyp
   }
   if (IsWaveSupportedType(mimeType.Type().AsString())) {
     return CANPLAY_MAYBE;
   }
   if (DecoderTraits::IsMP4TypeAndEnabled(mimeType.Type().AsString(), aDiagnostics)) {
     return CANPLAY_MAYBE;
   }
 #if !defined(MOZ_OMX_WEBM_DECODER)
-  if (DecoderTraits::IsWebMTypeAndEnabled(mimeType.Type().AsString())) {
+  if (WebMDecoder::IsSupportedType(mimeType)) {
     return CANPLAY_MAYBE;
   }
 #endif
   if (IsMP3SupportedType(mimeType.Type().AsString())) {
     return CANPLAY_MAYBE;
   }
   if (IsAACSupportedType(mimeType.Type().AsString())) {
     return CANPLAY_MAYBE;
@@ -417,17 +397,17 @@ InstantiateDecoder(const MediaContentTyp
   if (MediaDecoder::IsAndroidMediaPluginEnabled() &&
       EnsureAndroidMediaPluginHost()->FindDecoder(aType.Type().AsString(),
                                                   nullptr)) {
     decoder = new AndroidMediaDecoder(aOwner, aType.Type().AsString());
     return decoder.forget();
   }
 #endif
 
-  if (IsWebMSupportedType(aType.Type().AsString())) {
+  if (WebMDecoder::IsSupportedType(aType)) {
     decoder = new WebMDecoder(aOwner);
     return decoder.forget();
   }
 
 #ifdef MOZ_DIRECTSHOW
   // Note: DirectShow should come before WMF, so that we prefer DirectShow's
   // MP3 support over WMF's.
   if (IsDirectShowSupportedType(aType.Type().AsString())) {
@@ -493,17 +473,17 @@ MediaDecoderReader* DecoderTraits::Creat
     decoderReader = new MediaFormatReader(aDecoder, new OggDemuxer(aDecoder->GetResource()));
   } else
 #ifdef MOZ_ANDROID_OMX
   if (MediaDecoder::IsAndroidMediaPluginEnabled() &&
       EnsureAndroidMediaPluginHost()->FindDecoder(aType, nullptr)) {
     decoderReader = new AndroidMediaReader(aDecoder, aType);
   } else
 #endif
-  if (IsWebMSupportedType(aType)) {
+  if (WebMDecoder::IsSupportedType(*type)) {
     decoderReader =
       new MediaFormatReader(aDecoder, new WebMDemuxer(aDecoder->GetResource()));
   } else
 #ifdef MOZ_DIRECTSHOW
   if (IsDirectShowSupportedType(aType)) {
     decoderReader = new DirectShowReader(aDecoder);
   } else
 #endif
@@ -525,17 +505,17 @@ bool DecoderTraits::IsSupportedInVideoDo
 
   Maybe<MediaContentType> type = MakeMediaContentType(aType);
   if (!type) {
     return false;
   }
 
   return
     OggDecoder::IsSupportedType(*type) ||
-    IsWebMSupportedType(aType) ||
+    WebMDecoder::IsSupportedType(*type) ||
 #ifdef MOZ_ANDROID_OMX
     (MediaDecoder::IsAndroidMediaPluginEnabled() && IsAndroidMediaType(aType)) ||
 #endif
 #ifdef MOZ_FMP4
     IsMP4SupportedType(aType, /* DecoderDoctorDiagnostics* */ nullptr) ||
 #endif
     IsMP3SupportedType(aType) ||
     IsAACSupportedType(aType) ||
--- a/dom/media/DecoderTraits.h
+++ b/dom/media/DecoderTraits.h
@@ -51,18 +51,16 @@ public:
   static MediaDecoderReader* CreateReader(const nsACString& aType,
                                           AbstractMediaDecoder* aDecoder);
 
   // Returns true if MIME type aType is supported in video documents,
   // or false otherwise. Not all platforms support all MIME types, and
   // vice versa.
   static bool IsSupportedInVideoDocument(const nsACString& aType);
 
-  static bool IsWebMTypeAndEnabled(const nsACString& aType);
-  static bool IsWebMAudioType(const nsACString& aType);
   static bool IsMP4TypeAndEnabled(const nsACString& aType,
                                   DecoderDoctorDiagnostics* aDiagnostics);
 };
 
 } // namespace mozilla
 
 #endif
 
--- a/dom/media/eme/MediaKeySystemAccess.cpp
+++ b/dom/media/eme/MediaKeySystemAccess.cpp
@@ -646,18 +646,17 @@ GetSupportedCapabilities(const CodecType
       EME_LOG("MediaKeySystemConfiguration (label='%s') "
               "MediaKeySystemMediaCapability('%s','%s') unsupported; "
               "MP4 requested but unsupported.",
               NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
               NS_ConvertUTF16toUTF8(contentTypeString).get(),
               NS_ConvertUTF16toUTF8(robustness).get());
       continue;
     }
-    const bool isWebM =
-      DecoderTraits::IsWebMTypeAndEnabled(contentType.Type().AsString());
+    const bool isWebM = WebMDecoder::IsSupportedType(contentType);
     if (isWebM && !aKeySystem.mWebM.IsSupported()) {
       EME_LOG("MediaKeySystemConfiguration (label='%s') "
               "MediaKeySystemMediaCapability('%s','%s') unsupported; "
               "WebM requested but unsupported.",
               NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
               NS_ConvertUTF16toUTF8(contentTypeString).get(),
               NS_ConvertUTF16toUTF8(robustness).get());
       continue;
--- a/dom/media/gtest/TestMediaDataDecoder.cpp
+++ b/dom/media/gtest/TestMediaDataDecoder.cpp
@@ -2,17 +2,19 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "gtest/gtest.h"
 #include "Benchmark.h"
 #include "MockMediaResource.h"
 #include "DecoderTraits.h"
+#include "MediaContentType.h"
 #include "MP4Demuxer.h"
+#include "WebMDecoder.h"
 #include "WebMDemuxer.h"
 
 using namespace mozilla;
 
 class BenchmarkRunner
 {
 public:
   explicit BenchmarkRunner(Benchmark* aBenchmark)
@@ -53,17 +55,17 @@ TEST(MediaDataDecoder, H264)
 
     BenchmarkRunner runner(new Benchmark(new MP4Demuxer(resource)));
     EXPECT_GT(runner.Run(), 0u);
   }
 }
 
 TEST(MediaDataDecoder, VP9)
 {
-  if (!DecoderTraits::IsWebMTypeAndEnabled(NS_LITERAL_CSTRING("video/webm"))) {
+  if (!WebMDecoder::IsSupportedType(MediaContentType(MEDIAMIMETYPE("video/webm")))) {
     EXPECT_TRUE(true);
   } else {
     RefPtr<MediaResource> resource =
       new MockMediaResource("vp9cake.webm", NS_LITERAL_CSTRING("video/webm"));
     nsresult rv = resource->Open(nullptr);
     EXPECT_TRUE(NS_SUCCEEDED(rv));
 
     BenchmarkRunner runner(new Benchmark(new WebMDemuxer(resource)));
--- a/dom/media/webm/WebMDecoder.cpp
+++ b/dom/media/webm/WebMDecoder.cpp
@@ -1,97 +1,67 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Preferences.h"
+#include "MediaContentType.h"
 #include "MediaDecoderStateMachine.h"
 #include "WebMDemuxer.h"
 #include "WebMDecoder.h"
 #include "VideoUtils.h"
-#include "nsContentTypeParser.h"
 
 namespace mozilla {
 
 MediaDecoderStateMachine* WebMDecoder::CreateStateMachine()
 {
   mReader =
     new MediaFormatReader(this, new WebMDemuxer(GetResource()), GetVideoFrameContainer());
   return new MediaDecoderStateMachine(this, mReader);
 }
 
 /* static */
 bool
-WebMDecoder::IsEnabled()
+WebMDecoder::IsSupportedType(const MediaContentType& aContentType)
 {
-  return Preferences::GetBool("media.webm.enabled");
-}
-
-/* static */
-bool
-WebMDecoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
-                                const nsAString& aCodecs)
-{
-  if (!IsEnabled()) {
+  if (!Preferences::GetBool("media.webm.enabled")) {
     return false;
   }
 
-  const bool isWebMAudio = aMIMETypeExcludingCodecs.EqualsASCII("audio/webm");
-  const bool isWebMVideo = aMIMETypeExcludingCodecs.EqualsASCII("video/webm");
-  if (!isWebMAudio && !isWebMVideo) {
+  bool isVideo = aContentType.Type() == MEDIAMIMETYPE("video/webm");
+  if (aContentType.Type() != MEDIAMIMETYPE("audio/webm") && !isVideo) {
     return false;
   }
 
-  nsTArray<nsCString> codecMimes;
-  if (aCodecs.IsEmpty()) {
+  const MediaCodecs& codecs = aContentType.ExtendedType().Codecs();
+  if (codecs.IsEmpty()) {
     // WebM guarantees that the only codecs it contained are vp8, vp9, opus or vorbis.
     return true;
   }
   // Verify that all the codecs specified are ones that we expect that
   // we can play.
-  nsTArray<nsString> codecs;
-  if (!ParseCodecsString(aCodecs, codecs)) {
-    return false;
-  }
-  for (const nsString& codec : codecs) {
+  for (const auto& codec : codecs.Range()) {
     if (codec.EqualsLiteral("opus") || codec.EqualsLiteral("vorbis")) {
       continue;
     }
     // Note: Only accept VP8/VP9 in a video content type, not in an audio
     // content type.
-    if (isWebMVideo &&
+    if (isVideo &&
         (codec.EqualsLiteral("vp8") || codec.EqualsLiteral("vp8.0") ||
          codec.EqualsLiteral("vp9") || codec.EqualsLiteral("vp9.0"))) {
-
       continue;
     }
     // Some unsupported codec.
     return false;
   }
   return true;
 }
 
-/* static */ bool
-WebMDecoder::CanHandleMediaType(const nsAString& aContentType)
-{
-  nsContentTypeParser parser(aContentType);
-  nsAutoString mimeType;
-  nsresult rv = parser.GetType(mimeType);
-  if (NS_FAILED(rv)) {
-    return false;
-  }
-  nsString codecs;
-  parser.GetParameter("codecs", codecs);
-
-  return CanHandleMediaType(NS_ConvertUTF16toUTF8(mimeType),
-                            codecs);
-}
-
 void
 WebMDecoder::GetMozDebugReaderData(nsAString& aString)
 {
   if (mReader) {
     mReader->GetMozDebugReaderData(aString);
   }
 }
 
--- a/dom/media/webm/WebMDecoder.h
+++ b/dom/media/webm/WebMDecoder.h
@@ -6,39 +6,34 @@
 #if !defined(WebMDecoder_h_)
 #define WebMDecoder_h_
 
 #include "MediaDecoder.h"
 #include "MediaFormatReader.h"
 
 namespace mozilla {
 
+class MediaContentType;
+
 class WebMDecoder : public MediaDecoder
 {
 public:
   explicit WebMDecoder(MediaDecoderOwner* aOwner) : MediaDecoder(aOwner) {}
   MediaDecoder* Clone(MediaDecoderOwner* aOwner) override {
     if (!IsWebMEnabled()) {
       return nullptr;
     }
     return new WebMDecoder(aOwner);
   }
   MediaDecoderStateMachine* CreateStateMachine() override;
 
-  // Returns true if the WebM backend is preffed on.
-  static bool IsEnabled();
-
-  // Returns true if aMIMEType is a type that we think we can render with the
-  // a WebM platform decoder backend. If aCodecs is non emtpy, it is filled
-  // with a comma-delimited list of codecs to check support for. Notes in
-  // out params whether the codecs string contains Opus/Vorbis or VP8/VP9.
-  static bool CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
-                                 const nsAString& aCodecs);
-
-  static bool CanHandleMediaType(const nsAString& aContentType);
+  // Returns true if aContentType is a WebM type that we think we can render
+  // with an enabled platform decoder backend.
+  // If provided, codecs are checked for support.
+  static bool IsSupportedType(const MediaContentType& aContentType);
 
   void GetMozDebugReaderData(nsAString& aString) override;
 
 private:
   RefPtr<MediaFormatReader> mReader;
 };
 
 } // namespace mozilla