欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 艺术 > Hi3518E官方录像例程流程分析(二)

Hi3518E官方录像例程流程分析(二)

2025/4/16 23:19:11 来源:https://blog.csdn.net/2401_86112944/article/details/147227514  浏览:    关键词:Hi3518E官方录像例程流程分析(二)

文章目录

  • 变量定义
  • step 1:初始化系统变量,根据应用和需求计算参数
    • SAMPLE_COMM_VI_GetSizeBySensor(&enSize[0]);
    • SAMPLE_COMM_SYS_CalcPicVbBlkSize()
      • SAMPLE_COMM_SYS_GetPicSize

源码地址 + 文档资料 – 提取码: chmr

本专栏分析的是mpp\venc\sample\sample_venc.c

变量定义

	//一些初始化用到的参数//这里默认三路通道都先默认输出H264PAYLOAD_TYPE_E enPayLoad[3]= {PT_H264, PT_H264,PT_H264};//默认三路通道输出的视频格式PIC_SIZE_E enSize[3] = {PIC_HD1080, PIC_VGA,PIC_QVGA};HI_U32 u32Profile = 0;//视频缓冲池设置
//这个缓冲池非常重要,缓冲池的指针会随着
//VI->VPSS->VENC一直传递VB_CONF_S stVbConf;SAMPLE_VI_CONFIG_S stViConfig = {0};//VPSS的Grp后面会讲到VPSS_GRP VpssGrp;VPSS_CHN VpssChn;VPSS_GRP_ATTR_S stVpssGrpAttr;VPSS_CHN_ATTR_S stVpssChnAttr;VPSS_CHN_MODE_S stVpssChnMode;//编码用到的变量VENC_CHN VencChn;SAMPLE_RC_E enRcMode= SAMPLE_RC_CBR;//通道数,也会在后面章节提到HI_S32 s32ChnNum=0;HI_S32 s32Ret = HI_SUCCESS;HI_U32 u32BlkSize;SIZE_S stSize;char c;

缓存池结构体
在这里插入图片描述
u32MaxPoolCnt 记录的是缓存池有多少个,即上一专栏里的A、B…
u32BlkSize 记录的是缓存池里的块的大小,即A1、A2…Am
u32BlkCnt 则是Am的m的值,即有多少块
后面的name是便于调试的
在这里插入图片描述

step 1:初始化系统变量,根据应用和需求计算参数

    /******************************************step  1: init sys variable, Calculate parameters based on application and requirements******************************************/memset(&stVbConf,0,sizeof(VB_CONF_S));//Select the sensor to be used//AR0130 -- PIC_HD720SAMPLE_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 hi3518ev201s32ChnNum = 1;
#endifs32ChnNum = 1;printf("s32ChnNum = %d\n",s32ChnNum);//Customize the size of the buffer poolstVbConf.u32MaxPoolCnt = 128;//D:Hi3518E V200R001C01SPC030\01.software\board\document_cn\HiMPP IPC V2.0 媒体处理软件开发参考/*video buffer*///Each different image uses different memory,//To ensure that the blocks in each buffer pool are the same size//so the size of the buffer pool is also different. such as A(pool) -- 720, B(pool) -- 1080if(s32ChnNum >= 1){				//ensize[0] -> pixel Size 720 \ 1080 \......u32BlkSize = SAMPLE_COMM_SYS_CalcPicVbBlkSize(gs_enNorm,\enSize[0], SAMPLE_PIXEL_FORMAT, SAMPLE_SYS_ALIGN_WIDTH);//ALIGN_WIDTH -> Pixel alignmentstVbConf.astCommPool[0].u32BlkSize = u32BlkSize;//Blockcnt defines it by itself, but it should also consider whether the memory can be placed,// and it cannot fill the memory at one time.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){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(&enSize[0]);

这主要就是通过传感器来选择输出的格式
我用到的传感器是
APTINA_AR0130_DC_720P_30FPS:
所以会命中penSize = PIC_HD720;

    switch (enMode){case APTINA_AR0130_DC_720P_30FPS:case APTINA_9M034_DC_720P_30FPS:case SONY_IMX222_DC_720P_30FPS:case OMNIVISION_OV9712_DC_720P_30FPS:case OMNIVISION_OV9732_DC_720P_30FPS:case OMNIVISION_OV9750_MIPI_720P_30FPS:case OMNIVISION_OV9752_MIPI_720P_30FPS:*penSize = PIC_HD720;break;case APTINA_AR0230_HISPI_1080P_30FPS:case SONY_IMX222_DC_1080P_30FPS:case PANASONIC_MN34222_MIPI_1080P_30FPS:case OMNIVISION_OV2718_MIPI_1080P_25FPS:*penSize = PIC_HD1080;break;default:printf("not support this sensor\n");break;}

然后回到SAMPLE_VENC_1080P_CLASSIC
因为前面命中了PIC_HD720,所以回进入这个分支

   else if (PIC_HD720 == enSize[0]){enSize[1] = PIC_VGA;			enSize[2] = PIC_QVGA;//通道数为三,这个很重非要!!!会贯穿全文s32ChnNum = 3;}

SAMPLE_COMM_SYS_CalcPicVbBlkSize()

因为s32ChnNum = 3,所以下面三个if都会命中,由于内容都一样,所以我们只进入第一个if里的SAMPLE_COMM_SYS_CalcPicVbBlkSize函数

	if(s32ChnNum >= 1){				//ensize[0] -> pixel Size 720 \ 1080 \......u32BlkSize = SAMPLE_COMM_SYS_CalcPicVbBlkSize(gs_enNorm,\enSize[0], SAMPLE_PIXEL_FORMAT, SAMPLE_SYS_ALIGN_WIDTH);//ALIGN_WIDTH -> Pixel alignmentstVbConf.astCommPool[0].u32BlkSize = u32BlkSize;//Blockcnt defines it by itself, but it should also consider whether the memory can be placed,// and it cannot fill the memory at one time.stVbConf.astCommPool[0].u32BlkCnt = g_u32BlkCnt;}

通过声明看看参数

SAMPLE_COMM_SYS_CalcPicVbBlkSize(VIDEO_NORM_E enNorm, PIC_SIZE_E enPicSize, PIXEL_FORMAT_E enPixFmt, HI_U32 u32AlignWidth);

第一个是要选择的视频标准格式,这个在main顶上有定义一个全局变量

VIDEO_NORM_E gs_enNorm = VIDEO_ENCODING_MODE_NTSC;

PAL 和 NTSC 是两种不同的视频标准格式,主要用于电视广播和视频录制等领域

typedef enum hiVIDEO_NORM_E
{VIDEO_ENCODING_MODE_PAL = 0,VIDEO_ENCODING_MODE_NTSC,VIDEO_ENCODING_MODE_AUTO,VIDEO_ENCODING_MODE_BUTT
} VIDEO_NORM_E;

ensize[0] 就是视频像素 pixel Size 720 \ 1080 …
这个在上面函数已经被填充过了
SAMPLE_PIXEL_FORMAT : YUV420,因为我的AR0131只支持YUV420格式
SAMPLE_SYS_ALIGN_WIDTH:对齐方式

然后就进函数看看

    HI_S32 s32Ret = HI_FAILURE;SIZE_S stSize;HI_U32 u32VbSize;HI_U32 u32HeaderSize;//Calculate the size of the images32Ret = SAMPLE_COMM_SYS_GetPicSize(enNorm, enPicSize, &stSize);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("get picture size[%d] failed!\n", enPicSize);return HI_FAILURE;}//format judgmentif (PIXEL_FORMAT_YUV_SEMIPLANAR_422 != enPixFmt && PIXEL_FORMAT_YUV_SEMIPLANAR_420 != enPixFmt){SAMPLE_PRT("pixel format[%d] input failed!\n", enPixFmt);return HI_FAILURE;}//Alignment judgmentif (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);//CEILING_2_POWER Rounding up after alignmentu32VbSize = (CEILING_2_POWER(stSize.u32Width, u32AlignWidth) * \CEILING_2_POWER(stSize.u32Height,u32AlignWidth) * \//422 is rich in color, 420 saves memory((PIXEL_FORMAT_YUV_SEMIPLANAR_422 == enPixFmt)?2:1.5));//422 -> 2, 420 -> 1.5//Leave room for headers to be added in the futureVB_PIC_HEADER_SIZE(stSize.u32Width, stSize.u32Height, enPixFmt, u32HeaderSize);u32VbSize += u32HeaderSize;
//Leave a margin when calculating in memory
// to avoid data expansion in subsequent processing and occupy the memory space of other datareturn u32VbSize;

SAMPLE_COMM_SYS_GetPicSize

首先是SAMPLE_COMM_SYS_GetPicSize,这个函数在后面也会被经常用到,就是获取图像大大小
我们是PIC_HD720自然会在里面命中这个

case PIC_HD720:   /* 1280 * 720 */pstSize->u32Width  = 1280;pstSize->u32Height = 720;

后面是一些判断不理他
然后是计算缓存池的块大小

    u32VbSize = (CEILING_2_POWER(stSize.u32Width, u32AlignWidth) * \CEILING_2_POWER(stSize.u32Height,u32AlignWidth) * \((PIXEL_FORMAT_YUV_SEMIPLANAR_422 == enPixFmt)?2:1.5));

CEILING_2_POWER

#define CEILING_2_POWER(x,a)     ( ((x) + ((a) - 1) ) & ( ~((a) - 1) ) )

就是图像大小对齐以后在向上取整

PIXEL_FORMAT_YUV_SEMIPLANAR_422 == enPixFmt)?2:1.5)

这个是422 * 2,420 * 1.5就没什么好说的了

给未来的数据头留够一定余量,避免等后面进行编码的时候数据膨胀吧别的数据空间霸占了

VB_PIC_HEADER_SIZE(stSize.u32Width, stSize.u32Height, enPixFmt, u32HeaderSize);

第一阶段结束

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词