FFMPEG с ускорением D3D11 hw: Как скопировать текстуру DirectX в OpenGL? - PullRequest
0 голосов
/ 07 апреля 2020

Я декодирую видео, используя FFMPEG с ускорением видео D3D11. Я хочу отобразить декодированные кадры в моем GUI, для которого я использую OpenGL для рендеринга. Я хочу избежать копирования декодированного кадра обратно в системную память. Поэтому моя цель - скопировать / отобразить ID3D11Texture2D, который я получаю из FFMPEG, непосредственно в текстуру OpenGL. Для этого существует расширение OpenGL (WGL_NV_DX_interop и WGL_NV_DX_interop2).

Однако я не запускаю его. Вот мой код (урезанный):

// 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. Однако эта текстура пуста. Я также не вижу никаких действий копирования в мониторе ресурсов графического процессора.

Кто-нибудь, кто сделал это, или может увидеть ошибку в моем подходе?

Я не учел никаких соображений обработки формата NV12. Пока мне достаточно скопировать часть кадра яркости.

...