視訊編碼 通道配置 範例
阿新 • • 發佈:2020-08-11
文件中的範例:
/********************************* *函式功能:視訊編碼通道使能 *輸出引數: *返回值:成功為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; } }