功能 :openh264 码率控制框架中宏块级码率控制函数,根据是否启用GOM QP来决定如何设置宏块的QP值,以控制编码的质量和比特率。原理过程 : 函数参数: pEncCtx: 指向编码上下文的指针,包含编码过程中所需的全局信息。 pCurMb: 指向当前宏块的指针,宏块是视频编码的基本单位。 pSlice: 指向当前切片的指针,切片是一系列连续宏块的集合。  局部变量: pWelsSvcRc: 指向服务层码率控制结构的指针。 pSOverRc: 指向切片覆盖码率控制结构的指针。 pCurLayer: 指向当前解码质量层的指针。 kuiChromaQpIndexOffset: 色度QP索引偏移量,用于调整色度通道的量化参数。  主要逻辑: 首先,获取当前宏块的比特流位置,并更新到切片覆盖码率控制结构中。 如果全局优化码率控制(GOM QP)被启用: 如果当前宏块是GOM的起始宏块(即其索引能被GOM的数量整除),并且不是切片的起始宏块,则增加复杂度指数。 调用RcCalculateGomQp函数计算GOM的QP值。 调用RcGomTargetBits函数计算GOM的目标比特数。 调用RcCalculateMbQp函数计算当前宏块的QP值。  如果GOM QP未启用: 将当前宏块的亮度QP值设置为全局QP值。 根据亮度QP值和色度QP索引偏移量,计算并设置色度QP值。   关键功能: 函数通过判断是否启用GOM QP来决定如何设置宏块的量化参数(QP),这影响编码后视频的质量和比特率。 使用CLIP3_QP_0_51宏来确保QP值在有效范围内(0到51)。    
源码 :void  WelsRcMbInitGom  ( sWelsEncCtx*  pEncCtx,  SMB*  pCurMb,  SSlice*  pSlice)  { SWelsSvcRc*  pWelsSvcRc        =  & pEncCtx-> pWelsSvcRc[ pEncCtx-> uiDependencyId] ; SRCSlicing*  pSOverRc          =  & pSlice-> sSlicingOverRc; SDqLayer*  pCurLayer           =  pEncCtx-> pCurDqLayer; const  uint8_t  kuiChromaQpIndexOffset =  pCurLayer-> sLayerInfo. pPpsP-> uiChromaQpIndexOffset; pSOverRc-> iBsPosSlice =  pEncCtx-> pFuncList-> pfGetBsPosition  ( pSlice) ; if  ( pWelsSvcRc-> bEnableGomQp)  { if  ( 0  ==  ( pCurMb-> iMbXY %  pWelsSvcRc-> iNumberMbGom) )  { if  ( pCurMb-> iMbXY !=  pSOverRc-> iStartMbSlice)  { pSOverRc-> iComplexityIndexSlice++ ; RcCalculateGomQp  ( pEncCtx,  pSlice,  pCurMb) ; } RcGomTargetBits  ( pEncCtx,  pSlice) ; } RcCalculateMbQp  ( pEncCtx,  pSlice,  pCurMb) ; }  else  { pCurMb-> uiLumaQp   =  pEncCtx-> iGlobalQp; pCurMb-> uiChromaQp =  g_kuiChromaQpTable[ CLIP3_QP_0_51  ( pCurMb-> uiLumaQp +  kuiChromaQpIndexOffset) ] ; } } 
功能 :计算宏块组的量化参数 qp 的具体实现原理过程 : 函数参数: pEncCtx: 指向编码上下文的指针,包含编码过程中所需的全局信息。 pSlice: 指向当前切片的指针。 pCurMb: 指向当前宏块的指针,虽然在这段代码中没有直接使用。  局部变量: pWelsSvcRc: 指向服务层码率控制结构的指针。 pSOverRc: 指向切片覆盖码率控制结构的指针。 iBitsRatio: 用于计算比特率比例的变量。  主要逻辑: 计算剩余的比特数 iLeftBits,即目标比特数减去已使用的比特数。 计算目标剩余比特数 iTargetLeftBits,考虑了当前GOM的已用比特数。  QP调整逻辑: 如果剩余比特数小于或等于0,增加QP以降低质量,减少比特率的使用。 否则,根据比特率比例 iBitsRatio 来调整QP: 如果 iBitsRatio 小于 8409,增加QP 2。 如果 iBitsRatio 在 8409 和 9439 之间,增加QP 1。 如果 iBitsRatio 大于 10600,减少QP 1。 如果 iBitsRatio 大于 11900,减少QP 2。   QP值的边界限制: 使用 WELS_CLIP3 宏来确保计算出的QP值在允许的最小值和最大值之间。  重置GOM比特计数器: 将 iGomBitsSlice 重置为0,为下一个GOM的比特计数做准备。  注释: 注释中提到了一个可能的日志记录语句,但在这段代码中被注释掉了。  设计目的: 函数的目的是根据当前的编码比特率情况动态调整量化参数,以控制视频的质量和编码效率。  关键功能: 函数通过计算剩余比特数与目标比特数的比例,动态调整QP值,实现码率控制。    
源码 :void  RcCalculateGomQp  ( sWelsEncCtx*  pEncCtx,  SSlice*  pSlice,  SMB*  pCurMb)  { SWelsSvcRc*  pWelsSvcRc    =  & pEncCtx-> pWelsSvcRc[ pEncCtx-> uiDependencyId] ; SRCSlicing*  pSOverRc      =  & pSlice-> sSlicingOverRc; int64_t  iBitsRatio        =  1 ; int64_t  iLeftBits         =  pSOverRc-> iTargetBitsSlice -  pSOverRc-> iFrameBitsSlice; int64_t  iTargetLeftBits   =  iLeftBits +  pSOverRc-> iGomBitsSlice -  pSOverRc-> iGomTargetBits; if  ( ( iLeftBits <=  0 )  ||  ( iTargetLeftBits <=  0 ) )  { pSOverRc-> iCalculatedQpSlice +=  2 ; }  else  { 
iBitsRatio =  10000  *  iLeftBits /  ( iTargetLeftBits +  1 ) ; if  ( iBitsRatio <  8409 )               pSOverRc-> iCalculatedQpSlice +=  2 ; else  if  ( iBitsRatio <  9439 )          pSOverRc-> iCalculatedQpSlice +=  1 ; else  if  ( iBitsRatio >  10600 )         pSOverRc-> iCalculatedQpSlice -=  1 ; else  if  ( iBitsRatio >  11900 )         pSOverRc-> iCalculatedQpSlice -=  2 ; } pSOverRc-> iCalculatedQpSlice =  WELS_CLIP3  ( pSOverRc-> iCalculatedQpSlice,  pWelsSvcRc-> iMinFrameQp, pWelsSvcRc-> iMaxFrameQp) ; 
pSOverRc-> iGomBitsSlice =  0 ; } 
功能 :在视频编码过程中为一个组(Group of Macroblocks,GOM)分配目标比特数。原理过程 : 函数参数: pEncCtx: 指向编码上下文的指针,包含编码过程中所需的全局信息。 pSlice: 指向当前切片的指针。  局部变量: pWelsSvcRc: 指向当前依赖层的码率控制服务结构体的指针。 pWelsSvcRc_Base: 指向基础码率控制服务结构体的指针,可能用于比较或计算。 pSOverRc: 指向切片覆盖码率控制结构的指针。 iAllocateBits: 用于存储分配给当前GOM的比特数。 iSumSad: 用于累加GOM的总SAD(Sum of Absolute Differences)值。 iLastGomIndex: 表示最后一个GOM的索引。 iLeftBits: 表示剩余的比特数。 kiComplexityIndex: 表示当前GOM的复杂度指数。  主要逻辑: 计算最后一个GOM的索引 iLastGomIndex。 计算剩余的比特数 iLeftBits。 如果剩余比特数小于或等于0,将GOM的目标比特数设置为0并返回。 如果当前复杂度指数等于最后一个GOM的索引,将所有剩余比特数分配给当前GOM。 否则,计算从当前复杂度指数到最后一个GOM的SAD总和 iSumSad。 根据SAD值按比例分配剩余比特数。  比特分配策略: 如果 iSumSad 为0,等比例分配剩余比特数。 如果 iSumSad 不为0,根据当前GOM的SAD值占总SAD的比例来分配比特数。  辅助函数: RcJudgeBaseUsability: 用于判断基础码率控制服务结构体的可用性,其返回值可能用于计算。 设计目的: 函数的目的是根据宏块的复杂度和剩余的比特资源,动态地为每个GOM分配目标比特数,以优化视频质量和编码效率。  关键功能: 函数通过计算SAD值来评估宏块的复杂度,并据此分配比特数,实现码率控制。    
源码 :void  RcGomTargetBits  ( sWelsEncCtx*  pEncCtx,  SSlice*  pSlice)  { SWelsSvcRc*  pWelsSvcRc        =  & pEncCtx-> pWelsSvcRc[ pEncCtx-> uiDependencyId] ; SWelsSvcRc*  pWelsSvcRc_Base   =  NULL ; SRCSlicing*  pSOverRc          =  & pSlice-> sSlicingOverRc; int32_t  iAllocateBits =  0 ; int32_t  iSumSad =  0 ; int32_t  iLastGomIndex =  0 ; int32_t  iLeftBits =  0 ; const  int32_t  kiComplexityIndex =  pSOverRc-> iComplexityIndexSlice; int32_t  i; iLastGomIndex  =  pSOverRc-> iEndMbSlice /  pWelsSvcRc-> iNumberMbGom; iLeftBits =  pSOverRc-> iTargetBitsSlice -  pSOverRc-> iFrameBitsSlice; if  ( iLeftBits <=  0 )  { pSOverRc-> iGomTargetBits =  0 ; return ; }  else  if  ( kiComplexityIndex >=  iLastGomIndex)  { iAllocateBits =  iLeftBits; }  else  { pWelsSvcRc_Base =  RcJudgeBaseUsability  ( pEncCtx) ; pWelsSvcRc_Base =  ( pWelsSvcRc_Base)  ?  pWelsSvcRc_Base :  pWelsSvcRc; for  ( i =  kiComplexityIndex +  1 ;  i <=  iLastGomIndex;  i++ )  { iSumSad +=  pWelsSvcRc_Base-> pCurrentFrameGomSad[ i] ; } if  ( 0  ==  iSumSad) iAllocateBits =  WELS_DIV_ROUND  ( iLeftBits,  ( iLastGomIndex -  kiComplexityIndex) ) ; else iAllocateBits =  WELS_DIV_ROUND  ( ( int64_t ) iLeftBits *  pWelsSvcRc_Base-> pCurrentFrameGomSad[ kiComplexityIndex +  1 ] , iSumSad) ; } pSOverRc-> iGomTargetBits =  iAllocateBits; 
} 
功能 :作用是在视频编码过程中为当前宏块(Macroblock, MB)计算量化参数(Quantization Parameter, QP)原理过程 : 函数参数: pEncCtx: 指向编码上下文的指针,包含编码过程中所需的全局信息。 pSlice: 指向当前切片的指针。 pCurMb: 指向当前宏块的指针。  局部变量: pWelsSvcRc: 指向服务层码率控制结构的指针。 pSOverRc: 指向切片覆盖码率控制结构的指针。 iLumaQp: 存储计算得到的亮度QP值。 pCurLayer: 指向当前解码质量层的指针。 kuiChromaQpIndexOffset: 色度QP索引偏移量。  主要逻辑: 从切片覆盖码率控制结构中获取iCalculatedQpSlice计算得到的亮度QP值 iLumaQp。 如果启用了自适应量化(bEnableAdaptiveQuant),则根据宏块的运动和纹理信息调整QP值。  自适应量化: 如果启用自适应量化,使用 pMotionTextureIndexToDeltaQp 数组,根据宏块的位置 MbXY 来获取QP调整值,并将其加到基础QP值iLumaQp上。 调整后的QP值通过 WELS_CLIP3 宏确保在允许的范围内。  色度QP计算: 使用色度QP表 g_kuiChromaQpTable 和色度QP索引偏移量 kuiChromaQpIndexOffset 来计算色度QP值。 色度QP值通过 CLIP3_QP_0_51 宏确保在0到51的范围内。  宏块QP赋值: 将计算得到的亮度QP和色度QP值赋给当前宏块 pCurMb。    
源码 :void  RcCalculateMbQp  ( sWelsEncCtx*  pEncCtx,  SSlice*  pSlice,  SMB*  pCurMb)  { SWelsSvcRc*  pWelsSvcRc        =  & pEncCtx-> pWelsSvcRc[ pEncCtx-> uiDependencyId] ; SRCSlicing*  pSOverRc          =  & pSlice-> sSlicingOverRc; int32_t  iLumaQp               =  pSOverRc-> iCalculatedQpSlice; SDqLayer*  pCurLayer           =  pEncCtx-> pCurDqLayer; const  uint8_t  kuiChromaQpIndexOffset =  pCurLayer-> sLayerInfo. pPpsP-> uiChromaQpIndexOffset; if  ( pEncCtx-> pSvcParam-> bEnableAdaptiveQuant)  { iLumaQp   =  ( int8_t ) WELS_CLIP3  ( iLumaQp + pEncCtx-> pVaa-> sAdaptiveQuantParam. pMotionTextureIndexToDeltaQp[ pCurMb-> iMbXY] ,  pWelsSvcRc-> iMinFrameQp, pWelsSvcRc-> iMaxFrameQp) ; } pCurMb-> uiChromaQp    =  g_kuiChromaQpTable[ CLIP3_QP_0_51  ( iLumaQp +  kuiChromaQpIndexOffset) ] ; pCurMb-> uiLumaQp      =  iLumaQp; 
} 
功能 :通过收集和更新宏块的编码信息来帮助编码器动态调整编码参数,以优化视频质量和编码效率。原理过程 : 函数参数: pEncCtx: 指向编码上下文的指针,包含编码过程中所需的全局信息。 pCurMb: 指向当前宏块的指针。 iCostLuma: 当前宏块的亮度成本,用于码率控制。 pSlice: 指向当前切片的指针。  局部变量: pWelsSvcRc: 指向服务层码率控制结构的指针。 pSOverRc: 指向切片覆盖码率控制结构的指针。 kiComplexityIndex: 复杂度指数,用于码率控制策略。  主要逻辑: 计算当前宏块的比特数iCurMbBits,即从切片开始到当前宏块的比特流位置差。 更新切片的总比特数iFrameBitsSlice和GOM(Group of Macroblocks)的总比特数iGomBitsSlice。  码率控制相关操作: 累加当前宏块的亮度成本iCostLuma到对应复杂度指数的成本数组pGomCost中。 如果当前宏块的比特数大于0,更新切片的总QP(量化参数)和宏块计数器。  设计目的: 该函数的目的是在编码过程中收集和更新宏块的相关信息,以便进行有效的码率控制。  关键功能: 函数通过更新宏块的比特数和亮度成本,为后续的码率控制决策提供数据支持。    
源码 :void  WelsRcMbInfoUpdateGom  ( sWelsEncCtx*  pEncCtx,  SMB*  pCurMb,  int32_t  iCostLuma,  SSlice*  pSlice)  { SWelsSvcRc*  pWelsSvcRc            =  & pEncCtx-> pWelsSvcRc[ pEncCtx-> uiDependencyId] ; SRCSlicing*  pSOverRc              =  & pSlice-> sSlicingOverRc; const  int32_t  kiComplexityIndex   =  pSOverRc-> iComplexityIndexSlice; int32_t  iCurMbBits =  pEncCtx-> pFuncList-> pfGetBsPosition  ( pSlice)  -  pSOverRc-> iBsPosSlice; pSOverRc-> iFrameBitsSlice +=  iCurMbBits; pSOverRc-> iGomBitsSlice +=  iCurMbBits; pWelsSvcRc-> pGomCost[ kiComplexityIndex]  +=  iCostLuma; if  ( iCurMbBits >  0 )  { pSOverRc-> iTotalQpSlice +=  pCurMb-> uiLumaQp; pSOverRc-> iTotalMbSlice++ ; } 
}