【问题标题】:Render an IDirect3DSurface9 from DXVA2?从 DXVA2 渲染 IDirect3DSurface9?
【发布时间】:2019-06-07 19:02:21
【问题描述】:

我使用硬件加速从DXVA2 视频解码器获得了IDirect3DSurface9

我正在尝试通过其句柄在“我的窗口”上渲染此硬件IDirect3DSurface9。以下是我的总结代码。

第一个,我叫dxva2_init(AVCodecContext *s, HWND hwnd)hwnd 是窗口的句柄

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,我通过以下函数渲染它。

 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-&gt;deviceHandle = hwnd;

我搜索了很多次,但到目前为止我仍然找不到解决方案,任何人都可以帮助我吗?

非常感谢!

【问题讨论】:

    标签: c++ ffmpeg render hardware-acceleration dxva


    【解决方案1】:

    我可以提供完整的代码。

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

    IDirect3DDevice9::StretchRect

    StretchRect 限制

    • 驱动程序支持各不相同。请参阅驱动程序支持部分(下文),了解哪些驱动程序支持哪些源格式和目标格式。
    • 必须在默认内存池中创建源表面和目标表面。
    • 如果指定了过滤,则必须设置适当的过滤器上限(请参阅 D3DCAPS9 中的 StretchRectFilterCaps)。
    • 等等……

    这背后的想法,例如,我们对您的 d3d9device/surface9(创建/初始化/参数/等)一无所知。

    另外,您可以从我的项目中研究这段代码来进行 dxva2 解码:

    H264Dxva2Decoder

    【讨论】:

      猜你喜欢
      • 2017-03-01
      • 1970-01-01
      • 2016-04-15
      • 1970-01-01
      • 1970-01-01
      • 2020-11-15
      • 1970-01-01
      • 2014-12-04
      • 1970-01-01
      相关资源
      最近更新 更多