[mjpeg_qsv] get_buffer() failed
qsv解码后,使用滤镜经常会遇到这个问题。报这个错误是因为GPU的显存数据无法直接使用。
如下:
访问qsv解码后存入GPU的数据有两种方式。
1.把显存的数据copy到系统内存
re = av_hwframe_transfer_data(sw_pframe, praw_frame, 0);
这个接口的问题是,从GPU->CPU的数据拷贝,过于消耗cpu,也费时,远大于系统内存之间的拷贝,可能因为显卡是外设的原因吧。因此有了下面这一种不拷贝的方式。
2.将显存中的数据映射成可以访问的数据。
(此时数据依然还在显存中,只是我们拥有了访问的能力。若未经映射,即使有地址如praw_frame->data,一读写就报错),笔者环境为intel N6000,4核4线程,切换为这种方式后,id节省了10%。
但用它也经常会带来一些问题。
re = av_hwframe_map(sw_pframe, praw_frame, 0);
就比如标题中的报错问题
我们用滤镜如下,用2.映射地址的方式,将sw_pframe传入滤镜。
若此时不进行其中的像素格式转换,就会报标题的错误。
av_bprintf(&args,
"buffer=video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d:frame_rate=%d/%d[main];"
"buffer=video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d:frame_rate=%d/%d[logo];"
"[main][logo]overlay=x=10:y=10[result];"
"[result]format=yuv420p[result_2];"
"[result_2]buffersink",
frame->width, frame->height, frame->format, tb.num, tb.den, sar.num, sar.den, fr.num, fr.den,
logo_frame->width, logo_frame->height, logo_frame->format, logo_tb.num, logo_tb.den,
logo_sar.num, logo_sar.den, logo_fr.num, logo_fr.den);
然后add输入,get数据。注意result_frame->data的内存是接口分配的。因此从sw_pframe到result_frame其实是一次深拷贝。并且从显存copy到系统内存了。而av_buffersink_get_frame_flags并不具备这个能力,因此才会报上述错误。
加上像素格式转换就正常了呢,因此可以看出滤镜的像素格式转换拥有av_hwframe_transfer_data的能力。
发现进行nv12的像素格式转换,依然报上述错误。因为数据inter硬件解码后就是nv12,不会进行这步。因此也没有完成av_hwframe_transfer_data过程。
AVFrame *result_frame = av_frame_alloc();
....//伪代码
ret = av_buffersrc_add_frame_flags(mainsrc_ctx, sw_pframe,AV_BUFFERSRC_FLAG_PUSH);
ret = av_buffersink_get_frame_flags(resultsink_ctx, result_frame,AV_BUFFERSINK_FLAG_NO_REQUEST);
ffmpeg是音视频必备,但即使从业数年,它似乎依然有无穷的秘密,感兴趣添加笔者微信:YQW1163720468,加入ffmpeg微信群讨论。但记得备注:ffmpeg爱好者" />
![](https://img-blog.csdnimg.cn/32ebb60e13f9449496052c247d2ccf65.png)
![](https://img-blog.csdnimg.cn/1b3e3fc19f5f4837a6514769eabf4e10.png)
![](https://img-blog.csdnimg.cn/32ebb60e13f9449496052c247d2ccf65.png)