Bug 1457499 - Part 3: Query decoded frame size instead of calculating it. r=bryce, a=RyanVM
authorJean-Yves Avenard <jyavenard@mozilla.com>
Wed, 16 May 2018 11:09:20 +0200
changeset 473384 6b7ce6f146aba5250999edf11029ea63cfce4d57
parent 473383 d6500ec9e0e84c531d59ab51f2f201d2988f541b
child 473385 6e890ccae3ab700b89a64e3799eff1d45b6a413f
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbryce, RyanVM
bugs1457499
milestone61.0
Bug 1457499 - Part 3: Query decoded frame size instead of calculating it. r=bryce, a=RyanVM Under most cases, the frame decoded height is just the displayed height rounded to the next 16 row aligned value. However, this doesn't appear to always be the case. So we query the WMF framework for the decoded frame size. We continue to use the displayed sizes as found in the SPS to ensure proper display of non 1:1 aspect ratio. Adding diagnostic assertion to find potential regressions, we will address those as they come. MozReview-Commit-ID: L8VowEw6L9F
dom/media/platforms/wmf/WMFVideoMFTManager.cpp
dom/media/platforms/wmf/WMFVideoMFTManager.h
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
@@ -166,16 +166,17 @@ GetCompositorBackendType(layers::KnowsCo
 WMFVideoMFTManager::WMFVideoMFTManager(
   const VideoInfo& aConfig,
   layers::KnowsCompositor* aKnowsCompositor,
   layers::ImageContainer* aImageContainer,
   float aFramerate,
   bool aDXVAEnabled)
   : mVideoInfo(aConfig)
   , mImageSize(aConfig.mImage)
+  , mDecodedImageSize(aConfig.mImage)
   , mVideoStride(0)
   , mYUVColorSpace(YUVColorSpace::BT601)
   , mImageContainer(aImageContainer)
   , mKnowsCompositor(aKnowsCompositor)
   , mDXVAEnabled(aDXVAEnabled)
   , mAMDVP9InUse(false)
   , mFramerate(aFramerate)
   // mVideoStride, mVideoWidth, mVideoHeight, mUseHwAccel are initialized in
@@ -188,16 +189,23 @@ WMFVideoMFTManager::WMFVideoMFTManager(
     mStreamType = H264;
   } else if (VPXDecoder::IsVP8(aConfig.mMimeType)) {
     mStreamType = VP8;
   } else if (VPXDecoder::IsVP9(aConfig.mMimeType)) {
     mStreamType = VP9;
   } else {
     mStreamType = Unknown;
   }
+
+  // The V and U planes are stored 16-row-aligned, so we need to add padding
+  // to the row heights to ensure the Y'CbCr planes are referenced properly.
+  // This value is only used with software decoder.
+  if (mDecodedImageSize.height % 16 != 0) {
+    mDecodedImageSize.height += 16 - (mDecodedImageSize.height % 16);
+  }
 }
 
 WMFVideoMFTManager::~WMFVideoMFTManager()
 {
   MOZ_COUNT_DTOR(WMFVideoMFTManager);
   // Ensure DXVA/D3D9 related objects are released on the main thread.
   if (mDXVA2Manager) {
     DeleteOnMainThread(mDXVA2Manager);
@@ -969,24 +977,20 @@ WMFVideoMFTManager::CreateBasicVideoFram
   // Y (Y') plane
   b.mPlanes[0].mData = data;
   b.mPlanes[0].mStride = stride;
   b.mPlanes[0].mHeight = videoHeight;
   b.mPlanes[0].mWidth = videoWidth;
   b.mPlanes[0].mOffset = 0;
   b.mPlanes[0].mSkip = 0;
 
-  // The V and U planes are stored 16-row-aligned, so we need to add padding
-  // to the row heights to ensure the Y'CbCr planes are referenced properly.
-  uint32_t padding = 0;
-  if (videoHeight % 16 != 0) {
-    padding = 16 - (videoHeight % 16);
-  }
-  uint32_t y_size = stride * (videoHeight + padding);
-  uint32_t v_size = stride * (videoHeight + padding) / 4;
+  MOZ_DIAGNOSTIC_ASSERT(mDecodedImageSize.height % 16 == 0,
+                        "decoded height must be 16 bytes aligned");
+  uint32_t y_size = stride * mDecodedImageSize.height;
+  uint32_t v_size = stride * mDecodedImageSize.height / 4;
   uint32_t halfStride = (stride + 1) / 2;
   uint32_t halfHeight = (videoHeight + 1) / 2;
   uint32_t halfWidth = (videoWidth + 1) / 2;
 
   // U plane (Cb)
   b.mPlanes[1].mData = data + y_size + v_size;
   b.mPlanes[1].mStride = halfStride;
   b.mPlanes[1].mHeight = halfHeight;
@@ -1134,16 +1138,23 @@ WMFVideoMFTManager::Output(int64_t aStre
         // The stride may have changed, recheck for it.
         RefPtr<IMFMediaType> outputType;
         hr = mDecoder->GetOutputMediaType(outputType);
         NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
         mYUVColorSpace = GetYUVColorSpace(outputType);
         hr = GetDefaultStride(outputType, mVideoInfo.ImageRect().width,
                               &mVideoStride);
         NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
+
+        UINT32 width = 0, height = 0;
+        hr = MFGetAttributeSize(outputType, MF_MT_FRAME_SIZE, &width, &height);
+        NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
+        NS_ENSURE_TRUE(width <= MAX_VIDEO_WIDTH, E_FAIL);
+        NS_ENSURE_TRUE(height <= MAX_VIDEO_HEIGHT, E_FAIL);
+        mDecodedImageSize = gfx::IntSize(width, height);
       }
       // Catch infinite loops, but some decoders perform at least 2 stream
       // changes on consecutive calls, so be permissive.
       // 100 is arbitrarily > 2.
       NS_ENSURE_TRUE(typeChangeCount < 100, MF_E_TRANSFORM_STREAM_CHANGE);
       // Loop back and try decoding again...
       ++typeChangeCount;
       continue;
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.h
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.h
@@ -83,16 +83,17 @@ private:
 
   bool CanUseDXVA(IMFMediaType* aType, float aFramerate);
 
   already_AddRefed<MFTDecoder> LoadAMDVP9Decoder();
 
   // Video frame geometry.
   const VideoInfo mVideoInfo;
   const gfx::IntSize mImageSize;
+  gfx::IntSize mDecodedImageSize;
   uint32_t mVideoStride;
   YUVColorSpace mYUVColorSpace;
 
   RefPtr<layers::ImageContainer> mImageContainer;
   RefPtr<layers::KnowsCompositor> mKnowsCompositor;
   nsAutoPtr<DXVA2Manager> mDXVA2Manager;
 
   media::TimeUnit mLastDuration;