1. 程式人生 > >openh264碼控筆記一(整體框架)

openh264碼控筆記一(整體框架)

一、名詞解釋

計算碼控時會用到如下的一些引數:

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;