如何使用带有ffmpeg的DXVA2解码和获取帧
How to employ DXVA2 with ffmpeg to decode and get frame
我在 Windows 中搜索了一个关于如何使用 ffmpeg 使用硬件加速解码 H264 流的简单示例,但我找不到任何示例。
我知道我应该使用 dxva2 和 ffmpeg 来获得硬件加速。
我可以在 CPU 上使用 ffmpeg 解码 H264,然后将 NV12 格式转换为 RGBA 并将帧保存为 bmp 文件,感谢 post.
中提供的示例项目
我已按照以下post中提供的内容获得有关 dxva2 的帮助:
我相信我可以用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] bad src image pointers
显然 pFrameYuv->data
有问题,但我不知道是什么。
我们如何将使用 DXVA2 解码的 NV12 帧转换为使用 sws_scale 的 RGBA?
问题已解决。
这是由于不正确的像素格式类型。
创建 sws_context 时,我使用了编解码器上下文的像素格式,如下所示:(这对于 SW 解码是可行的)
// 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
);
pCodecCtx->pix_fmt 是 AV_PIX_FMT_YUV420P 但解码帧格式是 AV_PIX_FMT_NV12 与 DXVA2。设置正确的格式后,我可以使用 sws_scale 将 NV12 帧转换为 RGB。
正确的参数:
// 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
);
另外,注意取消引用输出检索的帧,如下所示:
av_frame_unref(pFrameYuv);
否则内存泄漏。
此外,如 所述,dxva2_retrieve_data_call 效率非常低。您应该寻找另一种从 GPU 获取数据的方法。
我在 Windows 中搜索了一个关于如何使用 ffmpeg 使用硬件加速解码 H264 流的简单示例,但我找不到任何示例。 我知道我应该使用 dxva2 和 ffmpeg 来获得硬件加速。
我可以在 CPU 上使用 ffmpeg 解码 H264,然后将 NV12 格式转换为 RGBA 并将帧保存为 bmp 文件,感谢 post.
中提供的示例项目我已按照以下post中提供的内容获得有关 dxva2 的帮助:
我相信我可以用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] bad src image pointers
显然 pFrameYuv->data
有问题,但我不知道是什么。
我们如何将使用 DXVA2 解码的 NV12 帧转换为使用 sws_scale 的 RGBA?
问题已解决。
这是由于不正确的像素格式类型。 创建 sws_context 时,我使用了编解码器上下文的像素格式,如下所示:(这对于 SW 解码是可行的)
// 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
);
pCodecCtx->pix_fmt 是 AV_PIX_FMT_YUV420P 但解码帧格式是 AV_PIX_FMT_NV12 与 DXVA2。设置正确的格式后,我可以使用 sws_scale 将 NV12 帧转换为 RGB。
正确的参数:
// 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
);
另外,注意取消引用输出检索的帧,如下所示:
av_frame_unref(pFrameYuv);
否则内存泄漏。
此外,如