视频编码 通道配置 范例

文档中的范例:

/*********************************
*函数功能:视频编码通道使能
*输出参数:
*返回值:成功为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
",s32Ret); 
        return HI_FAILURE; 
    } 

    s32Ret = HI_MPI_VENC_StartRecvPic(VeChn);             //开启编码通道接收输入图像。
    if (s32Ret != HI_SUCCESS) 
    { 
        printf("HI_MPI_VENC_StartRecvPic err 0x%x
",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
", 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
", 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!!!
");
        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!
",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!
",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!
", s32Ret);
        return HI_FAILURE;
    }
}
原文地址:https://www.cnblogs.com/qifeng1024/p/13479449.html