4 海思Hi3518E实例代码分析

海思媒体(mmp)处理平台架构
海思媒体处理平台的主要内部处理流程如图 1-2 所示,主要分为视频输入(VI)、视频处理(VPSS)、视频编码(VENC)、视频解码(VDEC)、视频输出(VO)、视频侦测分析(VDA)、音频输入(AI)、音频输出(AO)、音频编码(AENC)、音频解码(ADEC)、区域管理(REGION)等模块。主要的处理流程介绍如下:

VI 模块捕获视频图像,可对其做剪切、缩放等处理,并输出多路不同分辨率的图像数据。解码模块对编码后的视频码流进行解码,并将解析后的图像数据送 VPSS 进行图像处理或直接送 VO 显示。可对 H264/MPEG4/MPEG2 格式的视频码流进行解码。


VPSS 模块接收 VI 和解码模块发送过来的图像,可对图像进行去噪、图像增强、锐化等处理,并实现同源输出多路不同分辨率的图像数据用于编码、预览或抓拍。


编码模块接收 VI 捕获并经 VPSS 处理后输出的图像数据,可叠加用户通过 Region模块设置的 OSD 图像,然后按不同协议进行编码并输出相应码流。


VDA 模块接收 VI 的输出图像,并进行移动侦测和遮挡侦测,最后输出侦测分析结果。


VO 模块接收 VPSS 处理后的输出图像,可进行播放控制等处理,最后按用户配置的输出协议输出给外围视频设备。


AI 模块捕获音频数据,然后 AENC 模块支持按多种音频协议对其进行编码,最后输出音频码流。


用户从网络或外围存储设备获取的音频码流可直接送给 ADEC 模块, ADEC 支持解码多种不同的音频格式码流,解码后数据送给 AO 模块即可播放声音。


下面的代码我把不会用到的代码删除了,这样更简洁,为了简介,下面我只做一路输出,只选择APTINA_AR0130_DC_720P_30FPS为视频输出格式

int main(int argc, char *argv[])
{
    HI_S32 s32Ret;
    signal(SIGINT, SAMPLE_VENC_HandleSig);//ctrl+c,delete
    signal(SIGTERM, SAMPLE_VENC_HandleSig);//ctrl+\

    /* H.264@1080p@30fps+H.265@1080p@30fps+H.264@D1@30fps */
    s32Ret = SAMPLE_VENC_1080P_CLASSIC();

    if (HI_SUCCESS == s32Ret)
        printf("program exit normally!\n");
    else
        printf("program exit abnormally!\n");
    exit(s32Ret);
}

SAMPLE_VENC_HandleSig:主要做系统的回收,ISP线程的退出,ISP的停止

SAMPLE_VENC_1080P_CLASSIC:H.264@1080p@30fps+H.265@1080p@30fps+H.264@D1@30fps这几种情况的处理

由于海思的应用程序启动 MPP 业务前,必须完成 MPP 系统初始化工作。同理,应用程序退出MPP 业务后,也要完成 MPP 系统去初始化工作,释放资源。

初始化工作主要为:

视频缓存池的设置

各个模块之间的绑定

设置VI/VPSS 离/在线模式

可以参考:https://blog.csdn.net/qq_40732350/article/details/87970605

在H264_Venc()函数里先去初始化MPI系统,然后根据摄像头设置参数。我这里是AR030摄像头,其拍摄图片大小为720P,编码为H264,为了简单只输出一路。在初始化MPI系统时要计算视频缓存池VB_CONF_S的大小,然后填充VB_CONF_S结构体。填充完VB_CONF_S结构体后再用HI_MPI_VB_SetConf设置,最后初始化视频视频缓存池HI_MPI_VB_Init。这里注意的是基本上每个函数调用后都会判断返回值并作出错出理,后面很多函数也是这样处理的,这样利于程序排错
 

第一步:初始化视频缓冲池和系统MPP初始化

	//为了简单点,编码类型就选择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;
    }	

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章