问题
I got a IDirect3DSurface9
from DXVA2
video decoder using hardware acceleration.
I'm try to Render this hardware IDirect3DSurface9
on My Window via its handle. The following is my summary code.
The first, I call dxva2_init(AVCodecContext *s, HWND hwnd)
; with hwnd
is window's handle
int dxva2_init(AVCodecContext *s, HWND hwnd)
{
InputStream *ist = (InputStream *)s->opaque;
int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
DXVA2Context *ctx;
int ret;
if (!ist->hwaccel_ctx) {
ret = dxva2_alloc(s);
if (ret < 0)
return ret;
}
ctx = (DXVA2Context *)ist->hwaccel_ctx;
ctx->deviceHandle = hwnd;
if (s->codec_id == AV_CODEC_ID_H264 &&
(s->profile & ~FF_PROFILE_H264_CONSTRAINED) > FF_PROFILE_H264_HIGH) {
av_log(NULL, loglevel, "Unsupported H.264 profile for DXVA2 HWAccel: %d\n", s->profile);
return AVERROR(EINVAL);
}
if (ctx->decoder)
dxva2_destroy_decoder(s);
ret = dxva2_create_decoder(s);
if (ret < 0) {
av_log(NULL, loglevel, "Error creating the DXVA2 decoder\n");
return ret;
}
return 0;
}
After Decoding successful, I got got a IDirect3DSurface9
, and I Render it by following function.
int dxva2_render(AVCodecContext *s, AVFrame *frame)
{
LPDIRECT3DSURFACE9 surface = (LPDIRECT3DSURFACE9)frame->data[3];
InputStream *ist = (InputStream *)s->opaque;
DXVA2Context *ctx = (DXVA2Context *)ist->hwaccel_ctx;
try
{
lockRenderCS.Enter();
HRESULT hr = ctx->d3d9device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 0, 0), 1.0f, 0);
if (hr != D3D_OK)
return 0;
hr = ctx->d3d9device->BeginScene();
if (hr != D3D_OK)
return 0;
hr = ctx->d3d9device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
if (hr != D3D_OK)
return 0;
hr = ctx->d3d9device->StretchRect(surface, NULL, pBackBuffer, NULL, D3DTEXF_LINEAR);
if (hr != D3D_OK)
return 0;
hr = ctx->d3d9device->EndScene();
if (hr != D3D_OK)
return 0;
hr = ctx->d3d9device->Present(NULL, NULL, NULL, NULL);
if (hr != D3D_OK)
return 0;
}
finally
{
lockRenderCS.Leave();
}
return 0;
}
Note: All D3D function above: Clear(), BeginScene(), GetBackBuffer(), StretchRect(), EndScene(), Present()
were return Successful. But the frame was not display on My Window.
I Guess that, I miss some code for integrated My Window Handle with DXVA2Context
. In this code I only assign: ctx->deviceHandle = hwnd;
in function dxva2_init()
.
I search many times, but so far I still cannot find the solution, Anyone can help me?
Many Thanks!
回答1:
I could help with full code.
Without full code, i suggest you to check your use of StretchRect, just like that :
IDirect3DDevice9::StretchRect
StretchRect Restrictions
- Driver support varies. See the section on driver support (below) to see which drivers support which source and destination formats.
- The source and destination surfaces must be created in the default memory pool.
- If filtering is specified, you must set the appropriate filter caps (see StretchRectFilterCaps in D3DCAPS9).
- etc...
The idea behind this, we don't know nothing about your d3d9device/surface9 (creation/initialization/parameter/etc...), for example.
Also, you can study this code from my project to do dxva2 decoding :
H264Dxva2Decoder
来源:https://stackoverflow.com/questions/54170536/render-an-idirect3dsurface9-from-dxva2