概述
1.
Hi35xx芯片自带硬件的移动侦测功能,要实现需要找到对应接口及配置相关通道属性。
2.
找到“..._SDK_V1.0.4.0mppsamplecommonsample_comm_vda.c",查看移动侦测的实现过程。
3.应用到嵌入式设备中
①.封装接口,调用sample_comm_vda.c文件里的函数。
int vda_md(VI_CHN ViChn_Md)
{
int s32Ret;
本例,ViChn_Md参数是设置绑定的输入通道为物理输入,通道号为24
VDA_CHN VdaChn_Md = 0;设置对应的vda通道为0.
SIZE_S stSize;
//vi通道实际是1080p的,此处输入是720p。实际移动侦测是等比缩放检测,不影响结果。
stSize.u32Width = 720;/设置vda通道的输入视频宽高:
stSize.u32Height = 576;
s32Ret = SAMPLE_COMM_VDA_MdStart(VdaChn_Md, ViChn_Md, &stSize);
if (SUCCESS != s32Ret)
{
("VDA Md Start failed!n");
return -1;
}
return 0;
}
②.修改sample_comm_vda.c文件里的函数,对应设备程序。
int SAMPLE_COMM_VDA_MdStart(VDA_CHN VdaChn, VI_CHN ViChn, SIZE_S *pstSize)
{
HI_S32 s32Ret = HI_SUCCESS;
VDA_CHN_ATTR_S stVdaChnAttr; //设置VDA通道的属性
MPP_CHN_S stSrcChn, stDestChn;
if (VDA_MAX_WIDTH < pstSize->u32Width || VDA_MAX_HEIGHT < pstSize->u32Height)
{
("Picture size invaild!n");
return -1;
}
/* step 1 create vda channel */
stVdaChnAttr.enWorkMode = VDA_WORK_MODE_MD;//设置工作模式为md
stVdaChnAttr.u32Width = pstSize->u32Width; 通道宽度,传递的参数值是720
stVdaChnAttr.u32Height = pstSize->u32Height; 通道高度,传递的参数值是576
设置移动侦测属性结构体
stVdaChnAttr.unAttr.stMdAttr.enVdaAlg = VDA_ALG_REF; //VDA算法采样帧差法
stVdaChnAttr.unAttr.stMdAttr.enMbSize = VDA_MB_16PIXEL;//宏块大小,两种16*16和8*8单位像素。
stVdaChnAttr.unAttr.stMdAttr.enMbSadBits = VDA_MB_SAD_8BIT;//SAD输出精度
stVdaChnAttr.unAttr.stMdAttr.enRefMode = VDA_REF_MODE_DYNAMIC;
stVdaChnAttr.unAttr.stMdAttr.u32MdBufNum = 8;
stVdaChnAttr.unAttr.stMdAttr.u32VdaIntvl = 4; //侦测间隔以帧为单位
stVdaChnAttr.unAttr.stMdAttr.u32BgUpSrcWgt = 128;
stVdaChnAttr.unAttr.stMdAttr.u32SadTh = 2000; //SAD报警阈值,最大4080
stVdaChnAttr.unAttr.stMdAttr.u32ObjNumMax = 128; //运动区域最大输出个数
s32Ret = HI_MPI_VDA_CreateChn(VdaChn, &stVdaChnAttr);//创建视频侦测通道,这里主要设置好vda通道属性。
if(s32Ret != HI_SUCCESS)
{
("err!n");
return s32Ret;
}
/* step 2: vda chn bind vi chn */
stSrcChn.enModId = HI_ID_VIU;设置输入通道的类型,本次采用物理输入hdmi或vga
stSrcChn.s32ChnId = ViChn; ///VI物理输入通道号
stSrcChn.s32DevId = 0;VI 和 VDEC 作为数据源,是以通道为发送者,向其他模块发送数据,用户将设备号置为 0,SDK 不检查输入的设备号。详细查看绑定接口说明。
("stSrcChn.s32ChnId=%dn", stSrcChn.s32ChnId);
stDestChn.enModId = HI_ID_VDA;
stDestChn.s32ChnId = VdaChn;
stDestChn.s32DevId = 0;
s32Ret = HI_MPI_SYS_Bind(&stSrcChn, &stDestChn);//将vda通道和要进行md的通道进行绑定
if(s32Ret != HI_SUCCESS)
{
("err!n");
return s32Ret;
}
/* step 3: vda chn start recv picture */
s32Ret = HI_MPI_VDA_StartRecvPic(VdaChn);开始接受图像
if(s32Ret != HI_SUCCESS)
{
("err!n");
return s32Ret;
}
/* step 4: create thread to get result */
gs_stMdParam.bThreadStart = HI_TRUE;
gs_stMdParam.VdaChn = VdaChn;
("gs_stMdParam.bThreadStart=%dn", gs_stMdParam.bThreadStart);
("gs_stMdParam.VdaChn=%dn", gs_stMdParam.VdaChn);
pthread_create(&gs_VdaPid[SAMPLE_VDA_MD_CHN], 0, SAMPLE_COMM_VDA_MdGetResult, (void *)&gs_stMdParam);获取结果并对结果处理。
return HI_SUCCESS;
}
③.获取MD结果
void *SAMPLE_COMM_VDA_MdGetResult(void *pdata)
{
HI_S32 s32Ret;
VDA_CHN VdaChn;
VDA_DATA_S stVdaData;
VDA_MD_PARAM_S *pgs_stMdParam;
HI_S32 maxfd = 0;
FILE *fp = stdout;
HI_S32 VdaFd;
fd_set read_fds;
struct timeval TimeoutVal;
pgs_stMdParam = (VDA_MD_PARAM_S *)pdata;
VdaChn = pgs_stMdParam->VdaChn;
/* decide the stream file name, and open file to save stream */
/* Set Venc Fd. */
VdaFd = HI_MPI_VDA_GetFd(VdaChn);
if (VdaFd < 0)
{
printf("HI_MPI_VDA_GetFd failed with %#x!n", VdaFd);
return NULL;
}
if (maxfd <= VdaFd)
{
maxfd = VdaFd;
}
while (HI_TRUE == pgs_stMdParam->bThreadStart)
{
FD_ZERO(&read_fds);
FD_SET(VdaFd, &read_fds);
TimeoutVal.tv_sec = 2;
TimeoutVal.tv_usec = 0;
s32Ret = select(maxfd + 1, &read_fds, NULL, NULL, &TimeoutVal);
if (s32Ret < 0)
{
printf("select failed!n");
break;
}
else if (s32Ret == 0)
{
printf("get venc stream time out, exit threadn");
//break;
continue;
}
else
{
if (FD_ISSET(VdaFd, &read_fds))
{
/*******************************************************
step 2.3 : call mpi to get one-frame stream
*******************************************************/
s32Ret = HI_MPI_VDA_GetData(VdaChn, &stVdaData, HI_TRUE);获取视频侦测分析结果
if(s32Ret != HI_SUCCESS)
{
printf("HI_MPI_VDA_GetData failed with %#x!n", s32Ret);
return NULL;
}
/*******************************************************
*step 2.4 : save frame to file
*******************************************************/
//printf("