海思3559的stride与TCP的SIGPIPE

目录

图像宽度

stride的概念

3559的stride一些要求

配置实践

通道创建

编码帧创建

错误配置

图像的扩展

VPSS扩展

内存拷贝扩展

DMA逐行拷贝

编码耗时

耗时优化

总结

SIGPIPE


图像宽度

|-----------|---|---|---|---|---|
| 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服务端关闭,客户端程序直接闪退了,啥现象也没有。

往上同类型案例也比较多,例如:

(98 封私信 / 80 条消息) 我的服务程序被 SIGPIPE 信号给搞崩了! - 知乎

深入解析Linux SIGPIPE信号:网络编程中的沉默杀手-CSDN博客