将ffmpeg d3dva纹理资源复制到共享渲染纹理

4
我正在使用ffmpeg通过d3dva解码视频,参考了这个示例https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/hw_decode.c。我已经成功地解码了视频。接下来需要做的是渲染解码后的NV12帧。我根据这个示例https://github.com/balapradeepswork/D3D11NV12Rendering创建了直接渲染纹理,并将其设置为共享状态。
    D3D11_TEXTURE2D_DESC texDesc;
    texDesc.Format = DXGI_FORMAT_NV12;              // Pixel format
    texDesc.Width = width;                          // Width of the video frames
    texDesc.Height = height;                        // Height of the video frames
    texDesc.ArraySize = 1;                          // Number of textures in the array
    texDesc.MipLevels = 1;                          // Number of miplevels in each texture
    texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; // We read from this texture in the shader
    texDesc.Usage = D3D11_USAGE_DEFAULT;
    texDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
    texDesc.CPUAccessFlags = 0;

    hr = device.CreateTexture2D(&texDesc, null, &nv12Texture);
    if (FAILED(hr))
    {
        error("Failed to create NV12 texture (hr: %s)", hr);
        return false;
    }

    // QI IDXGIResource interface to synchronized shared surface.
    IDXGIResource dxgiResource;
    nv12Texture.QueryInterface(&IID_IDXGIResource, cast(void**)&dxgiResource);

    // obtain handle to IDXGIResource object.
    hr = dxgiResource.GetSharedHandle(&sharedHandle);
    dxgiResource.Release();
    dxgiResource = null;

    if (FAILED(hr))
    {
        error("Failed to create NV12 texture shared handle (hr: %s)", hr);
        return false;
    }

我正在尝试将来自FFmpeg纹理的NV12复制到我的渲染纹理中,就像FFmpeg在d3d11va_transfer_data函数中所做的那样。请注意,保留HTML标签。
    ID3D11Texture2D hwTexture = cast(ID3D11Texture2D)frame.data[0];

    ID3D11Device hwDevice;
    hwTexture.GetDevice(&hwDevice);

    ID3D11DeviceContext hwDeviceCtx;
    hwDevice.GetImmediateContext(&hwDeviceCtx);

    ID3D11Texture2D sharedTexture;

    HRESULT hr = device.OpenSharedResource(sharedHandle, &IID_ID3D11Texture2D,cast(void**) &sharedTexture);
    if(FAILED(hr))
    {
        error("Failed to obtaion open shared resource.");
        return;
    }

    int index = cast(int)frame.data[1];
    hwDeviceCtx.CopySubresourceRegion(sharedTexture, 0, 0, 0, 0, hwTexture, index, null);

但是渲染窗口只是绿色,没有错误,没有失败的hr结果。当我使用sw解码器时,我可以渲染帧,我只需创建具有D3D11_USAGE_DYNAMIC和D3D11_CPU_ACCESS_WRITE的纹理即可。
以下是每个纹理的描述。
hwTexture desc D3D11_TEXTURE2D_DESC(1280, 720, 1, 20, 103, DXGI_SAMPLE_DESC(1, 0), 0, 512, 0, 0)
nv12Texture desc D3D11_TEXTURE2D_DESC(1280, 720, 1, 1, 103, DXGI_SAMPLE_DESC(1, 0), 0, 8, 0, 2)
sharedTexture desc D3D11_TEXTURE2D_DESC(1280, 720, 1, 1, 103, DXGI_SAMPLE_DESC(1, 0), 0, 8, 0, 2)

有什么想法我错过了什么吗?


尝试使用AVD3D11VADeviceContext *device_hwctx = ctx->device_ctx->hwctx;(进行适当的转换)而不是从纹理中获取设备上下文。ctx是您通过avcodec_alloc_context3创建的AVCodecContext。还尝试为nv12Texture设置D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE。 - VuVirt
非常感谢您的评论,但是这并没有帮到我。 - Teamol
1个回答

3
所以,我终于找出问题出在哪里了,问题是OpenSharedResource从设备上调用而不是从hwDevice上调用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接