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

标签 ffmpeg rendering textures directx-11 render-to-texture

基于此示例,我正在使用 ffmpeg 通过 d3dva 解码视频 https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/hw_decode.c 。我能够成功解码视频。接下来我需要做的是渲染解码的 NV12 帧。我根据这个例子创建了directx渲染纹理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;
    }

然后我尝试将 nv12 从 ffmpeg 纹理复制到我的渲染纹理。正如 ffmpeg 在函数 d3d11va_transfer_data 中所做的那样.

    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);

但是渲染窗口只是绿色的,没有错误,没有失败,没有任何结果。当我使用 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)

知道我错过了什么吗?

最佳答案

所以我终于弄清楚出了什么问题,问题是 OpenSharedResource 是从设备而不是 hwDevice 调用的。

关于ffmpeg - 将ffmpeg d3dva纹理资源复制到共享渲染纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58342736/

相关文章:

ffmpeg 转换为 h264 解码器(编解码器 av1)未找到输入流 #0 :0

c# - 将非托管 directX 嵌入 C# 形式

javascript - 如何检测React中的隐藏组件

java - 为什么我的纹理不起作用?

android - 在 Android 上使用 OpenGL ES 2.0 中的着色器程序绘制轮廓

opencv - 为什么我不能使用 FFMPEG 作为 OpenCV 的后端?

c++ - 如何将 Ubuntu 11 中的 Eclipse Indigo 链接到 C++ 的 FFMPEG 8

c++ - FFmpeg C++ 在单独的线程中解码

OpenGL:如何以 10 位(或 12 位或 16 位) channel 深度颜色渲染三角形网格?

c++ - QOpenGLContext 和 native OpenGL 上下文之间的纹理共享不适用于 Mesa 驱动程序