Bug 1397307 - P8. Pass averaged video frame rate to constructor. r?mattwoodrow draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 12 Sep 2017 17:55:03 +0200
changeset 665098 54e86e966ba89fa160df990557016538fe4bc182
parent 665097 61e18a25dbcbcf607b9412408784765bc3b85bc5
child 665099 fe47ba53148858f2e4d8dec0dbb534a65d40a306
push id79919
push userbmo:jyavenard@mozilla.com
push dateThu, 14 Sep 2017 22:16:27 +0000
reviewersmattwoodrow
bugs1397307
milestone57.0a1
Bug 1397307 - P8. Pass averaged video frame rate to constructor. r?mattwoodrow MozReview-Commit-ID: FMFz3RdFsHA
dom/media/platforms/wmf/WMFDecoderModule.cpp
dom/media/platforms/wmf/WMFVideoMFTManager.cpp
dom/media/platforms/wmf/WMFVideoMFTManager.h
--- a/dom/media/platforms/wmf/WMFDecoderModule.cpp
+++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp
@@ -103,16 +103,17 @@ WMFDecoderModule::CreateVideoDecoder(con
     // when low latency is required.
     return nullptr;
   }
 
   nsAutoPtr<WMFVideoMFTManager> manager(
     new WMFVideoMFTManager(aParams.VideoConfig(),
                            aParams.mKnowsCompositor,
                            aParams.mImageContainer,
+                           aParams.mRate.mValue,
                            sDXVAEnabled));
 
   MediaResult result = manager->Init();
   if (NS_FAILED(result)) {
     if (aParams.mError) {
       *aParams.mError = result;
     }
     return nullptr;
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
@@ -159,27 +159,29 @@ GetCompositorBackendType(layers::KnowsCo
 {
   if (aKnowsCompositor) {
     return aKnowsCompositor->GetCompositorBackendType();
   }
   return LayersBackend::LAYERS_NONE;
 }
 
 WMFVideoMFTManager::WMFVideoMFTManager(
-                            const VideoInfo& aConfig,
-                            layers::KnowsCompositor* aKnowsCompositor,
-                            layers::ImageContainer* aImageContainer,
-                            bool aDXVAEnabled)
+  const VideoInfo& aConfig,
+  layers::KnowsCompositor* aKnowsCompositor,
+  layers::ImageContainer* aImageContainer,
+  float aFramerate,
+  bool aDXVAEnabled)
   : mVideoInfo(aConfig)
   , mImageSize(aConfig.mImage)
   , mVideoStride(0)
   , mImageContainer(aImageContainer)
   , mDXVAEnabled(aDXVAEnabled)
   , mKnowsCompositor(aKnowsCompositor)
   , mAMDVP9InUse(false)
+  , mFramerate(aFramerate)
   // mVideoStride, mVideoWidth, mVideoHeight, mUseHwAccel are initialized in
   // Init().
 {
   MOZ_COUNT_CTOR(WMFVideoMFTManager);
 
   // Need additional checks/params to check vp8/vp9
   if (MP4Decoder::IsH264(aConfig.mMimeType)) {
     mStreamType = H264;
@@ -731,17 +733,17 @@ WMFVideoMFTManager::InitInternal()
                              RESULT_DETAIL("Fail to set the decoder media types.")));
 
   RefPtr<IMFMediaType> outputType;
   hr = mDecoder->GetOutputMediaType(outputType);
   NS_ENSURE_TRUE(SUCCEEDED(hr),
                  MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
                             RESULT_DETAIL("Fail to get the output media type.")));
 
-  if (mUseHwAccel && !CanUseDXVA(outputType)) {
+  if (mUseHwAccel && !CanUseDXVA(outputType, mFramerate)) {
     mDXVAEnabled = false;
     // DXVA initialization with current decoder actually failed,
     // re-do initialization.
     return InitInternal();
   }
 
   LOG("Video Decoder initialized, Using DXVA: %s",
       (mUseHwAccel ? "Yes" : "No"));
@@ -854,17 +856,18 @@ WMFVideoMFTManager::Input(MediaRawData* 
   mLastDuration = aSample->mDuration;
   mLastTime = aSample->mTime;
   mSamplesCount++;
 
   // Forward sample data to the decoder.
   return mDecoder->Input(inputSample);
 }
 
-class SupportsConfigEvent : public Runnable {
+class SupportsConfigEvent : public Runnable
+{
 public:
   SupportsConfigEvent(DXVA2Manager* aDXVA2Manager,
                       IMFMediaType* aMediaType,
                       float aFramerate)
     : Runnable("SupportsConfigEvent")
     , mDXVA2Manager(aDXVA2Manager)
     , mMediaType(aMediaType)
     , mFramerate(aFramerate)
@@ -875,17 +878,17 @@ public:
   NS_IMETHOD Run()
   {
     MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
     mSupportsConfig = mDXVA2Manager->SupportsConfig(mMediaType, mFramerate);
     return NS_OK;
   }
   DXVA2Manager* mDXVA2Manager;
   IMFMediaType* mMediaType;
-  float mFramerate;
+  const float mFramerate;
   bool mSupportsConfig;
 };
 
 // The MFTransform we use for decoding h264 video will silently fall
 // back to software decoding (even if we've negotiated DXVA) if the GPU
 // doesn't support decoding the given resolution. It will then upload
 // the software decoded frames into d3d textures to preserve behaviour.
 //
@@ -895,32 +898,28 @@ public:
 //
 // This code tests if the given resolution can be supported directly on the GPU,
 // and makes sure we only ask the MFT for DXVA if it can be supported properly.
 //
 // Ideally we'd know the framerate during initialization and would also ensure
 // that new decoders are created if the resolution changes. Then we could move
 // this check into Init and consolidate the main thread blocking code.
 bool
-WMFVideoMFTManager::CanUseDXVA(IMFMediaType* aType)
+WMFVideoMFTManager::CanUseDXVA(IMFMediaType* aType, float aFramerate)
 {
   MOZ_ASSERT(mDXVA2Manager);
   // SupportsConfig only checks for valid h264 decoders currently.
   if (mStreamType != H264) {
     return true;
   }
 
-  // Assume the current samples duration is representative for the
-  // entire video.
-  float framerate = 1000000.0 / mLastDuration.ToMicroseconds();
-
   // The supports config check must be done on the main thread since we have
   // a crash guard protecting it.
   RefPtr<SupportsConfigEvent> event =
-    new SupportsConfigEvent(mDXVA2Manager, aType, framerate);
+    new SupportsConfigEvent(mDXVA2Manager, aType, aFramerate);
 
   if (NS_IsMainThread()) {
     event->Run();
   } else {
     // This logic needs to run on the main thread
     mozilla::SyncRunnable::DispatchToThread(
       SystemGroup::EventTargetFor(mozilla::TaskCategory::Other), event);
   }
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.h
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.h
@@ -21,16 +21,17 @@ namespace mozilla {
 class DXVA2Manager;
 
 class WMFVideoMFTManager : public MFTManager
 {
 public:
   WMFVideoMFTManager(const VideoInfo& aConfig,
                      layers::KnowsCompositor* aKnowsCompositor,
                      layers::ImageContainer* aImageContainer,
+                     float aFramerate,
                      bool aDXVAEnabled);
   ~WMFVideoMFTManager();
 
   MediaResult Init();
 
   HRESULT Input(MediaRawData* aSample) override;
 
   HRESULT Output(int64_t aStreamOffset, RefPtr<MediaData>& aOutput) override;
@@ -75,17 +76,17 @@ private:
                                 VideoData** aOutVideoData);
 
   HRESULT CreateD3DVideoFrame(IMFSample* aSample,
                               int64_t aStreamOffset,
                               VideoData** aOutVideoData);
 
   HRESULT SetDecoderMediaTypes();
 
-  bool CanUseDXVA(IMFMediaType* aType);
+  bool CanUseDXVA(IMFMediaType* aType, float aFramerate);
 
   already_AddRefed<MFTDecoder> LoadAMDVP9Decoder();
 
   // Video frame geometry.
   const VideoInfo mVideoInfo;
   const gfx::IntSize mImageSize;
   uint32_t mVideoStride;
 
@@ -118,13 +119,14 @@ private:
 
   uint32_t mNullOutputCount = 0;
   bool mGotValidOutputAfterNullOutput = false;
   bool mGotExcessiveNullOutput = false;
   bool mIsValid = true;
   bool mIMFUsable = false;
   bool mCheckForAMDDecoder = true;
   Atomic<bool> mAMDVP9InUse;
+  const float mFramerate;
 };
 
 } // namespace mozilla
 
 #endif // WMFVideoMFTManager_h_