将 ffmpeg d3dva 纹理资源复制到共享渲染纹理
Copy ffmpeg d3dva texture resource to shared rendering texture
我正在使用 ffmpeg 根据此示例通过 d3dva 解码视频https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/hw_decode.c. I'm able to succesfully decode video. What I need to do next is to render decoded NV12 frame. I have created directx rendering texture based on this example 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);
但是渲染 window 只是绿色,没有错误,没有 FAILED 小时结果。当我使用 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 根据此示例通过 d3dva 解码视频https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/hw_decode.c. I'm able to succesfully decode video. What I need to do next is to render decoded NV12 frame. I have created directx rendering texture based on this example 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);
但是渲染 window 只是绿色,没有错误,没有 FAILED 小时结果。当我使用 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 调用的。