WelsCodeOneSlice函数包含预测、变换等过程的入口函数,入口函数包含在一个二维数组中,该数组如下:
// 1st index: 0: for P pSlice; 1: for I pSlice;
// 2nd index: 0: for non-dynamic pSlice; 1: for dynamic I pSlice;
static const PWelsCodingSliceFunc g_pWelsSliceCoding[2][2] = {
{ WelsCodePSlice, WelsCodePOverDynamicSlice }, // P SSlice
{ WelsISliceMdEnc, WelsISliceMdEncDynamic } // I SSlice
};
预测过程的入口为:
int32_t iEncReturn = g_pWelsSliceCoding[pNalHeadExt->bIdrFlag][kiDynamicSliceFlag] (pEncCtx, pCurSlice);
根据索引值来确定取哪个函数进行帧内或帧间预测。
另外这个函数确定一个变量pCurSlice->sScaleShift的值,如果是I_SLICE,这个值为0,否则根据当前层的时域层数和参考帧图像的时域层数来计算。这个值表示缩放比例,用在帧间预测的时域运动矢量计算的过程中。具体使用位置在函数WelsMdP16x16中,代码如下:
//temporal motion vector predictors时域运动矢量预测,取参考帧中同位置右边和下边的MV经过缩放后加入到MV的预测候选列表中
if (pCurLayer->pRefPic->iPictureType == P_SLICE) {
if (pCurMb->iMbX < kiMbWidth - 1) {
SMVUnitXY sTempMv = pCurLayer->pRefPic->sMvList[pCurMb->iMbXY + 1];
pSlice->sMvc[pSlice->uiMvcNum].iMvX = sTempMv.iMvX >> pSlice->sScaleShift;
pSlice->sMvc[pSlice->uiMvcNum].iMvY = sTempMv.iMvY >> pSlice->sScaleShift;
++ pSlice->uiMvcNum;
}
if (pCurMb->iMbY < kiMbHeight - 1) {
SMVUnitXY sTempMv = pCurLayer->pRefPic->sMvList[pCurMb->iMbXY + kiMbWidth];
pSlice->sMvc[pSlice->uiMvcNum].iMvX = sTempMv.iMvX >> pSlice->sScaleShift;
pSlice->sMvc[pSlice->uiMvcNum].iMvY = sTempMv.iMvY >> pSlice->sScaleShift;
++ pSlice->uiMvcNum;
}
}