SOPHON ffmpeg 使用常见问题

1. 如何使用Sophon ffmpeg实现对JPEG的encode和transcode

示例:jpeg encoder

ffmpeg -c:v jpeg_bm -i src/5.jpg -c:v jpeg_bm  -is_dma_buffer 1 -y 5nx.jpg

示例:mjpeg transcoder

ffmpeg -c:v jpeg_bm -num_extra_framebuffers 2 -i in_mjpeg.avi -c:v jpeg_bm -is_dma_buffer 1 -y test_avi.mov
ffmpeg -c:v jpeg_bm -num_extra_framebuffers 2 -i in_mjpeg.mov -c:v jpeg_bm -is_dma_buffer 1 -y test_mov.mov

2. 获取SOPHON ffmepg支持的所有bm硬件编/解码器的名称以及详细信息

获取FFMPEG支持的编/解码器名称的命令(解码器示例):ffmpeg -decoders | grep _bm
输出

V….. avs_bm bm AVS decoder wrapper (codec avs)
V….. cavs_bm bm CAVS decoder wrapper (codec cavs)
V….. flv1_bm bm FLV1 decoder wrapper (codec flv1)
V….. h263_bm bm H.263 decoder wrapper (codec h263)
V….. h264_bm bm H.264 decoder wrapper (codec h264)
V….. hevc_bm bm HEVC decoder wrapper (codec hevc)
V….. jpeg_bm BM JPEG DECODER (codec mjpeg)
V….. mpeg1_bm bm MPEG1 decoder wrapper (codec mpeg1video)
V….. mpeg2_bm bm MPEG2 decoder wrapper (codec mpeg2video)
V….. mpeg4_bm bm MPEG4 decoder wrapper (codec mpeg4)
V….. mpeg4v3_bm bm MPEG4V3 decoder wrapper (codec msmpeg4v3)
V….. vc1_bm bm VC1 decoder wrapper (codec vc1)
V….. vp3_bm bm VP3 decoder wrapper (codec vp3)
V….. vp8_bm bm VP8 decoder wrapper (codec vp8)
V….. wmv1_bm bm WMV1 decoder wrapper (codec wmv1)
V….. wmv2_bm bm WMV2 decoder wrapper (codec wmv2)
V….. wmv3_bm bm WMV3 decoder wrapper (codec wmv3)

解码器获取详细信息(以 jpeg_bm 为示例):ffmpeg -h decoder=jpeg_bm
输出

Decoder jpeg_bm [BM JPEG DECODER]:
General capabilities: avoidprobe
Threading capabilities: none
jpeg_bm_decoder AVOptions:
-bs_buffer_size <int> .D.V….. the bitstream buffer size (Kbytes) for bm jpeg decoder (from 0 to INT_MAX) (default 5120)
-chroma_interleave <flags> .D.V….. chroma interleave of output frame for bm jpeg decoder (default 0)
-num_extra_framebuffers <int> .D.V….. the number of extra frame buffer for jpeg decoder (0 for still jpeg, at least 2 for motion jpeg) (from 0 to INT_MAX) (default 0)

3. SOPHON ffmpeg中做图像格式/大小变换导致视频播放时回退或者顺序不对的情况处理办法

原因分析:

ffmpeg在编码的时候底层维护了一个avframe的队列作为编码器的输入源,编码期间应保证队列中数据有效,如果在解码后需要缩放或者像素格式转换时候需要注意送进编码器的avframe的数据有效和释放问题。

在例子ff_bmcv_transcode中从解码输出src-avframe转换成src-bm_image然后做像素格式转换或者缩放为dst-bm_image最后转回dst-avframe 去编码的过程中src-avframe、src-bm_image的设备内存是同一块,dst- avframe、dst-bm_image的设备内存是同一块。在得到dst-bm_image后即可释放src_avframe和src-bm_image的内存(二者释放其中一个即可释放设备内存),作为编码器的输入dts-bm_image在转换成dst- avframe之后其设备内存依然不能被释放(常见的异常情况是函数结束dts-bm_image的引用计数为0导致其被释放),如果dst-bm_image被释放了此时用dst-avframe去编码结果肯定会有问题。

解决方法

通过dst-bm_image的指针malloc分配一块内存,然后将其传给av_buffer_create,这样就保证在函数结束的时候dst-bm_image引用计数不会减1,释放的方法是将malloc的dst-bm_image指针通过av_buffer_create传给释放的回调函数,当dst- avframe引用计数为0的时候会调用回调函数将malloc的指针和dst-bm_image的设备内存一起释放。详见例子ff_bmcv_transcode/ff_avframe_convert.cpp。

4. SOPHON ffmpeg在soc模式下解码时拿到AVframe将data[0-3] 拷贝到系统内存时间远大于系统内存内部拷贝

SOPHON ffmpeg在soc模式下解码时拿到AVframe将data[0-3] copy到系统内存发现copy时间是在20ms左右而相同数据量在系统内存两块地址copy只需要1-3ms

原因分析及解决方案:
出现问题的原因是系统在ffmpeg中认是禁止cache的,因此用cpu copy性能很低,使能cache就能达到系统内存互相copy同样的速度。可以用以下接口使能cache:

av_dict_set_int(&opts, "enable_cache", 1, 0);

但是这样直接copy数据保存是非常占用内存、带宽和cpu算力的,我们推荐采用零拷贝的方式来实现原始解码数据的保存:

  1. 推荐使用 extra_frame_buffer_num 参数指定增大硬件帧缓存数量,可以根据自己的需要选择缓存帧的数量。 这个方式的弊端,一个是占用解码器内存,可能减少视频解码的路数;另一个是当不及时释放,当缓存帧全部用完时,会造成视频硬件解码堵塞。

    av_dict_set_int(&opts, "extra_frame_buffer_num", extra_frame_buffer_num, 0);
    
  2. 推荐使用 output_format参数设置解码器输出压缩格式数据,然后使用vpp处理输出非压缩yuv数据(当需要缩放,crop时,可以同步完成), 然后直接零拷贝引用非压缩yuv数据。这种方式不会影响到硬件解码性能,并且可以缓存的数据空间也大很多。

    av_dict_set_int(&opts, "output_format", 101, 0);
    

相关文章

显卡天梯图2024最新版,显卡是电脑进行图形处理的重要设备,...
初始化电脑时出现问题怎么办,可以使用win系统的安装介质,连...
todesk远程开机怎么设置,两台电脑要在同一局域网内,然后需...
油猴谷歌插件怎么安装,可以通过谷歌应用商店进行安装,需要...
虚拟内存这个名词想必很多人都听说过,我们在使用电脑的时候...