Bug 872375 - Specify picture region in D3D9SurfaceImage. r=padenot
authorChris Pearce <cpearce@mozilla.com>
Mon, 20 May 2013 13:14:13 +0800
changeset 143876 2ba61101fe9431420046bfe169e5bc51cfe0d715
parent 143875 25a1e66c0f1dcf877dd5aa3ec8474700ea5ccc82
child 143877 be1d72a1f2286bc53f50bdd031f99847eed331b5
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs872375
milestone24.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 872375 - Specify picture region in D3D9SurfaceImage. r=padenot
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);