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

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

但是,有几个问题:

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

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

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

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

4、新遇到问题(2019.11),如果编码端采用硬件(GPU)编码后,会生成1088P的图像,你没看错,是1088,不是1080P,这时候解码如果直接显示会在屏幕下边产生8个像素高的绿条。

 

第一个问题,修改源码:

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哦

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周星星的星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值