如何使用带有ffmpeg的DXVA2来解码和获取帧

时间:2016-06-22 09:11:12

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

我搜索了一个关于如何使用Windows中的ffmpeg通过硬件加速解码H264流的简单示例,但我找不到任何。 我知道我应该使用带有ffmpeg的dxva2进行硬件加速。

我可以在CPU上使用ffmpeg解码H264,然后将NV12格式转换为RGBA并将帧保存为bmp文件,这要归功于post中提供的示例项目。

我已按照以下帖子中提供的内容获取有关dxva2的帮助:post

我相信我可以用dxva2成功解码;但是,当我想获得解码后的帧并将其转换为RGBA格式并将其保存为bmp文件时,我收到有关源指针的错误。

我解码并检索框架如下:

int videoFrameBytes = avcodec_decode_video2(pCodecCtx_hwaccel, pFrameYuv, &got_picture_ptr, avpkt);

if (got_picture_ptr==1)
{
    if(dxva2_retrieve_data_call(pCodecCtx_hwaccel, pFrameYuv) == 0)
    {
        fprintf(stderr, "Got frame successfully\n");
        result = true;
    }
}

并将输出框提供给:

sws_scale(pImgConvertCtx, pFrameYuv->data, pFrameYuv->linesize, 0, height, frame->data, frame->linesize);  

我收到此错误:

  

[swscaler @ 030c5c20]糟糕的src图像指针

pFrameYuv->data显然有问题,但我不知道是什么。

如何使用sws_scale将使用DXVA2解码的NV12帧转换为RGBA?

1 个答案:

答案 0 :(得分:1)

问题解决了。

这是由于像素格式类型不正确。 在创建sws_context时,我使用了编解码器上下文的像素格式,如下所示:(可以进行SW解码)

latest_df <- cbind(latest_df, new_df)

并且pCodecCtx-&gt; pix_fmt是AV_PIX_FMT_YUV420P但是解码的帧格式是具有DXVA2的AV_PIX_FMT_NV12。设置正确的格式后,我可以使用sws_scale将NV12帧转换为RGB。

正确的参数:

// initialize SWS context for software scaling
sws_ctx = sws_getContext(pCodecCtx->width,
    pCodecCtx->height,
    pCodecCtx->pix_fmt,
    pCodecCtx->width,
    pCodecCtx->height,
    AV_PIX_FMT_RGB24,
    SWS_BILINEAR,
    NULL,
    NULL,
    NULL
    );

另外,请注意取消输出检索帧,如下所示:

// initialize SWS context for software scaling
sws_ctx = sws_getContext(pCodecCtx->width,
    pCodecCtx->height,
    AV_PIX_FMT_NV12,
    pCodecCtx->width,
    pCodecCtx->height,
    AV_PIX_FMT_RGB24,
    SWS_BILINEAR,
    NULL,
    NULL,
    NULL
    );

否则你有内存泄漏。

另外,正如post中所述,dxva2_retrieve_data_call的效率非常低。您应该寻找另一种从GPU获取数据的方法。