系统框图:
视频缓存池
视频缓存池主要向媒体业务提供大块物理内存管理功能,负责内存的分配和回收,充分发挥内存缓存池的作用,让物理内存资源在各个媒体处理模块中合理使用。
一组大小相同、物理地址连续的缓存块组成一个视频缓存池。
视频输入通道需要使用公共视频缓存池。所有的视频输入通道都可以从公共视频缓存池中获取视频缓存块用于保存采集的图像(如图中所示从公共视频缓存池 B 中获取视频缓存块 Bm)。由于视频输入通道不提供创建和销毁公共视频缓存池功能,因此,在系统初始化之前,必须为视频输入通道配置公共视频缓存池。
根据业务的不同,公共缓存池的数量、缓存块的大小和数量不同。 图中所示缓存块的生存期是指经过 VPSS 通道传给后续模块的情形(图 实线路径)。如果该缓存块完全没有经过 VPSS 通道传给其他模块,则将在 VPSS 模块处理后被放回公共缓存池(图虚线路径)。
B_CONF_S
【说明】
定义视频缓存池属性结构体。
【定义】
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;
【注意事项】
公共缓存池中每个缓存块的大小应根据当前图像像素格式以及图像是否压缩而有所不
同。如表所示:
视频帧内存 Size 计算表
'如表 2-2 所示,压缩指 256byte 段式压缩(目前仅支持此压缩模式)。另外,要求宽 16
对齐,高 2 对齐。压缩头 stride 为 16。压缩时,图像压缩头大小可以直接调用宏定义
VB_PIC_HEADER_SIZE 得到,图像总大小可以直接调用宏定义 VB_PIC_BLK_SIZE
得到,这两个宏定义皆位于 hi_define.h 头文件中。
由于海思的应用程序启动 MPP 业务前,必须完成 MPP 系统初始化工作。同理,应用程序退出MPP 业务后,也要完成 MPP 系统去初始化工作,释放资源。
初始化工作主要为:
各个模块之间的绑定
HI_S32 s32ret;
VB_CONF_S struVbConf;
MPP_SYS_CONF_S struSysConf;
memset(&struVbConf,0,sizeof(VB_CONF_S));
struVbConf.u32MaxPoolCnt = 64;
struVbConf.astCommPool[0].u32BlkSize = 1920*1088*2;
struVbConf.astCommPool[0].u32BlkCnt = 15;
memset(struVbConf.astCommPool[0].acMmzName,0,sizeof(struVbConf.astCommPool[0].acMmzName));
s32ret = HI_MPI_VB_SetConf(&struVbConf);
if (HI_SUCCESS != s32ret)
{
return s32ret;
}
s32ret = HI_MPI_VB_Init();
if (HI_SUCCESS != s32ret)
{
return s32ret;
}
struSysConf.u32AlignWidth = 16;
/* set config of mpp system*/
s32ret = HI_MPI_SYS_SetConf(&struSysConf);
if (HI_SUCCESS != s32ret)
{
printf("Set mpp sys config failed!\n");
return s32ret;
}
/* init system*/
s32ret = HI_MPI_SYS_Init();
if (HI_SUCCESS != s32ret)
{
printf("Mpi init failed!\n");
return s32ret;
}
/* ...... */
/* exit system*/
s32ret = HI_MPI_SYS_Exit();
if (HI_SUCCESS != s32ret)
{
printf("Mpi exit failed!\n");
return s32ret;
}
s32ret = HI_MPI_VB_Exit();
if (HI_SUCCESS != s32ret)
{
return s32ret;
}
只有在 MPP 整个系统处于未初始化状态,才可调用此函数配置 MPP 系统,否则会配置失败。
海思sdk中的例子:
//为了简单点,编码类型就选择PT_H264,图片大小就选择PIC_HD720,通道也只用1路s32ChnNum=1
PAYLOAD_TYPE_E enPayLoad=PT_H264;//264编码
PIC_SIZE_E enSize=PIC_HD720;//摄像头拍摄图片的大小,这里只用720P
HI_S32 s32ChnNum=1;//支持一路摄像
HI_S32 s32Ret=HI_FAILURE;
/******************************************
mpp system init.
******************************************/
HI_MPI_SYS_Exit();
HI_MPI_VB_Exit();
VB_CONF_S stVbConf;//缓存池参数结构体
HI_U32 u32BlkSize;//一张图片占多少字节
memset(&stVbConf,0,sizeof(VB_CONF_S));
//根据制式,图片大小,图片格式及对齐方式确定图片缓存大小
//这里用NTSC,720P,YUV420,64字节对齐
u32BlkSize=SAMPLE_COMM_SYS_CalcPicVbBlkSize(gs_enNorm,enSize, PIXEL_FORMAT_YUV_SEMIPLANAR_420, \
SAMPLE_SYS_ALIGN_WIDTH);
printf("u32BlkSize=%d\n",u32BlkSize);
stVbConf.u32MaxPoolCnt = 128;//用默认值,3518默认是128
stVbConf.astCommPool[0].u32BlkSize = u32BlkSize;//(宽+压缩头 stride) * 高 * 1.5 参考MPP手册94
stVbConf.astCommPool[0].u32BlkCnt = g_u32BlkCnt; //4个缓冲块
//设置缓冲池
HI_MPI_SYS_Exit();
HI_MPI_VB_Exit();
s32Ret = HI_MPI_VB_SetConf(&stVbConf);//设置 MPP 视频缓存池属性
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VB_SetConf failed!\n");
return HI_FAILURE;
}
s32Ret = HI_MPI_VB_Init();//初始化 MPP 视频缓存池
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VB_Init failed!\n");
return HI_FAILURE;
}
//设置系统属性
MPP_SYS_CONF_S stSysConf = {0};
HI_S32 s32Ret = HI_FAILURE;
stSysConf.u32AlignWidth = SAMPLE_SYS_ALIGN_WIDTH; //64
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;
}