openh264码控笔记一(整体框架)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CrystalShaw/article/details/83896681

一、名词解释

计算码控时会用到如下的一些参数:

SAD (Sum of Absolute Difference)=SAE(Sum of Absolute Error)绝对误差和
SATD(Sum of Absolute Transformed Difference)即hadamard变换后再绝对值求和
SSD (Sum of Squared  Difference)=SSE(Sum of Squared Error) 差值的平方和
MAD (Mean Absolute   Difference)=MAE(Mean Absolute Error)  平均绝对差值
MSD (Mean Squared    Difference)=MSE(Mean Squared Error)   平均平方误差

SAD绝对误差和,仅反映残差时域差异,影响PSNR值,不能有效反映码流的大小。SATD将残差经哈德曼变换的4×4块的预测残差绝对值总和,可以将其看作简单的时频变换,其值在一定程度上可以反映生成码流的大小。因此,不用率失真最优化时,可将其作为模式选择的依据。一般帧内要对所有的模式进行检测,帧内预测选用SATD的原因同上。

在做运动估计时,一般而言,离最优匹配点越远,匹配误差值SAD越大,这就是有名的单一平面假设,现有的运动估计快速算法大都利用该特性。但是,转换后SATD值并不满足该条件,如果在整象素中运用SATD搜索,容易陷入局部最优点。而在亚象素中,待搜索点不多,各点处的SAD差异相对不大,可以用SATD选择码流较少的匹配位置。

RDO(Rate–distortion optimization)率失真优化,用来确定编码模式,保证码率比特数和图像失真的最佳权衡点。

RQ模型是在上一层码率数一定的情况下用来确定下一层分配的比特数。RQ先于RDO进行。

二、码控钩子函数初始化

WelsRcInitFuncPointers函数初始化各种码控模式下的钩子函数。

三、RC_BITRATE_MODE码控函数框架

四、结构体参数

1、帧级QP参数

TagWelsRc->iInitialQp

typedef struct TagWelsRc {
int32_t   iRcVaryPercentage;
int32_t   iRcVaryRatio;

int32_t   iInitialQp; //initial qp
int64_t   iBitRate; // Note: although the max bit rate is 240000*1200 which can be represented by int32, but there are many multipler of this iBitRate in the calculation of RC, so use int64 to avoid type conversion at all such places
int32_t   iPreviousBitrate;
int32_t   iPreviousGopSize;
double    fFrameRate;
int32_t   iBitsPerFrame;
int32_t   iMaxBitsPerFrame;
double    dPreviousFps;

// bits allocation and status
int32_t   iRemainingBits;
int32_t   iBitsPerMb;
int32_t   iTargetBits;
int32_t   iCurrentBitsLevel;//0:normal; 1:limited; 2:exceeded.

int32_t   iIdrNum;
int64_t   iIntraComplexity; //255*255(MaxMbSAD)*36864(MaxFS) make the highest bit of 32-bit integer 1
int32_t   iIntraMbCount;
int64_t   iIntraComplxMean;

int8_t    iTlOfFrames[VGOP_SIZE];
int32_t   iRemainingWeights;
int32_t   iFrameDqBits;

bool       bGomRC;
double*    pGomComplexity;
int32_t*   pGomForegroundBlockNum;
int32_t*   pCurrentFrameGomSad;
int32_t*   pGomCost;

int32_t   bEnableGomQp;
int32_t   iAverageFrameQp;
int32_t   iMinFrameQp;
int32_t   iMaxFrameQp;
int32_t   iNumberMbFrame;
int32_t   iNumberMbGom;
int32_t   iGomSize;

int32_t   iSkipFrameNum;
int32_t   iFrameCodedInVGop;
int32_t   iSkipFrameInVGop;
int32_t   iGopNumberInVGop;
int32_t   iGopIndexInVGop;

int32_t   iSkipQpValue;
int32_t   iQpRangeUpperInFrame;
int32_t   iQpRangeLowerInFrame;
int32_t   iMinQp;
int32_t   iMaxQp;
//int32_t   delta_adaptive_qp;
int32_t   iSkipBufferRatio;

int32_t   iQStep; // *INT_MULTIPLY
int32_t   iFrameDeltaQpUpper;
int32_t   iFrameDeltaQpLower;
int32_t   iLastCalculatedQScale;

//for skip frame and padding
int32_t   iBufferSizeSkip;
int64_t   iBufferFullnessSkip;
int64_t   iBufferMaxBRFullness[TIME_WINDOW_TOTAL];//0: EVEN_TIME_WINDOW; 1: ODD_TIME_WINDOW
int32_t   iPredFrameBit;
bool      bNeedShiftWindowCheck[TIME_WINDOW_TOTAL];
int32_t   iBufferSizePadding;
int32_t   iBufferFullnessPadding;
int32_t   iPaddingSize;
int32_t   iPaddingBitrateStat;
bool      bSkipFlag;
int32_t   iContinualSkipFrames;
SRCTemporal* pTemporalOverRc;

//for scc
int64_t     iAvgCost2Bits;
int64_t     iCost2BitsIntra;
int32_t    iBaseQp;
long long  uiLastTimeStamp;

//for statistics and online adjustments
int32_t   iActualBitRate; // TODO: to complete later
float     fLatestFrameRate; // TODO: to complete later
} SWelsSvcRc;

2、Slice级QP参数

SRCSlicing->iCalculatedQpSlice

// slice level rc statistic info
typedef struct TagRCSlicing {
  int32_t   iComplexityIndexSlice;
  int32_t   iCalculatedQpSlice;
  int32_t   iStartMbSlice;
  int32_t   iEndMbSlice;
  int32_t   iTotalQpSlice;
  int32_t   iTotalMbSlice;
  int32_t   iTargetBitsSlice;
  int32_t   iBsPosSlice;
  int32_t   iFrameBitsSlice;
  int32_t   iGomBitsSlice;
  int32_t   iGomTargetBits;
  //int32_t   gom_coded_mb;
} SRCSlicing;

3、宏块级QP参数

TagMB->uiLumaQp/uiChromaQp

typedef struct TagMB {
/*************************mb_layer() syntax and generated********************************/
/*mb_layer():*/
Mb_Type         uiMbType;       // including MB detailed partition type, number and type of reference list
uint8_t         uiSubMbType[4]; // sub MB types
int32_t         iMbXY;          // offset position of MB top left point based
int16_t         iMbX;           // position of MB in horizontal axis [0..32767]
int16_t         iMbY;           // position of MB in vertical axis [0..32767]

uint8_t         uiNeighborAvail;        // avail && same_slice: LEFT_MB_POS:0x01, TOP_MB_POS:0x02, TOPRIGHT_MB_POS = 0x04 ,TOPLEFT_MB_POS = 0x08;
uint8_t         uiCbp;

SMVUnitXY*      sMv;
int8_t*         pRefIndex;

int32_t*        pSadCost;          // mb sad. set to 0 for intra mb
int8_t*         pIntra4x4PredMode; // [MB_BLOCK4x4_NUM]
int8_t*         pNonZeroCount;     // [MB_LUMA_CHROMA_BLOCK4x4_NUM]

SMVUnitXY       sP16x16Mv;

uint8_t         uiLumaQp;       // uiLumaQp: pPps->iInitialQp + sSliceHeader->delta_qp + mb->dquant.
uint8_t         uiChromaQp;
uint16_t        uiSliceIdc;     // 2^16=65536 > MaxFS(36864) of level 5.1; AVC: iFirstMbInSlice?; SVC: (iFirstMbInSlice << 7) | ((uiDependencyId << 4) | uiQualityId);
uint32_t        uiChromPredMode;
int32_t         iLumaDQp;
SMVUnitXY       sMvd[MB_BLOCK4x4_NUM]; //only for CABAC writing; storage structure the same as sMv, in 4x4 scan order.
int32_t         iCbpDc;
//uint8_t         reserved_filling_bytes[1];      // not deleting this line for further changes of this structure. filling bytes reserved to make structure aligned with 4 bytes, higher cache hit on less structure size by 2 cache lines( 2 * 64 bytes) once hit
} SMB, *PMb;

猜你喜欢

转载自blog.csdn.net/CrystalShaw/article/details/83896681
今日推荐