视频编码 通道配置 范例
文档中的范例:
/********************************* *函数功能:视频编码通道使能 *输出参数: *返回值:成功为0 失败非0 *********************************/ HI_S32 StartVenc(HI_VOID) { HI_S32 s32Ret; //返回值 VI_CHN ViChn = 0; VENC_CHN VeChn = 0; VENC_CHN_ATTR_S stAttr; MPP_CHN_S stSrcChn, stDestChn; /* set h264 chnnel video encode attribute */ //编码器属性 stAttr.stVeAttr.enType = PT_H264; //编码协议类型 stAttr.stVeAttr.stAttrH264e.u32PicWidth = u32PicWidth; stAttr.stVeAttr.stAttrH264e.u32PicHeight = u32PicHeigh; stAttr.stVeAttr.stAttrH264e.u32MaxPicWidth = u32MaxPicWidth; stAttr.stVeAttr.stAttrH264e.u32MaxPicHeight = u32MaxPicHeigh; stAttr.stVeAttr.stAttrH264e.u32Profile = 2; //…… // omit other video encode assignments here. /* set h264 chnnel rate control attribute */ //码率控制器属性 stAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR ; //RC模式 stAttr.stRcAttr.stAttrH264Cbr.u32BitRate = 10*1024; //平均bitrate stAttr.stRcAttr.stAttrH264Cbr.fr32DstFrmRate = 30; //编码器输出帧率 stAttr.stRcAttr.stAttrH264Cbr.u32SrcFrmRate = 30; //VI输入帧率 stAttr.stRcAttr.stAttrH264Cbr.u32Gop = 30; //gop值 stAttr.stRcAttr.stAttrH264Cbr.u32FluctuateLevel = 1; //最大码率相对平均码率波动等级 stAttr.stRcAttr.stAttrH264Cbr.u32StatTime = 1; //CBR码率统计时间 stAttr.stGopAttr.enGopMode = VENC_GOPMODE_NORMALP; stAttr.stGopAttr.stNormalP = 1; //…… // omit other rate control assignments here. s32Ret = HI_MPI_VENC_CreateChn(VeChn, &stAttr); //创建编码通道。 if (HI_SUCCESS != s32Ret) { printf("HI_MPI_VENC_CreateChn err 0x%x\n",s32Ret); return HI_FAILURE; } s32Ret = HI_MPI_VENC_StartRecvPic(VeChn); //开启编码通道接收输入图像。 if (s32Ret != HI_SUCCESS) { printf("HI_MPI_VENC_StartRecvPic err 0x%x\n",s32Ret); return HI_FAILURE; } //…… // omit other code here. return HI_SUCCESS; }
/********************************* *函数功能:视频编码参数设置 *输出参数: *返回值:成功为0 失败非0 *********************************/ HI_S32 SetRcParam(HI_VOID) { HI_S32 s32Ret = HI_FAILURE; //返回值 VENC_RC_PARAM_S stVencRcPara; VENC_CHN VeChnId = 0; //通道号 //...omit other thing s32Ret = HI_MPI_VENC_GetRcParam(VeChnId, &stVencRcPara); //获取编码通道码率控制器的高级参数 if (HI_SUCCESS != s32Ret) { printf("HI_MPI_VENC_GetRcParam err 0x%x\n", s32Ret); return HI_FAILURE; } stVencRcPara.stParamH264Cbr.enSuperFrmMode = SUPERFRM_DISCARD; s32Ret = HI_MPI_VENC_SetRcParam(VeChnId, &stVencRcPara); //设置编码通道码率控制器的高级参数 if (HI_SUCCESS != s32Ret) { printf("HI_MPI_VENC_SetRcParam err 0x%x\n", s32Ret); return HI_FAILURE; } //...omit other thing return HI_SUCCESS; }
实例:
HI_S32 venc_create_chn(VENC_CHN VencChn, VIDEO_NORM_E enNorm, RC_E enRcMode, int stream_type) { HI_S32 s32Ret; HI_U32 frame_rate; VENC_CHN_ATTR_S stVencChnAttr; VENC_ATTR_H264_S stH264Attr; VENC_ATTR_H265_S stH265Attr; VENC_ATTR_H265_AVBR_S stH265AVbr; VENC_ATTR_H265_CBR_S stH265Cbr; //add by yqf 2018.3.28 VENC_GOP_ATTR_S stGopAttr; SIZE_S stPicSize; VENC_RC_PARAM_S venc_rc_param; unsigned char local_channel = 0; local_channel = local_chan_index(VencChn); if(VencChn < vi_chn_num || VencChn == vi_chn_num * 2) { frame_rate = 15; } else { frame_rate = 8; //12 } if(VencChn >= vi_chn_num) { stPicSize.u32Width = 352; //480; stPicSize.u32Height = 240; //384; } else { /*if(major_stream[local_channel].width == 2592) { stPicSize.u32Width = 2560;//2592; stPicSize.u32Height = 1944;//1944; }*/ if(Simulate_IP_mixture_mode) { stPicSize.u32Width = 1920;//2560; //huangwj add 2560 stPicSize.u32Height = 1080;//1816; //1944; } else { stPicSize.u32Width = major_stream[local_channel].width; stPicSize.u32Height= major_stream[local_channel].height; } //stPicSize.u32Height= major_stream[local_channel].height; } if(VencChn < vi_chn_num) { /* if(Simulate_IP_mixture_mode) { stH265Attr.u32MaxPicWidth = 2560;//2592; //huangwj add 2560 stH265Attr.u32MaxPicHeight = 1816; //1944; } else*/ { stH265Attr.u32MaxPicWidth = 1920; //huangwj add 2560 stH265Attr.u32MaxPicHeight = 1080; //1944; } } else { stH265Attr.u32MaxPicWidth = 352; //480; stH265Attr.u32MaxPicHeight = 240; //384; } // stH265Attr.u32MaxPicWidth = stPicSize.u32Width; // stH265Attr.u32MaxPicHeight = stPicSize.u32Height; stH265Attr.u32PicWidth = stPicSize.u32Width; stH265Attr.u32PicHeight = stPicSize.u32Height; // stH265Attr.u32BufSize = stPicSize.u32Width * stPicSize.u32Height; stH265Attr.u32BufSize = stH265Attr.u32MaxPicWidth * stH265Attr.u32MaxPicHeight * 3/4; stH265Attr.u32Profile = 0;/*0: baseline; 1:MP; 2:HP */ stH265Attr.bByFrame = HI_TRUE; memcpy(&stVencChnAttr.stVeAttr.stAttrH265e, &stH265Attr, sizeof(VENC_ATTR_H265_S)); //目前对于3531d,3521D系列的DVR来说,本地码流均采用H265编码,变码率配置 stVencChnAttr.stVeAttr.enType = PT_H265; if(RC_CBR == enRcMode) //对应普通模式使用,呼吸效应会小很多 { stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H265CBR; stH265Cbr.u32Gop = 44; //30; stH265Cbr.u32StatTime = 4; //1; stH265Cbr.u32SrcFrmRate = 15; //30; stH265Cbr.fr32DstFrmRate = frame_rate; if(stream_type <= 0) { stH265Cbr.u32BitRate = 192; } else { stH265Cbr.u32BitRate = 768; //1080P } stH265Cbr.u32FluctuateLevel = 1; memcpy(&stVencChnAttr.stRcAttr.stAttrH265Cbr, &stH265Cbr, sizeof(VENC_ATTR_H265_CBR_S)); } else if (RC_FIXQP == enRcMode) { } else if (RC_VBR == enRcMode) { } else if (RC_AVBR == enRcMode) //对应SMART模式使用,暂时放弃此方案 { stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H265AVBR; stH265AVbr.u32Gop = 25; //30; //virtual I interval stH265AVbr.u32StatTime = 1; //40; stH265AVbr.u32SrcFrmRate = 30; stH265AVbr.fr32DstFrmRate = frame_rate; //目前暂时定义H265的最高码率为2048 if(stream_type <= 0) { stH265AVbr.u32MaxBitRate = 256; //子码流 } else { stH265AVbr.u32MaxBitRate = 1024; //主码流 } memcpy(&stVencChnAttr.stRcAttr.stAttrH265AVbr, &stH265AVbr, sizeof(VENC_ATTR_H265_AVBR_S)); } else { printf("choose the wrong venc type!!!\n"); return HI_FAILURE; } #if 0 //设置相关GOP的属性,目前设置当前的为SMART模式 考虑摄像头为固定状态 stGopAttr.enGopMode = VENC_GOPMODE_SMARTP; stGopAttr.stSmartP.s32BgQpDelta = 4; //7; stGopAttr.stSmartP.s32ViQpDelta = 2; stGopAttr.stSmartP.u32BgInterval = 100; //60; //25 * 40 ; // 统计时间为40秒 Gop为25 #else //对应普通模式使用 stGopAttr.enGopMode = VENC_GOPMODE_NORMALP; stGopAttr.stNormalP.s32IPQpDelta = 0; #endif memcpy(&stVencChnAttr.stGopAttr,&stGopAttr,sizeof(VENC_GOP_ATTR_S)); s32Ret = HI_MPI_VENC_CreateChn(VencChn, &stVencChnAttr); //创建编码通道。 if (HI_SUCCESS != s32Ret) { SDKPRINTF("HI_MPI_VENC_CreateChn [%d] faild with %#x!\n",VencChn, s32Ret); return s32Ret; } /////////// add by yqf 2018.4.16 省码率处理 /////////// s32Ret =HI_MPI_VENC_GetRcParam(VencChn,&venc_rc_param); //获取通道码率控制高级参数。 if (HI_SUCCESS != s32Ret) { printf("HI_MPI_VENC_GetRcParam [%d] faild with %#x!\n",VencChn, s32Ret); } /////MaxBitrate*ChangePos*MinStillPercent 表示静止情况下的最小码率///// //venc_rc_param.u32RowQpDelta = 3; //默认值为2。码率越高,建议此值设的越低。 //venc_rc_param.stParamH265AVbr.s32ChangePos = 80; //开始调整Qp时的码率相对于最大码率的比例。 venc_rc_param.stParamH265AVbr.s32MinStillPercent = 20; //静止状态下目标码率的最小百分比 //venc_rc_param.stParamH265AVbr.u32MaxStillQP = 30; //用于钳位静止场景下的I帧最大QP值,防止码率调节的过低导致图像质量变差 venc_rc_param.stParamH265AVbr.u32MinQp = 20; //静止场景在编码压力小时QP主动钳位在MinQp,降低码率 s32Ret =HI_MPI_VENC_SetRcParam(VencChn,&venc_rc_param); //设置编码通道码率控制器的高级参数。 /////////////////////////////////////////////////////// s32Ret = HI_MPI_VENC_StartRecvPic(VencChn); //开启编码通道接收输入图像 if (HI_SUCCESS != s32Ret) { SDKPRINTF("HI_MPI_VENC_StartRecvPic faild with%#x!\n", s32Ret); return HI_FAILURE; } }