海思3518E MPP初始化详解及blocksize的计算
为了兼容性的问题,海思为多个版本的3518e编写了sample
我们分析这一路
变量定义
这里有几个关键性的变量
playload数组中有3个成员,对应3个通道。编码尺寸也对应3个通道
typedef struct hiVB_CONF_S
{
HI_U32 u32MaxPoolCnt; /* max count of pools, (0,VB_MAX_POOLS] */
struct hiVB_CPOOL_S
{
HI_U32 u32BlkSize;
HI_U32 u32BlkCnt;
HI_CHAR acMmzName[MAX_MMZ_NAME_LEN];
}astCommPool[VB_MAX_COMM_POOLS];
} VB_CONF_S;
VB_CONF_S stVbConf;
这个结构体是视频缓冲池的相关属性
包括缓冲池的最大值、块的数量和大小等
step 1: init sys variable
/******************************************
step 1: init sys variable
******************************************/
memset(&stVbConf,0,sizeof(VB_CONF_S));
SAMPLE_COMM_VI_GetSizeBySensor(&enSize[0]);
if (PIC_HD1080 == enSize[0])
{
enSize[1] = PIC_VGA;
s32ChnNum = 2;
}
else if (PIC_HD720 == enSize[0])
{
enSize[1] = PIC_VGA;
enSize[2] = PIC_QVGA;
s32ChnNum = 3;
}
else
{
printf("not support this sensor\n");
return HI_FAILURE;
}
#ifdef hi3518ev201
s32ChnNum = 1;
#endif
printf("s32ChnNum = %d\n",s32ChnNum);
stVbConf.u32MaxPoolCnt = 128;//最大视频缓存池数量,根据内存大小给出的经验值
/*video buffer*/
if(s32ChnNum >= 1)//根据通道数量计算mpp结构体参数,填充视频缓存池结构体
{
//u32BlkSize为一帧图像所需要的大小,也就是块大小
u32BlkSize = SAMPLE_COMM_SYS_CalcPicVbBlkSize(gs_enNorm,\//第一个参数为扫描方式
enSize[0], SAMPLE_PIXEL_FORMAT, SAMPLE_SYS_ALIGN_WIDTH);//计算块大小,//传入分辨率格式,像素格式,对齐排布,用于像素取整//关键是把enSize[0]传进去,
stVbConf.astCommPool[0].u32BlkSize = u32BlkSize;//设置块大小 //从上面的得到enSize[0]为PIC_HD1080
stVbConf.astCommPool[0].u32BlkCnt = g_u32BlkCnt;//设置块数量
}
if(s32ChnNum >= 2)
{
u32BlkSize = SAMPLE_COMM_SYS_CalcPicVbBlkSize(gs_enNorm,\
enSize[1], SAMPLE_PIXEL_FORMAT, SAMPLE_SYS_ALIGN_WIDTH);
stVbConf.astCommPool[1].u32BlkSize = u32BlkSize;
stVbConf.astCommPool[1].u32BlkCnt =g_u32BlkCnt;
}
if(s32ChnNum >= 3)//3个通道对应三个视频缓存池,因为不同通道也就是不同分辨率,他们对应的码流不同
{
u32BlkSize = SAMPLE_COMM_SYS_CalcPicVbBlkSize(gs_enNorm,\
enSize[2], SAMPLE_PIXEL_FORMAT, SAMPLE_SYS_ALIGN_WIDTH);
stVbConf.astCommPool[2].u32BlkSize = u32BlkSize;
stVbConf.astCommPool[2].u32BlkCnt = g_u32BlkCnt;
}
首先初始化视频缓存池
接着调用SAMPLE_COMM_VI_GetSizeBySensor
,通过配置makefile传入的sensor类型进行图像尺寸及通道数的判断
由于我们使用的是AR0130
,于是走的是else。即三通道码流
一路主码流(原始的没有裁剪的,全功能版本),另外两路(在主码流的基础上经过裁剪缩放等操作简化而来,阉 割版本)为子码流,客户用手机看的话就用子码流看就行了,没必要看主码流,还可以省点网络带宽,还比较流畅。
裸流:开发过程中的半成品,把文件头一解析就知道这个文件的分辨率, mp4、rtsp等都可以查一下文件头来看。
裸流(h264)是没有这个文件头的。
怎么看sensor支持的图像大小?
720p 1280x720=92万像素至少要留点余量,100万像素以上
1080p 1920x1080 = 207万像素 至少sensor也要210万像素以上
为什么不同的码流要对应不同的pool呢?
因为不同的码流分辨率不一样,对应的blocksize的大小也就不一样
计算blocksize
最后根据不同通道不同分辨率,计算blocksize
调用了SAMPLE_COMM_SYS_CalcPicVbBlkSize
,传入
- 视频输入制式类型(图像的扫描方式,早期CRT显示用到,现在意义只有向前兼容)
- 编码尺寸
- 像素格式
- 像素对齐(根据像素排布进行向上取整对齐)
/******************************************************************************
* function : calculate VB Block size of picture.
******************************************************************************/
HI_U32 SAMPLE_COMM_SYS_CalcPicVbBlkSize(VIDEO_NORM_E enNorm, PIC_SIZE_E enPicSize, PIXEL_FORMAT_E enPixFmt, HI_U32 u32AlignWidth)
{
HI_S32 s32Ret = HI_FAILURE;
SIZE_S stSize;
HI_U32 u32VbSize;
HI_U32 u32HeaderSize;
s32Ret = SAMPLE_COMM_SYS_GetPicSize(enNorm, enPicSize, &stSize);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("get picture size[%d] failed!\n", enPicSize);
return HI_FAILURE;
}
if (PIXEL_FORMAT_YUV_SEMIPLANAR_422 != enPixFmt && PIXEL_FORMAT_YUV_SEMIPLANAR_420 != enPixFmt)
{
SAMPLE_PRT("pixel format[%d] input failed!\n", enPixFmt);
return HI_FAILURE;
}
if (16!=u32AlignWidth && 32!=u32AlignWidth && 64!=u32AlignWidth)
{
SAMPLE_PRT("system align width[%d] input failed!\n",\
u32AlignWidth);
return HI_FAILURE;
}
//SAMPLE_PRT("w:%d, u32AlignWidth:%d\n", CEILING_2_POWER(stSize.u32Width,u32AlignWidth), u32AlignWidth);
u32VbSize = (CEILING_2_POWER(stSize.u32Width, u32AlignWidth) * \
CEILING_2_POWER(stSize.u32Height,u32AlignWidth) * \
((PIXEL_FORMAT_YUV_SEMIPLANAR_422 == enPixFmt)?2:1.5));
VB_PIC_HEADER_SIZE(stSize.u32Width, stSize.u32Height, enPixFmt, u32HeaderSize);
u32VbSize += u32HeaderSize;
return u32VbSize;
}
SAMPLE_COMM_SYS_CalcPicVbBlkSize
中又调用了SAMPLE_COMM_SYS_GetPicSize
,用于计算图像大小
可以看到,在早期电视显示标准中,需要考虑制式,现在的数字显示就不需要。考虑兼容问题,于是这个sample就这样写了
接下来判断像素格式,这个sample只支持422和420
再考虑对齐,此sample只考虑16bit、32bit和64bit对齐,我们选用的是64字节对齐
最后就是计算blocksize的大小,宽x高x字节数,用了一个宏来计算宽和高CEILING_2_POWER
#define CEILING_2_POWER(x,a) ( ((x) + ((a) - 1) ) & ( ~((a) - 1) ) )
若输入15和2,即15和2对齐,输出16
若输入15和64,即15和64对齐,输出64
实际中,比如720p,代码中规定向64取整,即1280向上增加到64的倍数,即1280
如果是一个其他的数,如WVGA是854,和64向上取整,即896
每一个像素占多少字节,
yuv422
四个像素占8个字节,每个像素占2字节yuv420
四个像素占6个字节,每个像素占1.5个字节
宽x高x字节数就是blocksize
然后要留一些余量给后续操作做准备
为文件头留出余量后就计算完毕
以上,第一步计算mpp所需要的参数就计算好了
这些参数是根据应用需求进行核算的
但是此时系统还没有启动
于是进入第二步,进行初始化
step 2: mpp system init
第二步所有操作包在了一个函数里
/******************************************************************************
* function : vb init & MPI system init
******************************************************************************/
HI_S32 SAMPLE_COMM_SYS_Init(VB_CONF_S *pstVbConf)
{
MPP_SYS_CONF_S stSysConf = {0};
HI_S32 s32Ret = HI_FAILURE;
HI_MPI_SYS_Exit();
HI_MPI_VB_Exit();
if (NULL == pstVbConf)
{
SAMPLE_PRT("input parameter is null, it is invaild!\n");
return HI_FAILURE;
}
s32Ret = HI_MPI_VB_SetConf(pstVbConf);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VB_SetConf failed!\n");
return HI_FAILURE;
}
s32Ret = HI_MPI_VB_Init();
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VB_Init failed!\n");
return HI_FAILURE;
}
stSysConf.u32AlignWidth = SAMPLE_SYS_ALIGN_WIDTH;
s32Ret = HI_MPI_SYS_SetConf(&stSysConf);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_SYS_SetConf failed\n");
return HI_FAILURE;
}
s32Ret = HI_MPI_SYS_Init();
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_SYS_Init failed!\n");
return HI_FAILURE;
}
return HI_SUCCESS;
}
HI_MPI_SYS_Exit()
和HI_MPI_VB_Exit()
这两个是怕你之前的VB和SYS没处理干净,保险起见,打扫卫生的。需要注意,释放的时候是SYS在前,VB在后的(文档规定)
HI_MPI_VB_SetConf
和HI_MPI_VB_Init
是SDK中的函数
在定义好视频缓冲池后将结构体交给SDK进行处理,分配内存
只要把VB(缓冲池搞好了),SYS里面都是自动化的,海思封装的特别好,我们要操心的是VB的参数pstVbconf
- 分享
- 举报
-
浏览量:1461次2024-01-25 16:21:59
-
2024-01-11 15:44:19
-
浏览量:1007次2024-01-24 17:37:01
-
浏览量:928次2023-03-01 11:22:14
-
浏览量:1233次2024-02-22 15:52:02
-
浏览量:7116次2020-08-14 11:34:19
-
2023-06-12 14:35:32
-
浏览量:3630次2020-08-14 11:35:53
-
浏览量:3516次2020-07-30 11:57:30
-
浏览量:7440次2021-08-11 16:51:39
-
浏览量:986次2024-01-24 18:28:37
-
浏览量:1498次2023-12-29 16:51:41
-
2024-01-02 18:00:05
-
浏览量:10512次2020-08-03 14:27:03
-
浏览量:3575次2020-07-27 15:12:15
-
浏览量:574次2023-12-11 11:42:02
-
2020-08-13 17:36:37
-
浏览量:1489次2023-06-29 09:27:40
-
浏览量:4142次2020-08-14 11:25:29
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
Lixiaofeng
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明