首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >D3D11 hw加速的FFMPEG :如何将DirectX纹理复制到OpenGL?

D3D11 hw加速的FFMPEG :如何将DirectX纹理复制到OpenGL?
EN

Stack Overflow用户
提问于 2020-04-07 14:41:44
回答 1查看 2.1K关注 0票数 1

我用FFMPEG和D3D11视频加速解码一个视频。我想在我的图形用户界面中显示已解码的帧,为此我使用OpenGL进行呈现。我希望避免将解码后的帧复制回系统内存。因此,我的目标是复制/映射从FFMPEG直接获得的ID3D11Texture2D到OpenGL纹理。为此存在一个OpenGL扩展(WGL_NV_DX_interop和WGL_NV_DX_interop2)。

然而,我没有让它运行。到目前为止,我的代码如下(已删除):

代码语言:javascript
复制
// create texture, to be used later in DirectX
GLuint texture_opengl;
glGenTextures(1, &texture_opengl);
// .. and set the usual parameters for it

// setup WGL_NV_DX_interop extension
AVBufferRef* hw_device_ctx_buffer = decoder_ctx->hw_device_ctx;
AVHWDeviceContext* hw_device_ctx = (AVHWDeviceContext*)hw_device_ctx_buffer->data;
AVD3D11VADeviceContext* hw_d3d11_dev_ctx = (AVD3D11VADeviceContext*)hw_device_ctx->hwctx;
HANDLE device_handle = wglDXOpenDeviceNV(hw_d3d11_dev_ctx->device);

// create intermediate texture
D3D11_TEXTURE2D_DESC pDes{};
ZeroMemory(&pDes, sizeof(pDes));
pDes.Width = frame->width;
pDes.Height = frame->height;
pDes.ArraySize = 1;
pDes.MipLevels = 1;
pDes.Format = DXGI_FORMAT_NV12;
pDes.SampleDesc.Count = 1;
pDes.SampleDesc.Quality = 0;
pDes.Usage = D3D11_USAGE_DEFAULT;
pDes.BindFlags = D3D11_BIND_UNORDERED_ACCESS;
pDes.CPUAccessFlags = 0;
pDes.MiscFlags = 0;

ID3D11Texture2D* texture_D3D11;
hw_d3d11_dev_ctx->device->CreateTexture2D(&pDes, NULL, &texture_D3D11);

// connect opengl and directx textures
HANDLE hRegisterObject = wglDXRegisterObjectNV(
    device_handle, texture_D3D11, texture_opengl, GL_TEXTURE_2D, WGL_ACCESS_READ_WRITE_NV
        );

// run loop and display video
while(..)
{
  // read packets from video file and send it to decoder  

  // receive frame from decoder
  avcodec_receive_frame(decoder_ctx, frame);

  // get DirectX objects from frame
  ID3D11Texture2D* hwTexture = (ID3D11Texture2D*)frame->data[0];
  intptr_t texture_array_index = (intptr_t)frame->data[1];

  // copy frame texture to intermediate texture
  hw_d3d11_dev_ctx->device_context->CopySubresourceRegion(
        texture_D3D11, 0, 0, 0, 0,
        hwTexture, texture_array_index,
        NULL
  );

}

在将内容从FFMPEG帧复制到中间纹理texture_directx之后,我希望可以使用OpenGL纹理texture_opengl显示数据。然而,这个纹理是空的。我也没有在GPU的资源监视器中看到任何复制活动。

有谁做过这件事,或者可能在我的方法中看到了错误?

我忽略了处理NV12格式的任何考虑。现在,我只需复制框架的亮度部分就足够了。

EN

回答 1

Stack Overflow用户

发布于 2022-07-20 12:10:30

)太长了,不能发表评论。而且太晚了。但也许你可以向后人报告其中的一些。)

你试过这些吗?

  • 启用Direct3D11中的调试层
  • 将其他方法获得的OpenGL复制到ID3D11Texture2D (地图/上传、渲染、着色写入)。如果这是可行的,那么看下一个项目。
  • 也许您从ID3D11Texture2D获得的FFmpeg缺少一些必要的标志。FFmpeg在hwcontext_d3d11va.c中创建ID3D11Texture2D (包括单个和数组,但您已经在处理数组纹理) .Usage = D3D11_USAGE_DEFAULT,.BindFlags = D3D11_BIND_DECODER,//可能?.MiscFlags = 0,//可能?
  • 确认你遇到了所有的CopySubresourceRegion()。包括“必须具有兼容的DXGI格式.”。否则,复制将失败;请检查返回值是否有错误。调试层会告诉你细节!
  • 尝试使用一些D3D11_BOX,而不是用于pSrcBoxNULL
  • 尝试CopyResource()而不是CopySubresourceRegion()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61082653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档