Bug 1330284 - Use MediaContentType in WebMDecoder - r?jya draft
authorGerald Squelart <gsquelart@mozilla.com>
Sun, 01 Jan 2017 12:16:38 +1100
changeset 460033 31f563a4c8880073eb34e52e92147e58d276f2b0
parent 460032 2ccdbb8e97074b55472b868246ada161a258244e
child 460034 169efd15c0451d72fac7317a439d6064956804fa
push id41348
push usergsquelart@mozilla.com
push dateThu, 12 Jan 2017 20:50:49 +0000
reviewersjya
bugs1330284
milestone53.0a1
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