首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从DXVA2渲染IDirect3DSurface9?

从DXVA2渲染IDirect3DSurface9?
EN

Stack Overflow用户
提问于 2019-01-13 23:52:17
回答 1查看 603关注 0票数 1

我从使用硬件加速的DXVA2视频解码器得到了一个IDirect3DSurface9

我正在尝试通过它的句柄在我的窗口上呈现这个硬件IDirect3DSurface9。以下是我的摘要代码。

第一个方法是使用hwnd调用dxva2_init(AVCodecContext *s, HWND hwnd);它是窗口句柄

代码语言:javascript
复制
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;
}

解码成功后,我得到了一个IDirect3DSurface9,并通过以下函数呈现它。

代码语言:javascript
复制
 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;
}

注意:上面的所有D3D函数:Clear(), BeginScene(), GetBackBuffer(), StretchRect(), EndScene(), Present()都返回成功。但是这个框架没有显示在我的窗口上。

我想,我错过了一些将我的窗口句柄与DXVA2Context集成在一起的代码。在这段代码中,我只在函数dxva2_init()中指定:ctx->deviceHandle = hwnd;

我找了很多次,但到目前为止还是找不到解决方案,有人能帮我吗?

非常感谢!

EN

回答 1

Stack Overflow用户

发布于 2019-01-19 04:52:20

我可以帮你写完整的代码。

如果没有完整的代码,我建议你检查一下StretchRect的使用,就像这样:

IDirect3DDevice9::StretchRect

StretchRect限制

  • 驱动程序的支持各不相同。请参阅下面有关驱动程序支持的一节,以了解哪些驱动程序支持哪些源格式和目标格式。
  • 必须在默认内存池中创建源图面和目标图面。
  • 如果指定了筛选,则必须设置相应的筛选器上限(请参见
  • 中的StretchRectFilterCaps

这背后的想法是,例如,我们对d3d9设备/表面9(创建/初始化/参数/等)一无所知。

此外,您还可以研究我的项目中的代码来进行dxva2解码:

H264Dxva2Decoder

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54170536

复制
相关文章

相似问题

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