一、初始化系统参数
根据通道数和sensor型号,定义缓冲池单幅画面的大小以及整个缓冲池大小
二、初始化mmp系统
三、打开vi设备和通道进行捕捉
设置好sensor的型号,翻转,镜像宽动态等信息
1、mipi接口设置(打开sensor,填充sensor属性,操作sensor)
2、配置sensor和isp(执行sensor_register_callback,注册3A,给isp分配内存,设置isp属性,设置完成后进行isp初始化)
3、运行isp线程
4、配置打开vi的dev (设置设备属性翻转、镜像、宽动态、白平衡等后打开设备)
5、配置打开vi的chn(设置好宽高,翻转后,打开设备通道)
四、打开vpss后绑定vi和vpss
设置vpssGrp属性后创建vpssGrp
启动vpssGrp
设置vichn和vpssGrp后进行绑定
五、开始编码流
打开编码通道
开始编码图片
绑定vpssGrp和vencchn
六、编码流处理
七、退出程序
VI模块包含:1和sensor对接的部分,常用sensor接口MIPI、LVDS、DC;2 ISP;3 VI dev(采集图像的硬件单元)和channel(通道)
SAMPLE_VENC_1080P_CLASSIC(HI_VOID)
/********************************
step 1: init sys variable
********************************/
SAMPLE_COMM_VI_GetSizeBySensor(&enSize[0]); //通过获取sensor型号,给ensize[0]赋值
·if (PIC_HD720 == enSize[0])
{
enSize[1] = PIC_VGA;
enSize[2] = PIC_QVGA;
s32ChnNum = 3;
}//根据enSize[0],给enSize[1] enSize[2]赋值
stVbConf.u32MaxPoolCnt = 128;//定义缓冲池最大个数
/*video buffer*/
if(s32ChnNum >= 1)
{
u32BlkSize = SAMPLE_COMM_SYS_CalcPicVbBlkSize(gs_enNorm,\
enSize[0], SAMPLE_PIXEL_FORMAT, SAMPLE_SYS_ALIGN_WIDTH); //根据画面像素PIC_HD720和像素格式YUV420,加上头文件,统计一幅画面占的空间大小
stVbConf.astCommPool[0].u32BlkSize = u32BlkSize;//将一幅的大小填入缓冲池设置大小
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;
}
/******************************************
step 2: mpp system init.
******************************************/
s32Ret = SAMPLE_COMM_SYS_Init(&stVbConf);//该函数执行了以下函数,函数内部未开放
( HI_MPI_SYS_Exit();
HI_MPI_VB_Exit();
HI_MPI_VB_SetConf;
HI_MPI_VB_Init;
HI_MPI_SYS_SetConf;
HI_MPI_SYS_Init;
)
/******************************************
step 3: start vi dev & chn to capture
***************************************
stViConfig.enViMode = SENSOR_TYPE; //sensor型号
stViConfig.enRotate = ROTATE_NONE; //翻转
stViConfig.enNorm = VIDEO_ENCODING_MODE_AUTO;
stViConfig.enViChnSet = VI_CHN_SET_NORMAL;//镜像和轴转动
stViConfig.enWDRMode = WDR_MODE_NONE;//宽动态
s32Ret = SAMPLE_COMM_VI_StartVi(&stViConfig);
SAMPLE_COMM_VI_StartVi(&stViConfig)函数展开
s32Ret = SAMPLE_COMM_VI_StartIspAndVi(pstViConfig);
SAMPLE_COMM_VI_StartIspAndVi(pstViConfig); 展开分析
/******************************************
1: mipi configure(常用sensor接口MIPI、LVDS、DC)
******************************************/
s32Ret = SAMPLE_COMM_VI_StartMIPI(pstViConfig); //对sensor进行必要的初始化
s32Ret = SAMPLE_COMM_VI_SetMipiAttr(pstViConfig);
fd = open("/dev/hi_mipi", O_RDWR); //打开sensor
pstcomboDevAttr = &MIPI_CMOS3V3_ATTR; //填充sensor属性
ioctl(fd, HI_MIPI_SET_DEV_ATTR, pstcomboDevAttr) //应用操作驱动的函数
close(fd);
/******************************************
2: configure sensor and ISP (include WDR mode).
note: you can jump over this step, if you do not use Hi3516A interal isp.
******************************************/
s32Ret = SAMPLE_COMM_ISP_Init(pstViConfig->enWDRMode); //利用芯片内部的图像处理函数
s32Ret = sensor_register_callback(); //在sensor驱动文件中
s32Ret = HI_MPI_AE_Register(IspDev, &stLib); //注册AE单元,自动曝光
s32Ret = HI_MPI_AWB_Register(IspDev, &stLib); //注册AWB单元,自动白平衡
s32Ret = HI_MPI_AF_Register(IspDev, &stLib); //注册AF单元,自动对焦
s32Ret = HI_MPI_ISP_MemInit(IspDev); //给ISP单元分配必要的内存
s32Ret = HI_MPI_ISP_SetWDRMode(0, &stWdrMode); //设置宽动态属性
case APTINA_AR0130_DC_720P_30FPS: //根据不同的sensor设置
stPubAttr.enBayer = BAYER_GRBG;//BAYER_RGB格式
stPubAttr.f32FrameRate = 30; //帧率
stPubAttr.stWndRect.s32X = 0; //起始x轴
stPubAttr.stWndRect.s32Y = 0; //起始y轴
stPubAttr.stWndRect.u32Width = 1280; //宽度
stPubAttr.stWndRect.u32Height = 720; //高度
s32Ret = HI_MPI_ISP_SetPubAttr(IspDev, &stPubAttr); //将设置的属性写入到ISP内部
s32Ret = HI_MPI_ISP_Init(IspDev); //设置完成后,将ISP进行初始化
/******************************************
3: run isp thread
note: you can jump over this step, if you do not use Hi3516A interal isp.
******************************************/
s32Ret = SAMPLE_COMM_ISP_Run();
pthread_create(&gs_IspPid, 0, (void* (*)(void*))Test_ISP_Run, NULL)//创建一个线程
Test_ISP_Run //运行ISP
/******************************************************
4 : config & start vicap dev
******************************************************/
s32Ret = SAMPLE_COMM_VI_StartDev(ViDev, enViMode);
memcpy(&stViDevAttr,&DEV_ATTR_9M034_DC_720P_BASE,sizeof(stViDevAttr));//填充设备属性
HI_MPI_VI_SetDevAttr(ViDev, &stViDevAttr);//设置设备属性将翻转、镜像等信息真正写入到设备
HI_MPI_ISP_GetWDRMode(s32IspDev, &stWdrMode);//获取宽动态模式
HI_MPI_VI_SetWDRAttr(ViDev, &stWdrAttr);//设置白平衡属性
HI_MPI_VI_EnableDev(ViDev);//启动设备
/******************************************************
5: config & start vicap chn (max 1)
******************************************************/
stTargetSize.u32Width = stCapRect.u32Width;
stTargetSize.u32Height = stCapRect.u32Height;//设置宽和高
SAMPLE_COMM_VI_StartChn(ViChn, &stCapRect, &stTargetSize, pstViConfig);
HI_MPI_VI_SetChnAttr(ViChn, &stChnAttr);//设置chn属性
HI_MPI_VI_SetRotate(ViChn, enRotate); //设置翻转
HI_MPI_VI_EnableChn(ViChn); //打开硬件单元的channel
/******************************************
step 4: start vpss and vi bind vpss
******************************************/
SAMPLE_COMM_SYS_GetPicSize(gs_enNorm, enSize[0], &stSize);
if(s32ChnNum >= 1)
{
VpssGrp = 0;
stVpssGrpAttr.u32MaxW = stSize.u32Width;//设置vpssgrpattr属性
stVpssGrpAttr.u32MaxH = stSize.u32Height;
stVpssGrpAttr.bIeEn = HI_FALSE;
stVpssGrpAttr.bNrEn = HI_TRUE;
stVpssGrpAttr.bHistEn = HI_FALSE;
stVpssGrpAttr.bDciEn = HI_FALSE;
stVpssGrpAttr.enDieMode = VPSS_DIE_MODE_NODIE;
stVpssGrpAttr.enPixFmt = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
s32Ret = SAMPLE_COMM_VPSS_StartGroup(VpssGrp, &stVpssGrpAttr);
HI_MPI_VPSS_CreateGrp(VpssGrp, pstVpssGrpAttr);//创建vpssgroup
HI_MPI_VPSS_GetNRParam(VpssGrp, &unNrParam);//获取NRParam参数
HI_MPI_VPSS_SetNRParam(VpssGrp, &unNrParam);//设置NRaram参数
HI_MPI_VPSS_StartGrp(VpssGrp);//启动vpssgrp
SAMPLE_COMM_VI_BindVpss(stViConfig.enViMode);//绑定VI和vpss
SAMPLE_COMM_VI_Mode2Param(enViMode, &stViParam);//设置dev和chn的数量和间隔
stSrcChn.enModId = HI_ID_VIU;
stSrcChn.s32DevId = 0;
stSrcChn.s32ChnId = ViChn;
stDestChn.enModId = HI_ID_VPSS;
stDestChn.s32DevId = VpssGrp;
stDestChn.s32ChnId = 0;
s32Ret = HI_MPI_SYS_Bind(&stSrcChn, &stDestChn);//将设置好的src和des进行绑定
VpssChn = 0;
stVpssChnMode.enChnMode = VPSS_CHN_MODE_USER;
stVpssChnMode.bDouble = HI_FALSE;
stVpssChnMode.enPixelFormat = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
stVpssChnMode.u32Width = stSize.u32Width;
stVpssChnMode.u32Height = stSize.u32Height;
stVpssChnMode.enCompressMode = COMPRESS_MODE_SEG;
memset(&stVpssChnAttr, 0, sizeof(stVpssChnAttr));
stVpssChnAttr.s32SrcFrameRate = -1;
stVpssChnAttr.s32DstFrameRate = -1;
s32Ret = SAMPLE_COMM_VPSS_EnableChn(VpssGrp, VpssChn, &stVpssChnAttr, &stVpssChnMode, HI_NULL);//分别填充好vpsschnmod和vpsschnattr后启动vpsschn
HI_MPI_VPSS_SetChnAttr(VpssGrp, VpssChn, pstVpssChnAttr);//将填充的chnattr进行设置
HI_MPI_VPSS_SetChnMode(VpssGrp, VpssChn, pstVpssChnMode);//将填充的chnmod进行设置
HI_MPI_VPSS_EnableChn(VpssGrp, VpssChn);//设置完成启动vpsschn
if(s32ChnNum >= 2)
if(s32ChnNum >= 3)
//后面两个跟第一个在同一个group下,只需要填充spsschnmod和vpsschnattr后启动vpsschn即可
.
.
.
}
/******************************************
step 5: start stream venc
******************************************/
/*** enSize[0] **/
if(s32ChnNum >= 1)
{
VpssGrp = 0;
VpssChn = 0;
VencChn = 0;
s32Ret = SAMPLE_COMM_VENC_Start(VencChn, enPayLoad[0],gs_enNorm, enSize[0], enRcMode,u32Profile);
HI_MPI_VENC_CreateChn(VencChn, &stVencChnAttr);
HI_MPI_VENC_StartRecvPic(VencChn);//Start Recv Venc Pictures
SAMPLE_COMM_VENC_BindVpss(VencChn, VpssGrp, VpssChn);//绑定vpsschn和vencchn
stSrcChn.enModId = HI_ID_VPSS;
stSrcChn.s32DevId = VpssGrp;
stSrcChn.s32ChnId = VpssChn;
stDestChn.enModId = HI_ID_VENC;
stDestChn.s32DevId = 0;
stDestChn.s32ChnId = VeChn;
s32Ret = HI_MPI_SYS_Bind(&stSrcChn, &stDestChn);
/*** enSize[1] **/
/*** enSize[2] **/
...
..
/******************************************
step 6: stream venc process -- get stream, then save it to file.
******************************************/
s32Ret = SAMPLE_COMM_VENC_StartGetStream(s32ChnNum);
/******************************************
step 7: exit process
******************************************/
SAMPLE_COMM_VENC_StopGetStream();