1. 程式人生 > 實用技巧 >視訊編碼 通道配置 範例

視訊編碼 通道配置 範例

文件中的範例:

/*********************************
*函式功能:視訊編碼通道使能
*輸出引數:
*返回值:成功為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;
    }
}