目录
图像宽度
|-----------|---|---|---|---|---|
| MIN_ALIGN | 2 | 2 | 2 | 2 | 2 |
对齐最小为2个字节。在创建VENC通道时,宽度为2的倍数即可。那么在采用VENC模块进行编码时,是否分辨率的宽度为2的倍数就可以高枕无忧了呢?

stride的概念

理解为硬件每次获取的图像像素数吧,类似于人走一步,例如上图,假设图像宽度是1910,而stride 为1920 。通过stride设置为某些数值的倍数,例如16、32、64的倍数。
至于为啥会设置为16、32、64的倍数,那必定和性能、内存访问相关了,具体就不展开了。
3559的stride一些要求
表10-3 Hi3559AV100 VGS 硬件规格
|------------------|---------------------------------------------------------------------------------------------------------------------------------|
| 输入图像分辨率及对齐要求 | 1、最小支持: 32x32。2、最大支持: 16384x16384。3、宽度和高度均为 2 像素对齐,非压缩 stride 16 对齐,压缩stride 32 对齐。注意:如果宽度的缩小倍数大于 15 倍时,要求输入图像的宽度 4 像素对齐, 高度同理。 |
配置实践
以分辨率4760x1000为例,
通道创建
这里为了16对齐,将最大width配置为4768;而实际宽度配置为图像的宽度即4760
stVencChnAttr.stVencAttr.enType = enType;
stVencChnAttr.stVencAttr.u32MaxPicWidth = stPicSize.u32Width; 这里是4768
stVencChnAttr.stVencAttr.u32MaxPicHeight = stPicSize.u32Height;
stVencChnAttr.stVencAttr.u32PicWidth = stPicSize.u32Width-8;/*the picture width*/ 这里是4760
stVencChnAttr.stVencAttr.u32PicHeight = stPicSize.u32Height;/*the picture height*/
stVencChnAttr.stVencAttr.u32BufSize = stPicSize.u32Width * stPicSize.u32Height * 2;/*stream buffer size*/
stVencChnAttr.stVencAttr.u32Profile = u32Profile;
stVencChnAttr.stVencAttr.bByFrame = HI_TRUE;/*get stream mode is slice mode or frame mode?*/
编码帧创建
stFrmInfo.stVFrame.u32Width = g_u32PicWidth-8; //这里配置为4760
stFrmInfo.stVFrame.u32Height = g_u32PicHeigh;
stFrmInfo.stVFrame.u32Stride[0] = g_u32PicWidth; //这里配置为4768
通过上述两个配置,可以编码生成和原始图像一样的分辨率。
错误配置
1)假如通道创建时,设置的width为4768,而创建编码帧时width设置了 4760,则报如下错误:
<3>[ venc] [Func]:VencCheckVideoInfo [Line]:1595 [Info]:Venc 0 :Src pic is small,lost this frame,src(4760,1000),Venc(4768,1000).
2)假如通道创建时,设置的width为4760,而创建编码帧时width设置了 4768,则报如下错误
<3>[ vb] [Func]:VbSearchCommPoolBySize [Line]:979 [Info]:all blk size of vb pool (owner -1 ) is smaller than the actual size 18211200 required!
<1>[ venc] [Func]:VencSendPic2Vgs [Line]:2209 [Info]:get VB fail,for Venc 0 Vgs scale
<3>[ venc] [Func]:VencSendPic [Line]:1285 [Info]:Venc:0 send pic to vgs failed!,u64PTS=6076095458
通过此处我们可以得知:配置的尺寸不匹配时,3559 会自动进入vgs scale流程。
图像的扩展
由于原始进入到3559的图像是4760*1000的,为了能正常编码,满足编码器的要求,需要将stride扩展到4768,这就需要在每行扩展出8个字节。
VPSS扩展
报错:
<3>[ vpss] [Func]:VPSS_DRV_CheckImageAttr [Line]:5100 [Info]:[grp0]:pic Stride[0](4760) Stride[1](0) Stride[2](0) should be aligned to 16!!
很悲催,VPSS输入的stride也需要16字节对齐。
内存拷贝扩展
将图像内存映射成带cache的,然后memcpy,耗时15ms。即每帧编码的整个流程增加了15ms。
DMA逐行拷贝
PCIE 2.0 X1 。整帧拷贝时,耗时43ms。而按行拷贝时,变为dma time: 54979.000000 us,增加了11ms。
编码耗时
23ms
耗时优化
PCIE3.0 X2 。 在整帧DMA 时,数据带宽大概为理论的78%左右,因而整帧耗时大概12ms,而按行传输,时间大概要23ms上下了,不过这个也满足要求。
总结
在用海思 、RK芯片处理图像时,图像的stride 必须考虑清楚,否则引入新的操作流程就会带来新的延时。
RK芯片,这个有介绍:
嵌入式图像处理中的 Stride 原理与 Rockchip 平台对齐实践-CSDN博客
SIGPIPE
现象:客户要求用TCP推流, 在测试用TCP客户端发送推流数据时,将TCP服务端关闭,客户端程序直接闪退了,啥现象也没有。
往上同类型案例也比较多,例如: