CLSID_D2D1ChromaKey issues

1

I try to use DirectX ChromaKey effect, but my function stucks on some step.
What I do:

  1. Create ID2D1Factory1
  2. Create ID3D11Device and ID3D11DeviceContext
  3. Obtain DXGIResource from received texture
  4. Obtain shared handle from DXGIResource
  5. Open DXGIResource as new ID3D11Texture2D using ID3D11Device
  6. Obtain D3D11_TEXTURE2D_DESC of new ID3D11Texture2D
  7. Create new ID3D11Texture2D using input ID3D11Texture2D and D3D11_TEXTURE2D_DESC
  8. Copy resource from obtained ID3D11Texture2D to created ID3D11Texture2D
  9. Obtain IDXGISurface from created ID3D11Texture2D
  10. Define D2D1_SIZE_U, D2D1_PIXEL_FORMAT, D2D1_BITMAP_PROPERTIES
  11. Obtain desktop DPI from ID2D1Factory1
  12. Create D2D1_RENDER_TARGET_PROPERTIES using obtained DPI
  13. Create ID2D1RenderTarget using ID2D1Factory1, IDXGISurface and D2D1_RENDER_TARGET_PROPERTIES
  14. Create shared ID2D1Bitmap using ID2D1RenderTarget, IDXGISurface and D2D1_BITMAP_PROPERTIES
  15. Obtain IDXGIDevice using ID3D11Device
  16. Create ID2D1Device using ID2D1Factory1 and IDXGIDevice
  17. Obtain ID2D1DeviceContext using ID2D1Device
  18. Create ChromaKey ID2D1Effect using ID2D1DeviceContext
  19. Define D2D1_VECTOR_3F basing on ChromaKey background
  20. Set parameters and D2D1_VECTOR_3F of ID2D1Effect
  21. Drow over ID2D1Bitmap using ID2D1DeviceContext, and ID2D1Effect
  22. Return new ID3D11Texture2D bound to ID2D1Bitmap

Here is a code.

Defines:

#define SIZEOF_ARRAY(arr)   (sizeof(arr)/sizeof((arr)[0]))
#define RET_HR(_f) hr = _f; if (FAILED(hr)) return hr;
#define RET_HR_NULL( _f, _obj ) hr = _f; if (FAILED(hr) || !_obj) return FAILED(hr) ? hr : S_FALSE;

Device creation:

inline CComPtr<ID3D11Device> DX11_CreateDevice(IDXGIAdapter* _pAdapter, ID3D11DeviceContext** _ppD2D1DeviceContext = NULL)
{
    DXGI_ADAPTER_DESC dxgiDesc = {};
    CComQIPtr<IDXGIAdapter> qpDXGIAdapter(_pAdapter);
    if (qpDXGIAdapter)
        qpDXGIAdapter->GetDesc(&dxgiDesc);

    CComPtr<ID3D11Device> cpD3D11Device;
    D3D_FEATURE_LEVEL d3dFeature = (D3D_FEATURE_LEVEL)0;
    D3D_FEATURE_LEVEL arrD3DFeatures[] = {
        D3D_FEATURE_LEVEL_11_1,
        D3D_FEATURE_LEVEL_11_0,
        D3D_FEATURE_LEVEL_10_1,
        D3D_FEATURE_LEVEL_10_0,
        D3D_FEATURE_LEVEL_9_3,
        D3D_FEATURE_LEVEL_9_2,
        D3D_FEATURE_LEVEL_9_1 };

    HRESULT hr = S_OK;

    RET_HR(D3D11CreateDevice(
        qpDXGIAdapter, 
        qpDXGIAdapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, 
        nullptr, 
        D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_DEBUG, 
        arrD3DFeatures, 
        SIZEOF_ARRAY(arrD3DFeatures), 
        D3D11_SDK_VERSION, 
        &cpD3D11Device, 
        &d3dFeature, 
        _ppD2D1DeviceContext
    ));

    CComQIPtr<ID3D10Multithread> qpMTProtect(cpD3D11Device);
    ATLASSERT(qpMTProtect);
    if (qpMTProtect)
        qpMTProtect->SetMultithreadProtected(TRUE);

    return cpD3D11Device;
}

ChromaKey code:

HRESULT DXV_ChromaKey(ID3D11Texture2D* _pTexIn, ID3D11Texture2D** _pTexOut)
{
    // -----------------
    HRESULT hr = S_OK;

    CComPtr<ID2D1Factory1> cpD2DFactory;
    RET_HR_NULL(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &cpD2DFactory), cpD2DFactory);

    // Create the DX11 API device object, and get a corresponding context.
    CComPtr<ID3D11DeviceContext> cpD3D11DeviceContext;

    CComPtr<IDXGIAdapter> cpNVidiaAdpt = DXGI_AdapterByType(eGPU_NVidia);
    CComPtr<ID3D11Device> cpD3D11Device = DX11_CreateDevice(cpNVidiaAdpt, &cpD3D11DeviceContext);

    CComPtr<IDXGIResource> cpDXGIResource;
    RET_HR_NULL(_pTexIn->QueryInterface(__uuidof(IDXGIResource), (void**)&cpDXGIResource), cpDXGIResource);

    HANDLE sharedHandle;
    cpDXGIResource->GetSharedHandle(&sharedHandle);

    CComPtr<ID3D11Texture2D> cpTexIn;
    cpD3D11Device->OpenSharedResource(sharedHandle, __uuidof(ID3D11Resource), (void**)(&cpTexIn));

    D3D11_TEXTURE2D_DESC td;
    cpTexIn->GetDesc(&td);
    td.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    td.CPUAccessFlags = D3D11_CPU_ACCESS_READ;

    CComPtr<ID3D11Texture2D> cpNewTexture;
    RET_HR_NULL(cpD3D11Device->CreateTexture2D(&td, NULL, &cpNewTexture), cpNewTexture);

    cpD3D11DeviceContext->CopyResource(cpNewTexture, cpTexIn);

    CComPtr<IDXGISurface> cpDXGISurface;
    RET_HR_NULL(cpNewTexture->QueryInterface(&cpDXGISurface), cpDXGISurface);

    // -----------------

    D2D1_SIZE_U size = D2D1::SizeU(200, 200); // Adapt to your own size.

    D2D1_PIXEL_FORMAT desc2d;
    desc2d.format = DXGI_FORMAT_B8G8R8A8_UNORM;
    desc2d.alphaMode = D2D1_ALPHA_MODE_IGNORE; // Adapt to your needs.      

    D2D1_BITMAP_PROPERTIES bmpprops;
    bmpprops.dpiX = 96.0f;
    bmpprops.dpiY = 96.0f;
    bmpprops.pixelFormat = desc2d;

    FLOAT dpiX;
    FLOAT dpiY;
    cpD2DFactory->GetDesktopDpi(&dpiX, &dpiY);

    D2D1_RENDER_TARGET_PROPERTIES d2d1RenderTargetProperties =
        D2D1::RenderTargetProperties(
            D2D1_RENDER_TARGET_TYPE_DEFAULT,
            D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
            dpiX,
            dpiY
        );

    CComPtr<ID2D1RenderTarget> cpRenderTarget;
    RET_HR_NULL(cpD2DFactory->CreateDxgiSurfaceRenderTarget(
        cpDXGISurface,
        &d2d1RenderTargetProperties,
        &cpRenderTarget),
        cpRenderTarget);

    // -----------------

    CComPtr<ID2D1Bitmap> cpBitmap;
    cpRenderTarget->CreateSharedBitmap(__uuidof(IDXGISurface), cpDXGISurface, &bmpprops, &cpBitmap);

    // -----------------

    CComPtr<IDXGIDevice> cpDXGIDevice;
    // Obtain the underlying DXGI device of the Direct3D11 device.
    RET_HR_NULL(cpD3D11Device->QueryInterface(&cpDXGIDevice), cpDXGIDevice);

    CComPtr<ID2D1Device> cpD2D1Device;
    // Obtain the Direct2D device for 2-D rendering.
    RET_HR_NULL(cpD2DFactory->CreateDevice(cpDXGIDevice, &cpD2D1Device), cpD2D1Device);

    CComPtr<ID2D1DeviceContext> cpD2DContext;
    // Get Direct2D device's corresponding device context object.
    RET_HR_NULL(cpD2D1Device->CreateDeviceContext(
        D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
        &cpD2DContext
    ), cpD2DContext);

    CComPtr<ID2D1Effect> chromakeyEffect;
    RET_HR_NULL(cpD2DContext->CreateEffect(CLSID_D2D1ChromaKey, &chromakeyEffect), chromakeyEffect);

    D2D1_VECTOR_3F Vector3F;
    Vector3F.x = .32f;
    Vector3F.y = .99f;
    Vector3F.z = .48f;

    int nSize = sizeof(Vector3F);
    BYTE* pData = (BYTE*)&Vector3F;

    chromakeyEffect->SetInput(0, cpBitmap);
    RET_HR(chromakeyEffect->SetValue(D2D1_CHROMAKEY_PROP_COLOR, pData, nSize));
    RET_HR(chromakeyEffect->SetValue(D2D1_CHROMAKEY_PROP_TOLERANCE, 0.2f));
    RET_HR(chromakeyEffect->SetValue(D2D1_CHROMAKEY_PROP_INVERT_ALPHA, false));
    RET_HR(chromakeyEffect->SetValue(D2D1_CHROMAKEY_PROP_FEATHER, false));

    cpD2DContext->BeginDraw();
    cpD2DContext->DrawImage(chromakeyEffect);
    RET_HR(cpD2DContext->EndDraw());

    return cpNewTexture->QueryInterface(_pTexOut);
    // -----------------
}

Entry point:

TEST_METHOD(UT_DXV_ChromaKey)
{
    MTimeout timeOut(__FUNCTION__);
    HRESULT hr = S_OK;

    DX11Texture::TPtr apTexturePicOrg;
    DX_TextureLoadFromFile(cbsChromaCat, &apTexturePicOrg);
    Assert::IsTrue(apTexturePicOrg);

    CComPtr<ID3D11Texture2D> cpD3D11Texture;
    hr = m_arrVidProcessor[0]->DXV_ChromaKey(apTexturePicOrg, &cpD3D11Texture);

    CComPtr<IMFFrame> cpMFFrameCnv;
    MCreator::MFFrameCreateFromTexture(NULL, cpD3D11Texture, 0, NULL, &cpMFFrameCnv, NULL);
    cpMFFrameCnv->MFVideoSaveToFile(L"C:\\temp\\Kosh.bmp");
}

The input picture:
enter image description here

Now, I'm stucking on 13th step:

  1. Create ID2D1RenderTarget using ID2D1Factory1, IDXGISurface and D2D1_RENDER_TARGET_PROPERTIES
RET_HR_NULL(cpD2DFactory->CreateDxgiSurfaceRenderTarget(
        cpDXGISurface,
        &d2d1RenderTargetProperties,
        &cpRenderTarget),
        cpRenderTarget);

Despite D3D11_CREATE_DEVICE_DEBUG I get just follow error as HRESULT of CreateDxgiSurfaceRenderTarget:

E_INVALIDARG One or more arguments are invalid.

Here is content of td and description of cpDXGISurface:

td  {Width=0x00000354 Height=0x000001e0 MipLevels=0x00000001 ...}   D3D11_TEXTURE2D_DESC
    Width   0x00000354  unsigned int
    Height  0x000001e0  unsigned int
    MipLevels   0x00000001  unsigned int
    ArraySize   0x00000001  unsigned int
    Format  DXGI_FORMAT_B8G8R8A8_UNORM (0x00000057) DXGI_FORMAT
    SampleDesc  {Count=0x00000001 Quality=0x00000000 }  DXGI_SAMPLE_DESC
    Usage   D3D11_USAGE_DEFAULT (0x00000000)    D3D11_USAGE
    BindFlags   0x00000008  unsigned int
    CPUAccessFlags  0x00020000  unsigned int
    MiscFlags   0x00000002  unsigned int

sd  {Width=0x00000354 Height=0x000001e0 Format=DXGI_FORMAT_B8G8R8A8_UNORM (0x00000057) ...} DXGI_SURFACE_DESC
    Width   0x00000354  unsigned int
    Height  0x000001e0  unsigned int
    Format  DXGI_FORMAT_B8G8R8A8_UNORM (0x00000057) DXGI_FORMAT
    SampleDesc  {Count=0x00000001 Quality=0x00000000 }  DXGI_SAMPLE_DESC
c++
gpu
directx-11
direct2d
direct3d11
asked on Stack Overflow Mar 10, 2020 by Olga Pshenichnikova • edited Mar 17, 2020 by Olga Pshenichnikova

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0