Bug 1145029 - Disable DXVA for 4k videos on AMD hardware since it performs poorly. r=jya a=lmandel
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 19 Mar 2015 22:01:47 +1300
changeset 250457 2445fcfe99d4
parent 250456 52b55d9c1d61
child 250458 aabde7671ac0
push id4593
push usercpearce@mozilla.com
push date2015-03-19 22:44 +0000
treeherdermozilla-beta@2445fcfe99d4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya, lmandel
bugs1145029
milestone37.0
Bug 1145029 - Disable DXVA for 4k videos on AMD hardware since it performs poorly. r=jya a=lmandel
dom/media/fmp4/MP4Reader.cpp
dom/media/fmp4/PlatformDecoderModule.h
dom/media/fmp4/wmf/WMFDecoderModule.cpp
dom/media/fmp4/wmf/WMFDecoderModule.h
--- a/dom/media/fmp4/MP4Reader.cpp
+++ b/dom/media/fmp4/MP4Reader.cpp
@@ -478,17 +478,17 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo
   if (HasVideo()) {
     const VideoDecoderConfig& video = mDemuxer->VideoConfig();
     if (mInfo.mVideo.mHasVideo && !IsSupportedVideoMimeType(video.mime_type)) {
       return NS_ERROR_FAILURE;
     }
     mInfo.mVideo.mDisplay =
       nsIntSize(video.display_width, video.display_height);
     mVideo.mCallback = new DecoderCallback(this, kVideo);
-    if (!mIsEncrypted && mSharedDecoderManager) {
+    if (!mIsEncrypted && mSharedDecoderManager && mPlatform->SupportsSharedDecoders(video)) {
       // Note: Don't use SharedDecoderManager in EME content, as it doesn't
       // handle reiniting the decoder properly yet.
       mVideo.mDecoder =
         mSharedDecoderManager->CreateVideoDecoder(mPlatform,
                                                   video,
                                                   mLayersBackendType,
                                                   mDecoder->GetImageContainer(),
                                                   mVideo.mTaskQueue,
--- a/dom/media/fmp4/PlatformDecoderModule.h
+++ b/dom/media/fmp4/PlatformDecoderModule.h
@@ -132,16 +132,20 @@ public:
   virtual bool SupportsAudioMimeType(const char* aMimeType);
   virtual bool SupportsVideoMimeType(const char* aMimeType);
 
   // Indicates if the video decoder requires AVCC format.
   virtual bool DecoderNeedsAVCC(const mp4_demuxer::VideoDecoderConfig& aConfig);
 
   virtual void DisableHardwareAcceleration() {}
 
+  virtual bool SupportsSharedDecoders(const mp4_demuxer::VideoDecoderConfig& aConfig) const {
+    return true;
+  }
+
 protected:
   PlatformDecoderModule() {}
   virtual ~PlatformDecoderModule() {}
   // Caches pref media.fragmented-mp4.use-blank-decoder
   static bool sUseBlankDecoder;
   static bool sFFmpegDecoderEnabled;
   static bool sGonkDecoderEnabled;
   static bool sAndroidMCDecoderPreferred;
--- a/dom/media/fmp4/wmf/WMFDecoderModule.cpp
+++ b/dom/media/fmp4/wmf/WMFDecoderModule.cpp
@@ -9,16 +9,18 @@
 #include "WMFDecoder.h"
 #include "WMFVideoMFTManager.h"
 #include "WMFAudioMFTManager.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/DebugOnly.h"
 #include "WMFMediaDataDecoder.h"
 #include "nsIWindowsRegKey.h"
 #include "nsComponentManagerUtils.h"
+#include "nsIGfxInfo.h"
+#include "GfxDriverInfo.h"
 
 namespace mozilla {
 
 bool WMFDecoderModule::sIsWMFEnabled = false;
 bool WMFDecoderModule::sDXVAEnabled = false;
 
 WMFDecoderModule::WMFDecoderModule()
 {
@@ -70,17 +72,17 @@ WMFDecoderModule::CreateVideoDecoder(con
                                      layers::ImageContainer* aImageContainer,
                                      FlushableMediaTaskQueue* aVideoTaskQueue,
                                      MediaDataDecoderCallback* aCallback)
 {
   nsRefPtr<MediaDataDecoder> decoder =
     new WMFMediaDataDecoder(new WMFVideoMFTManager(aConfig,
                                                    aLayersBackend,
                                                    aImageContainer,
-                                                   sDXVAEnabled),
+                                                   sDXVAEnabled && ShouldUseDXVA(aConfig)),
                             aVideoTaskQueue,
                             aCallback);
   return decoder.forget();
 }
 
 already_AddRefed<MediaDataDecoder>
 WMFDecoderModule::CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
                                      FlushableMediaTaskQueue* aAudioTaskQueue,
@@ -89,16 +91,44 @@ WMFDecoderModule::CreateAudioDecoder(con
   nsRefPtr<MediaDataDecoder> decoder =
     new WMFMediaDataDecoder(new WMFAudioMFTManager(aConfig),
                             aAudioTaskQueue,
                             aCallback);
   return decoder.forget();
 }
 
 bool
+WMFDecoderModule::ShouldUseDXVA(const mp4_demuxer::VideoDecoderConfig& aConfig) const
+{
+  static bool isAMD = false;
+  static bool initialized = false;
+  if (!initialized) {
+    nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
+    nsAutoString vendor;
+    gfxInfo->GetAdapterVendorID(vendor);
+    isAMD = vendor.Equals(widget::GfxDriverInfo::GetDeviceVendor(widget::VendorAMD), nsCaseInsensitiveStringComparator()) ||
+            vendor.Equals(widget::GfxDriverInfo::GetDeviceVendor(widget::VendorATI), nsCaseInsensitiveStringComparator());
+    initialized = true;
+  }
+  if (!isAMD) {
+    return true;
+  }
+  // Don't use DXVA for 4k videos or above, since it seems to perform poorly.
+  return aConfig.display_height <= 1920 && aConfig.display_height <= 1200;
+}
+
+bool
+WMFDecoderModule::SupportsSharedDecoders(const mp4_demuxer::VideoDecoderConfig& 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);
+}
+
+bool
 WMFDecoderModule::SupportsVideoMimeType(const char* aMimeType)
 {
   return !strcmp(aMimeType, "video/mp4") ||
          !strcmp(aMimeType, "video/avc") ||
          !strcmp(aMimeType, "video/webm; codecs=vp8") ||
          !strcmp(aMimeType, "video/webm; codecs=vp9");
 }
 
--- a/dom/media/fmp4/wmf/WMFDecoderModule.h
+++ b/dom/media/fmp4/wmf/WMFDecoderModule.h
@@ -37,25 +37,29 @@ public:
   bool SupportsVideoMimeType(const char* aMimeType) MOZ_OVERRIDE;
   bool SupportsAudioMimeType(const char* aMimeType) MOZ_OVERRIDE;
 
   virtual void DisableHardwareAcceleration() MOZ_OVERRIDE
   {
     sDXVAEnabled = false;
   }
 
+  virtual bool SupportsSharedDecoders(const mp4_demuxer::VideoDecoderConfig& aConfig) const MOZ_OVERRIDE;
+
   // Accessors that report whether we have the required MFTs available
   // on the system to play various codecs. Windows Vista doesn't have the
   // H.264/AAC decoders if the "Platform Update Supplement for Windows Vista"
   // is not installed.
   static bool HasAAC();
   static bool HasH264();
 
   // Called on main thread.
   static void Init();
 private:
+  bool ShouldUseDXVA(const mp4_demuxer::VideoDecoderConfig& aConfig) const;
+
   static bool sIsWMFEnabled;
   static bool sDXVAEnabled;
 };
 
 } // namespace mozilla
 
 #endif