Bug 1148102: P7. Hookup WebMDemuxer. r=jya
authorJan Gerber <j@mailb.org>
Thu, 18 Jun 2015 15:59:43 +0200
changeset 253674 06340c449def11b56d50573d9fc7898de553b8f5
parent 253673 5a780859dc1c089672dffbabbd920c7bff90c888
child 253675 5b4aec6951dd81465c423029768a1d4880e20729
push id29074
push userryanvm@gmail.com
push dateMon, 20 Jul 2015 19:51:26 +0000
treeherdermozilla-central@b86e3ab5e974 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1148102
milestone42.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 1148102: P7. Hookup WebMDemuxer. r=jya
dom/media/DecoderTraits.cpp
dom/media/MediaFormatReader.cpp
dom/media/mediasource/MediaSourceReader.cpp
dom/media/platforms/PlatformDecoderModule.cpp
dom/media/platforms/PlatformDecoderModule.h
dom/media/platforms/agnostic/BlankDecoderModule.cpp
dom/media/platforms/wmf/WMFDecoderModule.cpp
dom/media/webm/WebMDecoder.cpp
modules/libpref/init/all.js
--- a/dom/media/DecoderTraits.cpp
+++ b/dom/media/DecoderTraits.cpp
@@ -18,16 +18,17 @@
 #include "OggReader.h"
 #ifdef MOZ_WAVE
 #include "WaveDecoder.h"
 #include "WaveReader.h"
 #endif
 #ifdef MOZ_WEBM
 #include "WebMDecoder.h"
 #include "WebMReader.h"
+#include "WebMDemuxer.h"
 #endif
 #ifdef MOZ_RAW
 #include "RawDecoder.h"
 #include "RawReader.h"
 #endif
 #ifdef MOZ_GSTREAMER
 #include "GStreamerDecoder.h"
 #include "GStreamerReader.h"
@@ -693,17 +694,19 @@ MediaDecoderReader* DecoderTraits::Creat
 #ifdef MOZ_ANDROID_OMX
   if (MediaDecoder::IsAndroidMediaEnabled() &&
       EnsureAndroidMediaPluginHost()->FindDecoder(aType, nullptr)) {
     decoderReader = new AndroidMediaReader(aDecoder, aType);
   } else
 #endif
 #ifdef MOZ_WEBM
   if (IsWebMType(aType)) {
-    decoderReader = new WebMReader(aDecoder);
+    decoderReader = Preferences::GetBool("media.format-reader.webm", true) ?
+      static_cast<MediaDecoderReader*>(new MediaFormatReader(aDecoder, new WebMDemuxer(aDecoder->GetResource()))) :
+      new WebMReader(aDecoder);
   } else
 #endif
 #ifdef MOZ_DIRECTSHOW
   if (IsDirectShowSupportedType(aType)) {
     decoderReader = new DirectShowReader(aDecoder);
   } else
 #endif
 #ifdef MOZ_APPLEMEDIA
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -253,23 +253,25 @@ bool MediaFormatReader::IsWaitingOnCDMRe
 #else
   return false;
 #endif
 }
 
 bool
 MediaFormatReader::IsSupportedAudioMimeType(const nsACString& aMimeType)
 {
-  return mPlatform && mPlatform->SupportsMimeType(aMimeType);
+  return mPlatform && (mPlatform->SupportsMimeType(aMimeType) ||
+    PlatformDecoderModule::AgnosticMimeType(aMimeType));
 }
 
 bool
 MediaFormatReader::IsSupportedVideoMimeType(const nsACString& aMimeType)
 {
-  return mPlatform && mPlatform->SupportsMimeType(aMimeType);
+  return mPlatform && (mPlatform->SupportsMimeType(aMimeType) ||
+    PlatformDecoderModule::AgnosticMimeType(aMimeType));
 }
 
 nsRefPtr<MediaDecoderReader::MetadataPromise>
 MediaFormatReader::AsyncReadMetadata()
 {
   MOZ_ASSERT(OnTaskQueue());
 
   if (mInitDone) {
--- a/dom/media/mediasource/MediaSourceReader.cpp
+++ b/dom/media/mediasource/MediaSourceReader.cpp
@@ -20,16 +20,17 @@
 #include "SharedDecoderManager.h"
 #include "MP4Decoder.h"
 #include "MP4Demuxer.h"
 #include "MP4Reader.h"
 #endif
 
 #ifdef MOZ_WEBM
 #include "WebMReader.h"
+#include "WebMDemuxer.h"
 #endif
 
 extern PRLogModuleInfo* GetMediaSourceLog();
 
 #define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), mozilla::LogLevel::Debug, ("MediaSourceReader(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 #define MSE_DEBUGV(arg, ...) MOZ_LOG(GetMediaSourceLog(), mozilla::LogLevel::Verbose, ("MediaSourceReader(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 
 // When a stream hits EOS it needs to decide what other stream to switch to. Due
@@ -713,17 +714,22 @@ CreateReaderForType(const nsACString& aT
       static_cast<MediaDecoderReader*>(new MediaFormatReader(aDecoder, new MP4Demuxer(aDecoder->GetResource()), aBorrowedTaskQueue)) :
       static_cast<MediaDecoderReader*>(new MP4Reader(aDecoder, aBorrowedTaskQueue));
     return reader;
   }
 #endif
 
 #ifdef MOZ_WEBM
   if (DecoderTraits::IsWebMType(aType)) {
-    return new WebMReader(aDecoder, aBorrowedTaskQueue);
+    bool useFormatDecoder =
+      Preferences::GetBool("media.mediasource.format-reader.webm", true);
+    MediaDecoderReader* reader = useFormatDecoder ?
+      static_cast<MediaDecoderReader*>(new MediaFormatReader(aDecoder, new WebMDemuxer(aDecoder->GetResource()), aBorrowedTaskQueue)) :
+      new WebMReader(aDecoder, aBorrowedTaskQueue);
+    return reader;
   }
 #endif
 
   return nullptr;
 }
 
 already_AddRefed<SourceBufferDecoder>
 MediaSourceReader::CreateSubDecoder(const nsACString& aType, int64_t aTimestampOffset)
--- a/dom/media/platforms/PlatformDecoderModule.cpp
+++ b/dom/media/platforms/PlatformDecoderModule.cpp
@@ -30,18 +30,23 @@
 #include "EMEDecoderModule.h"
 #include "mozilla/CDMProxy.h"
 #endif
 #include "SharedThreadPool.h"
 
 #include "MediaInfo.h"
 #include "H264Converter.h"
 
+#include "OpusDecoder.h"
+#include "VorbisDecoder.h"
+#include "VPXDecoder.h"
+
 namespace mozilla {
 
+extern already_AddRefed<PlatformDecoderModule> CreateAgnosticDecoderModule();
 extern already_AddRefed<PlatformDecoderModule> CreateBlankDecoderModule();
 
 bool PlatformDecoderModule::sUseBlankDecoder = false;
 bool PlatformDecoderModule::sFFmpegDecoderEnabled = false;
 bool PlatformDecoderModule::sGonkDecoderEnabled = false;
 bool PlatformDecoderModule::sAndroidMCDecoderEnabled = false;
 bool PlatformDecoderModule::sAndroidMCDecoderPreferred = false;
 bool PlatformDecoderModule::sGMPDecoderEnabled = false;
@@ -119,17 +124,17 @@ PlatformDecoderModule::Create()
 {
   // Note: This (usually) runs on the decode thread.
 
   nsRefPtr<PlatformDecoderModule> m(CreatePDM());
 
   if (m && NS_SUCCEEDED(m->Startup())) {
     return m.forget();
   }
-  return nullptr;
+  return CreateAgnosticDecoderModule();
 }
 
 /* static */
 already_AddRefed<PlatformDecoderModule>
 PlatformDecoderModule::CreatePDM()
 {
 #ifdef MOZ_WIDGET_ANDROID
   if(sAndroidMCDecoderPreferred && sAndroidMCDecoderEnabled){
@@ -179,34 +184,51 @@ already_AddRefed<MediaDataDecoder>
 PlatformDecoderModule::CreateDecoder(const TrackInfo& aConfig,
                                      FlushableTaskQueue* aTaskQueue,
                                      MediaDataDecoderCallback* aCallback,
                                      layers::LayersBackend aLayersBackend,
                                      layers::ImageContainer* aImageContainer)
 {
   nsRefPtr<MediaDataDecoder> m;
 
+  bool hasPlatformDecoder = SupportsMimeType(aConfig.mMimeType);
+
   if (aConfig.GetAsAudioInfo()) {
-    m = CreateAudioDecoder(*aConfig.GetAsAudioInfo(),
-                           aTaskQueue,
-                           aCallback);
+    if (!hasPlatformDecoder && VorbisDataDecoder::IsVorbis(aConfig.mMimeType)) {
+      m = new VorbisDataDecoder(*aConfig.GetAsAudioInfo(),
+                                aTaskQueue,
+                                aCallback);
+    } else if (!hasPlatformDecoder && OpusDataDecoder::IsOpus(aConfig.mMimeType)) {
+      m = new OpusDataDecoder(*aConfig.GetAsAudioInfo(),
+                              aTaskQueue,
+                              aCallback);
+    } else {
+      m = CreateAudioDecoder(*aConfig.GetAsAudioInfo(),
+                             aTaskQueue,
+                             aCallback);
+    }
     return m.forget();
   }
 
   if (!aConfig.GetAsVideoInfo()) {
     return nullptr;
   }
 
   if (H264Converter::IsH264(aConfig)) {
     m = new H264Converter(this,
                           *aConfig.GetAsVideoInfo(),
                           aLayersBackend,
                           aImageContainer,
                           aTaskQueue,
                           aCallback);
+  } else if (!hasPlatformDecoder && VPXDecoder::IsVPX(aConfig.mMimeType)) {
+    m = new VPXDecoder(*aConfig.GetAsVideoInfo(),
+                       aImageContainer,
+                       aTaskQueue,
+                       aCallback);
   } else {
     m = CreateVideoDecoder(*aConfig.GetAsVideoInfo(),
                            aLayersBackend,
                            aImageContainer,
                            aTaskQueue,
                            aCallback);
   }
   return m.forget();
@@ -215,9 +237,19 @@ PlatformDecoderModule::CreateDecoder(con
 bool
 PlatformDecoderModule::SupportsMimeType(const nsACString& aMimeType)
 {
   return aMimeType.EqualsLiteral("audio/mp4a-latm") ||
     aMimeType.EqualsLiteral("video/mp4") ||
     aMimeType.EqualsLiteral("video/avc");
 }
 
+/* static */
+bool
+PlatformDecoderModule::AgnosticMimeType(const nsACString& aMimeType)
+{
+  return VPXDecoder::IsVPX(aMimeType) ||
+    OpusDataDecoder::IsOpus(aMimeType) ||
+    VorbisDataDecoder::IsVorbis(aMimeType);
+}
+
+
 } // namespace mozilla
--- a/dom/media/platforms/PlatformDecoderModule.h
+++ b/dom/media/platforms/PlatformDecoderModule.h
@@ -88,31 +88,35 @@ public:
                 layers::ImageContainer* aImageContainer = nullptr);
 
   // An audio decoder module must support AAC by default.
   // A video decoder must support H264 by default.
   // If more codecs are to be supported, SupportsMimeType will have
   // to be extended
   virtual bool SupportsMimeType(const nsACString& aMimeType);
 
+  // MimeType can be decoded with shipped decoders if no platform decoders exist
+  static bool AgnosticMimeType(const nsACString& aMimeType);
+
+
   enum ConversionRequired {
     kNeedNone,
     kNeedAVCC,
     kNeedAnnexB,
   };
 
   // Indicates that the decoder requires a specific format.
   // The PlatformDecoderModule will convert the demuxed data accordingly before
   // feeding it to MediaDataDecoder::Input.
   virtual ConversionRequired DecoderNeedsConversion(const TrackInfo& aConfig) const = 0;
 
   virtual void DisableHardwareAcceleration() {}
 
   virtual bool SupportsSharedDecoders(const VideoInfo& aConfig) const {
-    return true;
+    return !AgnosticMimeType(aConfig.mMimeType);
   }
 
 protected:
   PlatformDecoderModule() {}
   virtual ~PlatformDecoderModule() {}
 
   friend class H264Converter;
   // Creates a Video decoder. The layers backend is passed in so that
--- a/dom/media/platforms/agnostic/BlankDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/BlankDecoderModule.cpp
@@ -241,23 +241,45 @@ public:
   }
 
   virtual bool
   SupportsMimeType(const nsACString& aMimeType) override
   {
     return true;
   }
 
+  virtual bool
+  SupportsSharedDecoders(const VideoInfo& aConfig) const override {
+    return false;
+  }
+
   virtual ConversionRequired
   DecoderNeedsConversion(const TrackInfo& aConfig) const override
   {
     return kNeedNone;
   }
 
 };
 
+class AgnosticDecoderModule : public BlankDecoderModule {
+public:
+
+  bool SupportsMimeType(const nsACString& aMimeType) override
+  {
+    // This module does not support any decoders itself,
+    // agnostic decoders are created in PlatformDecoderModule::CreateDecoder
+    return false;
+  }
+};
+
 already_AddRefed<PlatformDecoderModule> CreateBlankDecoderModule()
 {
   nsRefPtr<PlatformDecoderModule> pdm = new BlankDecoderModule();
   return pdm.forget();
 }
 
+already_AddRefed<PlatformDecoderModule> CreateAgnosticDecoderModule()
+{
+  nsRefPtr<PlatformDecoderModule> adm = new AgnosticDecoderModule();
+  return adm.forget();
+}
+
 } // namespace mozilla
--- a/dom/media/platforms/wmf/WMFDecoderModule.cpp
+++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp
@@ -21,16 +21,17 @@
 #include "MediaInfo.h"
 #include "prsystem.h"
 
 namespace mozilla {
 
 static bool sIsWMFEnabled = false;
 static bool sDXVAEnabled = false;
 static int  sNumDecoderThreads = -1;
+static bool sIsIntelDecoderEnabled = false;
 
 WMFDecoderModule::WMFDecoderModule()
   : mWMFInitialized(false)
 {
 }
 
 WMFDecoderModule::~WMFDecoderModule()
 {
@@ -39,16 +40,17 @@ WMFDecoderModule::~WMFDecoderModule()
     NS_ASSERTION(SUCCEEDED(hr), "MFShutdown failed");
   }
 }
 
 void
 WMFDecoderModule::DisableHardwareAcceleration()
 {
   sDXVAEnabled = false;
+  sIsIntelDecoderEnabled = false;
 }
 
 static void
 SetNumOfDecoderThreads()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Preferences can only be read on main thread");
   int32_t numCores = PR_GetNumberOfProcessors();
 
@@ -67,16 +69,17 @@ SetNumOfDecoderThreads()
 
 /* static */
 void
 WMFDecoderModule::Init()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
   sIsWMFEnabled = Preferences::GetBool("media.windows-media-foundation.enabled", false);
   sDXVAEnabled = gfxPlatform::GetPlatform()->CanUseHardwareVideoDecoding();
+  sIsIntelDecoderEnabled = Preferences::GetBool("media.webm.intel_decoder.enabled", false);
   SetNumOfDecoderThreads();
 }
 
 /* static */
 int
 WMFDecoderModule::GetNumDecoderThreads()
 {
   return sNumDecoderThreads;
@@ -140,28 +143,30 @@ WMFDecoderModule::ShouldUseDXVA(const Vi
   return aConfig.mDisplay.width <= 1920 && aConfig.mDisplay.height <= 1200;
 }
 
 bool
 WMFDecoderModule::SupportsSharedDecoders(const VideoInfo& aConfig) const
 {
   // If DXVA is enabled, but we're not going to use it for this specific config, then
   // we can't use the shared decoder.
-  return !sDXVAEnabled || ShouldUseDXVA(aConfig);
+  return !AgnosticMimeType(aConfig.mMimeType) &&
+    (!sDXVAEnabled || ShouldUseDXVA(aConfig));
 }
 
 bool
 WMFDecoderModule::SupportsMimeType(const nsACString& aMimeType)
 {
   return aMimeType.EqualsLiteral("video/mp4") ||
          aMimeType.EqualsLiteral("video/avc") ||
-         aMimeType.EqualsLiteral("video/webm; codecs=vp8") ||
-         aMimeType.EqualsLiteral("video/webm; codecs=vp9") ||
          aMimeType.EqualsLiteral("audio/mp4a-latm") ||
-         aMimeType.EqualsLiteral("audio/mpeg");
+         aMimeType.EqualsLiteral("audio/mpeg") ||
+         (sIsIntelDecoderEnabled &&
+          (aMimeType.EqualsLiteral("video/webm; codecs=vp8") ||
+           aMimeType.EqualsLiteral("video/webm; codecs=vp9")));
 }
 
 PlatformDecoderModule::ConversionRequired
 WMFDecoderModule::DecoderNeedsConversion(const TrackInfo& aConfig) const
 {
   if (aConfig.IsVideo() &&
       (aConfig.mMimeType.EqualsLiteral("video/avc") ||
        aConfig.mMimeType.EqualsLiteral("video/mp4"))) {
--- a/dom/media/webm/WebMDecoder.cpp
+++ b/dom/media/webm/WebMDecoder.cpp
@@ -1,19 +1,27 @@
 /* -*- 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 "MediaDecoderStateMachine.h"
+#include "MediaFormatReader.h"
+#include "WebMDemuxer.h"
 #include "WebMReader.h"
 #include "WebMDecoder.h"
 
 namespace mozilla {
 
 MediaDecoderStateMachine* WebMDecoder::CreateStateMachine()
 {
-  return new MediaDecoderStateMachine(this, new WebMReader(this));
+  bool useFormatDecoder =
+    Preferences::GetBool("media.format-reader.webm", true);
+  nsRefPtr<MediaDecoderReader> reader = useFormatDecoder ?
+      static_cast<MediaDecoderReader*>(new MediaFormatReader(this, new WebMDemuxer(GetResource()))) :
+      new WebMReader(this);
+  return new MediaDecoderStateMachine(this, reader);
 }
 
 } // namespace mozilla
 
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -475,16 +475,21 @@ pref("media.mediasource.webm.enabled", f
 // Enable new MediaSource architecture.
 pref("media.mediasource.format-reader", false);
 
 // Enable new MediaFormatReader architecture for mp4 in MSE
 pref("media.mediasource.format-reader.mp4", true);
 // Enable new MediaFormatReader architecture for plain mp4.
 pref("media.format-reader.mp4", true);
 
+// Enable new MediaFormatReader architecture for webm in MSE
+pref("media.mediasource.format-reader.webm", false);
+// Enable new MediaFormatReader architecture for plain webm.
+pref("media.format-reader.webm", false);
+
 #ifdef MOZ_WEBSPEECH
 pref("media.webspeech.recognition.enable", false);
 pref("media.webspeech.synth.enabled", false);
 #endif
 #ifdef MOZ_WEBM_ENCODER
 pref("media.encoder.webm.enabled", true);
 #endif
 #ifdef MOZ_OMX_ENCODER