Bug 872375 - Specify picture region in D3D9SurfaceImage. r=padenot, a=lsblakk
authorChris Pearce <cpearce@mozilla.com>
Mon, 20 May 2013 13:14:13 +0800
changeset 142751 a334c5088d0d566955b680a9aedfa9e68b45cbab
parent 142750 61f8d384403dd6df50d5cf78d81297ed4f88003c
child 142752 37d012e97d79a6d62c2e8186e006b2818fb18b58
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot, lsblakk
bugs872375
milestone23.0a2
Bug 872375 - Specify picture region in D3D9SurfaceImage. r=padenot, a=lsblakk
content/media/wmf/DXVA2Manager.cpp
content/media/wmf/DXVA2Manager.h
content/media/wmf/WMFReader.cpp
gfx/layers/D3D9SurfaceImage.cpp
gfx/layers/D3D9SurfaceImage.h
--- a/content/media/wmf/DXVA2Manager.cpp
+++ b/content/media/wmf/DXVA2Manager.cpp
@@ -21,18 +21,20 @@ class D3D9DXVA2Manager : public DXVA2Man
 public:
   D3D9DXVA2Manager();
   virtual ~D3D9DXVA2Manager();
 
   HRESULT Init();
 
   IUnknown* GetDXVADeviceManager() MOZ_OVERRIDE;
 
+  // Copies a region (aRegion) of the video frame stored in aVideoSample
+  // into an image which is returned by aOutImage.
   HRESULT CopyToImage(IMFSample* aVideoSample,
-                      const nsIntSize& aSize,
+                      const nsIntRect& aRegion,
                       ImageContainer* aContainer,
                       Image** aOutImage) MOZ_OVERRIDE;
 
 private:
   nsRefPtr<IDirect3D9Ex> mD3D9;
   nsRefPtr<IDirect3DDevice9Ex> mDevice;
   nsRefPtr<IDirect3DDeviceManager9> mDeviceManager;
   UINT32 mResetToken;
@@ -132,17 +134,17 @@ D3D9DXVA2Manager::Init()
   mDevice = device;
   mDeviceManager = deviceManager;
 
   return S_OK;
 }
 
 HRESULT
 D3D9DXVA2Manager::CopyToImage(IMFSample* aSample,
-                              const nsIntSize& aSize,
+                              const nsIntRect& aRegion,
                               ImageContainer* aImageContainer,
                               Image** aOutImage)
 {
   nsRefPtr<IMFMediaBuffer> buffer;
   HRESULT hr = aSample->GetBufferByIndex(0, getter_AddRefs(buffer));
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
   nsRefPtr<IDirect3DSurface9> surface;
@@ -154,17 +156,17 @@ D3D9DXVA2Manager::CopyToImage(IMFSample*
 
   ImageFormat format = D3D9_RGB32_TEXTURE;
   nsRefPtr<Image> image = aImageContainer->CreateImage(&format, 1);
   NS_ENSURE_TRUE(image, E_FAIL);
   NS_ASSERTION(image->GetFormat() == D3D9_RGB32_TEXTURE,
                "Wrong format?");
 
   D3D9SurfaceImage* videoImage = static_cast<D3D9SurfaceImage*>(image.get());
-  hr = videoImage->SetData(D3D9SurfaceImage::Data(surface, aSize));
+  hr = videoImage->SetData(D3D9SurfaceImage::Data(surface, aRegion));
 
   image.forget(aOutImage);
 
   return S_OK;
 }
 
 /* static */
 DXVA2Manager*
--- a/content/media/wmf/DXVA2Manager.h
+++ b/content/media/wmf/DXVA2Manager.h
@@ -4,16 +4,17 @@
  * 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/. */
 #if !defined(DXVA2Manager_h_)
 #define DXVA2Manager_h_
 
 #include "WMF.h"
 #include "nsAutoPtr.h"
 #include "mozilla/Mutex.h"
+#include "nsRect.h"
 
 class nsIntSize;
 
 namespace mozilla {
 
 namespace layers {
 class Image;
 class ImageContainer;
@@ -30,17 +31,17 @@ public:
   // Returns a pointer to the D3D device manager responsible for managing the
   // device we're using for hardware accelerated video decoding. If we're using
   // D3D9, this is an IDirect3DDeviceManager9. It is safe to call this on any
   // thread.
   virtual IUnknown* GetDXVADeviceManager() = 0;
 
   // Creates an Image for the video frame stored in aVideoSample.
   virtual HRESULT CopyToImage(IMFSample* aVideoSample,
-                              const nsIntSize& aSize,
+                              const nsIntRect& aRegion,
                               layers::ImageContainer* aContainer,
                               layers::Image** aOutImage) = 0;
 
   virtual ~DXVA2Manager();
 
 protected:
   Mutex mLock;
   DXVA2Manager();
--- a/content/media/wmf/WMFReader.cpp
+++ b/content/media/wmf/WMFReader.cpp
@@ -786,17 +786,17 @@ WMFReader::CreateD3DVideoFrame(IMFSample
   NS_ENSURE_TRUE(mDXVA2Manager, E_ABORT);
   NS_ENSURE_TRUE(mUseHwAccel, E_ABORT);
 
   *aOutVideoData = nullptr;
   HRESULT hr;
 
   nsRefPtr<Image> image;
   hr = mDXVA2Manager->CopyToImage(aSample,
-                                  nsIntSize(mPictureRegion.width, mPictureRegion.height),
+                                  mPictureRegion,
                                   mDecoder->GetImageContainer(),
                                   getter_AddRefs(image));
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
   NS_ENSURE_TRUE(image, E_FAIL);
 
   VideoData *v = VideoData::CreateFromImage(mInfo,
                                             mDecoder->GetImageContainer(),
                                             aOffsetBytes,
--- a/gfx/layers/D3D9SurfaceImage.cpp
+++ b/gfx/layers/D3D9SurfaceImage.cpp
@@ -32,51 +32,53 @@ D3D9SurfaceImage::SetData(const Data& aD
                                          D3DDEVTYPE_HAL,
                                          desc.Format,
                                          D3DFMT_X8R8G8B8);
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
   // DXVA surfaces aren't created sharable, so we need to copy the surface
   // to a sharable texture to that it's accessible to the layer manager's
   // device.
+  const nsIntRect& region = aData.mRegion;
   RefPtr<IDirect3DTexture9> texture;
   HANDLE shareHandle = NULL;
-  hr = device->CreateTexture(desc.Width,
-                             desc.Height,
+  hr = device->CreateTexture(region.width,
+                             region.height,
                              1,
                              D3DUSAGE_RENDERTARGET,
                              D3DFMT_X8R8G8B8,
                              D3DPOOL_DEFAULT,
                              byRef(texture),
                              &shareHandle);
   NS_ENSURE_TRUE(SUCCEEDED(hr) && shareHandle, hr);
 
   // Copy the image onto the texture, preforming YUV -> RGB conversion if necessary.
   RefPtr<IDirect3DSurface9> textureSurface;
   hr = texture->GetSurfaceLevel(0, byRef(textureSurface));
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
   // Stash the surface description for later use.
   textureSurface->GetDesc(&mDesc);
 
-  hr = device->StretchRect(surface, NULL, textureSurface, NULL, D3DTEXF_NONE);
+  RECT src = { region.x, region.y, region.x+region.width, region.y+region.height };
+  hr = device->StretchRect(surface, &src, textureSurface, NULL, D3DTEXF_NONE);
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
   // Flush the draw command now, so that by the time we come to draw this
   // image, we're less likely to need to wait for the draw operation to
   // complete.
   RefPtr<IDirect3DQuery9> query;
   hr = device->CreateQuery(D3DQUERYTYPE_EVENT, byRef(query));
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
   hr = query->Issue(D3DISSUE_END);
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
   mTexture = texture;
   mShareHandle = shareHandle;
-  mSize = gfxIntSize(aData.mSize.width, aData.mSize.height);
+  mSize = gfxIntSize(region.width, region.height);
   mQuery = query;
 
   return S_OK;
 }
 
 void
 D3D9SurfaceImage::EnsureSynchronized()
 {
--- a/gfx/layers/D3D9SurfaceImage.h
+++ b/gfx/layers/D3D9SurfaceImage.h
@@ -17,20 +17,20 @@ namespace layers {
 // Image class that wraps a IDirect3DSurface9. This class copies the image
 // passed into SetData(), so that it can be accessed from other D3D devices.
 // This class also manages the synchronization of the copy, to ensure the
 // resource is ready to use.
 class D3D9SurfaceImage : public Image {
 public:
 
   struct Data {
-    Data(IDirect3DSurface9* aSurface, const nsIntSize& aSize)
-      : mSurface(aSurface), mSize(aSize) {}
+    Data(IDirect3DSurface9* aSurface, const nsIntRect& aRegion)
+      : mSurface(aSurface), mRegion(aRegion) {}
     RefPtr<IDirect3DSurface9> mSurface;
-    nsIntSize mSize;
+    nsIntRect mRegion;
   };
 
   D3D9SurfaceImage() : Image(NULL, D3D9_RGB32_TEXTURE), mSize(0, 0) {}
   virtual ~D3D9SurfaceImage() {}
 
   // Copies the surface into a sharable texture's surface, and initializes
   // the image.
   HRESULT SetData(const Data& aData);