Bug 1495025 - P3. Store original IMFMediaType's subtype in D3D11SharedHandleImage. r=cpearce

This allows more easily the creation of the MFT required to convert to a RGBA32 image when doing a readback.

Depends on D7295

Differential Revision: https://phabricator.services.mozilla.com/D7296
This commit is contained in:
Jean-Yves Avenard 2018-10-08 13:26:00 +02:00
parent dd9e74b3bb
commit e0e52e125f
4 changed files with 39 additions and 49 deletions

View File

@ -620,8 +620,9 @@ public:
const gfx::IntRect& aRegion,
Image** aOutImage) override;
virtual HRESULT CopyToBGRATexture(ID3D11Texture2D *aInTexture,
ID3D11Texture2D** aOutTexture);
HRESULT CopyToBGRATexture(ID3D11Texture2D* aInTexture,
const GUID& aSubType,
ID3D11Texture2D** aOutTexture) override;
HRESULT ConfigureForSize(IMFMediaType* aInputType,
uint32_t aWidth,
@ -655,6 +656,7 @@ private:
uint32_t mHeight = 0;
UINT mDeviceManagerToken = 0;
RefPtr<IMFMediaType> mInputType;
GUID mInputSubType;
};
bool
@ -921,8 +923,8 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample,
NS_ENSURE_TRUE(aOutImage, E_POINTER);
MOZ_ASSERT(mTextureClientAllocator);
RefPtr<D3D11ShareHandleImage> image =
new D3D11ShareHandleImage(gfx::IntSize(mWidth, mHeight), aRegion);
RefPtr<D3D11ShareHandleImage> image = new D3D11ShareHandleImage(
gfx::IntSize(mWidth, mHeight), aRegion, mInputSubType);
// Retrieve the DXGI_FORMAT for the current video sample.
RefPtr<IMFMediaBuffer> buffer;
@ -937,20 +939,21 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample,
hr = dxgiBuf->GetResource(__uuidof(ID3D11Texture2D), getter_AddRefs(tex));
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
D3D11_TEXTURE2D_DESC desc;
tex->GetDesc(&desc);
D3D11_TEXTURE2D_DESC inDesc;
tex->GetDesc(&inDesc);
bool ok = image->AllocateTexture(
mTextureClientAllocator, mDevice, desc.Format == DXGI_FORMAT_NV12);
bool ok = image->AllocateTexture(mTextureClientAllocator, mDevice);
NS_ENSURE_TRUE(ok, E_FAIL);
RefPtr<TextureClient> client =
image->GetTextureClient(ImageBridgeChild::GetSingleton().get());
NS_ENSURE_TRUE(client, E_FAIL);
RefPtr<IDXGIKeyedMutex> mutex;
RefPtr<ID3D11Texture2D> texture = image->GetTexture();
D3D11_TEXTURE2D_DESC outDesc;
texture->GetDesc(&outDesc);
RefPtr<IDXGIKeyedMutex> mutex;
texture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mutex));
{
@ -963,7 +966,7 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample,
NS_ENSURE_TRUE(mSyncObject, E_FAIL);
}
if (client && client->GetFormat() == SurfaceFormat::NV12) {
if (outDesc.Format == inDesc.Format) {
// Our video frame is stored in a non-sharable ID3D11Texture2D. We need
// to create a copy of that frame as a sharable resource, save its share
// handle, and put that handle into the rendering pipeline.
@ -1003,23 +1006,9 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample,
return S_OK;
}
const GUID& TextureFormatToSubType(DXGI_FORMAT aFormat)
{
switch (aFormat) {
case DXGI_FORMAT_NV12:
return MFVideoFormat_NV12;
case DXGI_FORMAT_P010:
return MFVideoFormat_P010;
case DXGI_FORMAT_P016:
return MFVideoFormat_P016;
default:
// TextureFormat not handled.
return MFVideoFormat_NV12;
}
}
HRESULT
D3D11DXVA2Manager::CopyToBGRATexture(ID3D11Texture2D *aInTexture,
D3D11DXVA2Manager::CopyToBGRATexture(ID3D11Texture2D* aInTexture,
const GUID& aSubType,
ID3D11Texture2D** aOutTexture)
{
NS_ENSURE_TRUE(aInTexture, E_POINTER);
@ -1041,7 +1030,7 @@ D3D11DXVA2Manager::CopyToBGRATexture(ID3D11Texture2D *aInTexture,
hr = inputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
hr = inputType->SetGUID(MF_MT_SUBTYPE, TextureFormatToSubType(desc.Format));
hr = inputType->SetGUID(MF_MT_SUBTYPE, aSubType);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
hr =
@ -1120,17 +1109,11 @@ D3D11DXVA2Manager::ConfigureForSize(IMFMediaType* aInputType,
uint32_t aWidth,
uint32_t aHeight)
{
GUID inputSubType = { 0 };
HRESULT hr = aInputType->GetGUID(MF_MT_SUBTYPE, &inputSubType);
GUID subType = { 0 };
HRESULT hr = aInputType->GetGUID(MF_MT_SUBTYPE, &subType);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
GUID subType = { 0 };
if (mInputType) {
hr = mInputType->GetGUID(MF_MT_SUBTYPE, &subType);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
}
if (inputSubType == subType && aWidth == mWidth && aHeight == mHeight) {
if (subType == mInputSubType && aWidth == mWidth && aHeight == mHeight) {
// If the media type hasn't changed, don't reconfigure.
return S_OK;
}
@ -1186,6 +1169,7 @@ D3D11DXVA2Manager::ConfigureForSize(IMFMediaType* aInputType,
mWidth = aWidth;
mHeight = aHeight;
mInputType = inputType;
mInputSubType = subType;
return S_OK;
}

View File

@ -46,7 +46,8 @@ public:
const gfx::IntRect& aRegion,
layers::Image** aOutImage) = 0;
virtual HRESULT CopyToBGRATexture(ID3D11Texture2D *aInTexture,
virtual HRESULT CopyToBGRATexture(ID3D11Texture2D* aInTexture,
const GUID& aSubType,
ID3D11Texture2D** aOutTexture)
{
// Not implemented!

View File

@ -24,20 +24,23 @@ namespace layers {
using namespace gfx;
D3D11ShareHandleImage::D3D11ShareHandleImage(const gfx::IntSize& aSize,
const gfx::IntRect& aRect)
: Image(nullptr, ImageFormat::D3D11_SHARE_HANDLE_TEXTURE),
mSize(aSize),
mPictureRect(aRect)
const gfx::IntRect& aRect,
const GUID& aSourceFormat)
: Image(nullptr, ImageFormat::D3D11_SHARE_HANDLE_TEXTURE)
, mSize(aSize)
, mPictureRect(aRect)
, mSourceFormat(aSourceFormat)
{
}
bool
D3D11ShareHandleImage::AllocateTexture(D3D11RecycleAllocator* aAllocator,
ID3D11Device* aDevice,
bool aPreferNV12)
ID3D11Device* aDevice)
{
if (aAllocator) {
if (aPreferNV12 && gfxPrefs::PDMWMFUseNV12Format() &&
if (mSourceFormat == MFVideoFormat_NV12 &&
gfxPrefs::PDMWMFUseNV12Format() &&
gfx::DeviceManagerDx::Get()->CanUseNV12()) {
mTextureClient =
aAllocator->CreateOrRecycleClient(gfx::SurfaceFormat::NV12, mSize);
@ -102,10 +105,11 @@ D3D11ShareHandleImage::GetAsSourceSurface()
RefPtr<ID3D11Texture2D> outTexture;
hr = manager->CopyToBGRATexture(texture, getter_AddRefs(outTexture));
hr = manager->CopyToBGRATexture(
texture, mSourceFormat, getter_AddRefs(outTexture));
if (FAILED(hr)) {
gfxWarning() << "Failed to copy NV12 to BGRA texture.";
gfxWarning() << "Failed to copy to BGRA texture.";
return nullptr;
}

View File

@ -52,12 +52,12 @@ protected:
class D3D11ShareHandleImage final : public Image {
public:
D3D11ShareHandleImage(const gfx::IntSize& aSize,
const gfx::IntRect& aRect);
const gfx::IntRect& aRect,
const GUID& aSourceFormat);
virtual ~D3D11ShareHandleImage() {}
bool AllocateTexture(D3D11RecycleAllocator* aAllocator,
ID3D11Device* aDevice,
bool aPreferNV12);
ID3D11Device* aDevice);
gfx::IntSize GetSize() const override;
already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
@ -69,6 +69,7 @@ public:
private:
gfx::IntSize mSize;
gfx::IntRect mPictureRect;
const GUID mSourceFormat;
RefPtr<TextureClient> mTextureClient;
RefPtr<ID3D11Texture2D> mTexture;
};