VENC Q&A
Q1:定码率下画面有呼吸效应
调节方法如下:
-
调大Gop,实际上是减少I帧,因为I帧Size大,减少使得每张Size可以多一点。
-
强制设置qp-delta,强制干预I帧效果(通过MI_VENC_SetRcParam接口设置)。
-
加大码率。
-
ISP 调整画面清晰度等,使得编码压力变小。
Q2: venc绑到scl,如果不去调用MI_VENC_GetStream获取帧,发现串口下查看mi_venc时venc ch info的Fps_1s 显示为0;而调用MI_VENC_GetStream获取帧后,Fps_1s才有值,这是为什么?
没有获取帧,帧会堆积,venc就没有编码,fps自然是0,故是正常的现象。
Q3:创建编码通道时候,最大size如何确定?
最大width需要取使用到的最大值,height只需要满足width*height<max resolution即可,底层用max resolution分配buffer。比如一个用到的码流需要创建1280*1920的编码大小,而另一个大的使用场景是1080P前端信号接入的时候需要编码的大小是1920*1080,那么我们width取最大是1920,height使用1280,因为最大的resolution其实是1920*1280,而不需要按照1920*1920去创建编码通道,对应MI_U32 u32MaxPicWidth、MI_U32 u32MaxPicHeight参数分别设置1920和1280。
Q4:取流慢导致编码出现丢帧排查方法
查看venc proc信息:

发现:
-
getframe帧率是没问题的,但编码帧率只有23帧多。
-
只有1路1080p编码,性能是没问题的。
-
BlockCnt代表已接收到的不过由于当前还在处理上一张input picture从而rewind的input picture总数;这里BlockCnt已有一定数量堆积。
-
echo drop_out a d > /proc/mi_modules/mi_venc/mi_venc0 代表所有通道编码完数据直接丢弃,下此命令后帧率恢复正常。
综上可以确定是取流慢导致。后面确认到是在取流时有加sleep导致,没开高精度时钟,sleep时间会比较久,从而导致取流不及时,拿掉sleep测试ok。
Q5:退出编码时,调用MI_VENC_DestroyChn失败,日志有如下打印
[MI ERR ]: MI_VENC_IMPL_DestroyChn[12167]: dev0 chn0 unable to stop err:0xa0022012
从日志打印的error错误码0xa0022012,对照错误码,后面的三位“012” 表示设备忙。
这个错误的原因是MI_VENC_DestroyChn内部先调用MI_VENC_StopRecvPic,在调用MI_VENC_StopRecvPic就返回失败了,返回的错误码就是打印的错误码。
这种情况就是通道的资源还有被占用着,检查是否释放掉mma的内存(注意get数据后,一定要MI_VENC_ReleaseStream掉)。
Q6:修改编码帧率(u32SrcFrmRateDen)为15帧,实际在venc proc 查到的帧率对应不起来,这是什么原因呢?
venc本身是不做帧率控制,u32SrcFrmRateDen是用作码率控制的,帧率控制都是通过sys bind 进行控制,具体请查看MI SYS API的 MI_SYS_BindChnPort2 接口说明。
Q7:可以直接编码 argb8888 格式的数据吗?
不行,支持格式如下:
h26x:yuv420的nv12格式
jpeg:yuv420的nv12格式或 yuv422 的yuyv格式
Q8:vdec同时绑定venc和disp, disp进行显示,venc进行连续定时(比如2s)抓图时,前四张照片间隔时间非常短(不是2s)。
由于绑定vdec的关系,venc前几张直接从解码后的缓存队列拿到连续的几帧进行编码,venc也有缓存,导致还没get stream时,已经编码了几帧,所以这时候用venc来capture,拿到的jpeg是前面是连续的缓存数据,直到后面因为venc缓存满了之后,get stream一次,才能释放一个buffer,然后才能编一帧,后面间隔正常。这种情形下如需进行拍照,可以利用MI_VENC_StartRecvPicEx API设置为只接受一张图片的方法来实现。
stRecvParam.s32RecvPicNum = 1; s32Ret = MI_VENC_StartRecvPicEx(u32DevId, u8ChnId, &stRecvParam); if (s32Ret != MI_SUCCESS) { printf("MI_VENC_StartRecvPicEx err0x%x\n", s32Ret); return E_MI_ERR_FAILED; }
Q9:venc创建编码时调用MI_VENC_CreateDev()函数失败,返回exec function failed, error:a0022009
查看MI VENC API 的返回值a0022009表示:operation is not permitted
实际查看代码发现,创建了该dev之后,退出流程时只销毁了chn,并未销毁dev,导致再次创建dev时候报错,所以需要先调用MI_VENC_DestroyDev()。