dxva2+ffmpeg硬件解码(Windows)重要笔记1

参考了csdn上Win32Project1_ffmpeg_dxva2这个例子,很不错,直接就可以运行。

但是,有几个问题:

1、窗口无法正常缩放,缩放后,图像大小并没有一起缩放

2、H265的编码格式,显示下面有一块绿色。

3、无法从显卡获取YUV420P数据或者NV12数据

3、找了很久网上也没有相关代码实现从显卡获取数据到内存(有些方法相当慢,基本无法使用!)

 

第一个问题,修改源码:

ffmpeg_dxva2.cpp下的static int dxva2_retrieve_data(AVCodecContext *s, AVFrame *frame)函数:

原函数是这样的:

static int dxva2_retrieve_data(AVCodecContext *s, AVFrame *frame)
{
    LPDIRECT3DSURFACE9 surface = (LPDIRECT3DSURFACE9)frame->data[3];
    InputStream        *ist = (InputStream *)s->opaque;
    DXVA2Context       *ctx = (DXVA2Context *)ist->hwaccel_ctx;

    EnterCriticalSection(&cs);

    ctx->d3d9device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    ctx->d3d9device->BeginScene();
    if (m_pBackBuffer)
    {
        m_pBackBuffer->Release();
        m_pBackBuffer = NULL;
    }
    ctx->d3d9device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_pBackBuffer);
    GetClientRect(d3dpp.hDeviceWindow, &m_rtViewport);
    //ctx->d3d9device->StretchRect(surface, NULL, m_pBackBuffer, &m_rtViewport, D3DTEXF_LINEAR);
    ctx->d3d9device->StretchRect(surface, NULL, m_pBackBuffer, &m_rtViewport, D3DTEXF_LINEAR);
    ctx->d3d9device->EndScene();
    ctx->d3d9device->Present(NULL, NULL, NULL, NULL);

    LeaveCriticalSection(&cs);

    return 0;
}

 

修改为:

static int dxva2_retrieve_data(AVCodecContext *s, AVFrame *frame)
{
    LPDIRECT3DSURFACE9 surface = (LPDIRECT3DSURFACE9)frame->data[3];
    InputStream        *ist = (InputStream *)s->opaque;
    DXVA2Context       *ctx = (DXVA2Context *)ist->hwaccel_ctx;

    EnterCriticalSection(&cs);

    ctx->d3d9device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    ctx->d3d9device->BeginScene();
    if (m_pBackBuffer)
    {
        m_pBackBuffer->Release();
        m_pBackBuffer = NULL;
    }
    ctx->d3d9device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_pBackBuffer);
    ctx->d3d9device->StretchRect(surface, NULL, m_pBackBuffer, 0 D3DTEXF_LINEAR);
    ctx->d3d9device->EndScene();
    ctx->d3d9device->Present(NULL, NULL, NULL, NULL);

    LeaveCriticalSection(&cs);

    return 0;
}

 

测试下,可以了。。。

下一篇文章讲第二个问题,我的QQ35744025,windows下播放器已完成,需要合作的或者技术交流的可以加我QQ哦

dxva2+ffmpeg硬件解码(Windows)重要笔记1