问题描述
我正在尝试在 c ++ 中的 ffmpeg 中找出硬件解码。我在任何 api 上都会遇到相同的错误。 这是初始化代码:
AVHWDeviceType devType = av_hwdevice_find_type_by_name(HW_DECODER_NAME);
for (int i = 0;; i++)
{
const AVCodecHWConfig *config = avcodec_get_hw_config(av_codec,i);
if (!config)
{
fprintf(stderr,"Decoder %s does not support device type %s.\n",av_codec->name,av_hwdevice_get_type_name(devType));
return false;
}
if (config->methods & AV_CODEC_HW_CONfig_METHOD_HW_DEVICE_CTX && config->device_type == devType)
{
hw_pix_fmt = config->pix_fmt;
break;
}
}
hw_device_ctx = av_hwdevice_ctx_alloc(devType);
*av_codec_ctx = avcodec_alloc_context3(av_codec);
if (!av_codec_ctx)
{
printf("Couldn't create AVCodecContext\n");
return false;
}
if (avcodec_parameters_to_context(*av_codec_ctx,av_codec_params) < 0)
{
printf("Couldn't initialize AVCodecContext\n");
return false;
}
(*av_codec_ctx)->get_format = get_hw_format;
//Initialize hardware context
int err = 0;
if ((err = av_hwdevice_ctx_create(&hw_device_ctx,devType,NULL,0)) < 0)
{
fprintf(stderr,"Failed to create specified HW device.\n");
return false;
}
(*av_codec_ctx)->hw_device_ctx = av_buffer_ref(hw_device_ctx);
if (avcodec_open2(*av_codec_ctx,av_codec,NULL) < 0)
{
printf("Couldn't open codec\n");
return false;
}
b_is_initialized = true;
这里是解码器代码:
int response;
response = avcodec_send_packet(av_codec_ctx,av_packet);
if (response < 0)
{
printf("Couldn't send video frame to decoder.\n");
print_error(response);
return false;
}
realloc_frame(&av_frame);
response = avcodec_receive_frame(av_codec_ctx,av_frame);
if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
{
av_frame_free(&av_frame);
return false;
}
else if (response < 0)
{
print_error(response);
return false;
}
if(hwdecoder.is_initialized())
{
if(!hwdecoder.decode(av_packet,&av_frame))
{
printf("Failed while decoding frame on gpu.\n");
}
}
pts = av_frame->pts;
// Set up sws scaler
if (!sws_scaler_ctx)
{
auto source_pix_fmt = correct_for_deprecated_pixel_format((AVPixelFormat)av_frame->format);
//Send here frame params
sws_scaler_ctx = sws_getContext(width,height,source_pix_fmt,width,AV_PIX_FMT_RGB0,SWS_BICUBIC,NULL);
在处理器上解码没有问题,但是当我在 gpu 上解码时,结果是解码了视频的某些部分,然后在 avcodec_send_packet
期间我得到了Invalid data found处理输入错误时。请帮忙,我已经受苦了第二周。
编辑
OP 忘记了 hwdecoder.decode
方法。
int ret = 0;
realloc_frame(&sw_frame);
if ((*av_frame)->format == hw_pix_fmt)
{
if ((ret = av_hwframe_transfer_data(sw_frame,*av_frame,0)) < 0)
{
fprintf(stderr,"Error transferring the data to system memory\n");
av_frame_free(&sw_frame);
return false;
}
}
错误日志:
Couldn't send video frame to decoder.
Invalid data found when processing input
[AVHWFramesContext @ 000001E44F6EC8C0] Static surface pool size exceeded.
[h264 @ 000001E445D60940] get_buffer() Failed
[h264 @ 000001E445D60940] thread_get_buffer() Failed
[h264 @ 000001E445D60940] decode_slice_header error
[h264 @ 000001E445D60940] no frame!
我的代码基于这个例子:https://ffmpeg.org/doxygen/4.0/hw_decode_8c-example.html
在 windows 上我使用 dxva2 设备,使用 cmake 3.9 配置项目,并使用 MSVC amd64 构建。 在 linux 上,我使用了 vdpau 设备,从源 ffmpeg 库编译,项目使用 cmake 3.9 配置并使用 gcc 10 构建
更新
此代码在 cuda 上运行良好,但对于另一个 api,我仍然遇到问题。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)