📄 macroblock.c
字号:
/* Store CBP, qp, mbType for loopfilter*/ // change cbpY order, so we do not have to modify loop filter implementation mb->mbThis->cbp = mb->rastercbpY | (mb->cbpC << 16) | ((mb->lumaNonzeroDC != 0) << 24) | (mb->cbpChromaDC << 25); mb->mbThis->qp = (int8) mb->qp; mb->mbThis->intraModeChroma = (int8) mb->intraModeChroma; if (mb->type == MBK_INTRA) { mb->mbThis->mbType = (int8)((mb->intraType == MBK_INTRA_TYPE1) ? MB_TYPE_INTRA_4x4 : MB_TYPE_INTRA_16x16); } else // mb->interMode = 2, MOT_COPY (skipped MOT_16x16) mb->mbThis->mbType = (int8)(mb->interMode + 2); // Copy motion vectors of the best model to motion vector buffer for (j = 0; j < BLK_PER_MB; j ++) for (i = 0; i < BLK_PER_MB; i ++) mb->mbThis->blkInfo[j][i] = mb->current[j][i]; /* * Update MB mode statistics */ if (mb->type == MBK_INTRA) { if (mb->intraType == MBK_INTRA_TYPE1) stat->intraModeCtr1 += 1; else stat->intraModeCtr2[mb->intra16x16mode] += 1; } else stat->interModeCtr[mb->interMode] += 1; // temporary}void mbkModeSelection(rateCtrl_s *pbRC, macroblock_s *mb, meProfile_s *pMeProf, refFrmBuf_s **refBufList, int nRefFrames, int picType, encParams_s *encPar, int *mapRIR, int *channelDistortion, int forcedIRNo, int *forcedIR, int mbNum){ int i, j; costMeasure_s intraCost, interCost, intra16x16Cost, intra4x4Cost; double thr; int picWidth; int mbkPerLine; int chromaIntraSad; int constrainedIntra; int chromaModeAvail[IPR_CHROMA_NUM_MODES]; int fIntra; int8 i4x4Modes[4][4]; u_int8 colMbY[MBK_SIZE][MBK_SIZE]; u_int8 colMbC[MBK_SIZE/2][2 * (MBK_SIZE/2)]; int ssd0 = 0; float scale;#ifndef DISABLE_RDO encPar->rdo |= RDO_INTRA_LUMA_4x4 | RDO_INTRA_CHROMA |// RDO_INTRA_LUMA_16x16 | RDO_INTER;#endif#ifndef DISABLE_RDO if((encPar->rdo & 0x0F) == MODE_DECISION_RDO) scale=1.0f; else#endif scale=3.0f; picWidth = encPar->picWidth; mbkPerLine = picWidth / MBK_SIZE; fIntra = 0; if(encPar->nRandomIntraRefresh != 0 ) { for (i = 0; i < encPar->nRandomIntraRefresh; i ++) { if (mapRIR[i] == mb->mbAddr) fIntra = 1 ;//Force Intra } } // An MB is forced to be Intra Refreshed with fixed frequecy if (encPar->sIntraRefresh != 0 && forcedIRNo > 0) { if (forcedIR[mbNum] == 0) fIntra=1; forcedIR[mbNum]--; } constrainedIntra = encPar->constIpred && (IS_SLICE_P(picType)); getMbAvailability(mb, picWidth, constrainedIntra); // If inter picture, find best inter mode interCost = initCostMeasure; // set the initial condition of the macroblock, and calculate skipPredMv mbkLoadNeighbors(mb); mb->qp = rc_getMBQP(pbRC,mb,picType,mb->idxY*mbkPerLine+mb->idxX); mb->qpC = qpChroma[clip(MIN_QP, MAX_QP, mb->qp + encPar->chromaQpIdx)]; if (IS_SLICE_P(picType) && !fIntra) { // picType == IMG_INTER int interSad;// Do Motion Search and find the best mode based on SAD interSad = mesFindMotionFullSearch(mb, pMeProf, refBufList, nRefFrames); if(encPar->sIntraRefresh) { // get the colocated MB mcpGetColocatedMb(mb, refBufList, colMbY, colMbC);#ifndef DISABLE_RDO if((encPar->rdo & 0x0F) == MODE_DECISION_RDO) { scale=1.0f; // calculate the MSE between current and previous MB, it will be used as a metric of channel distortion ssd0 = CalculateSsd (& mb->origY[0][0], 16, &colMbY[0][0], 16, 16, 16); ssd0 += CalculateSsd (& mb->origC[0][0], 16, &colMbC[0][0], 16, 8, 8); ssd0 += CalculateSsd (& mb->origC[0][0] + 8, 16, &colMbC[0][0] + 8, 16, 8, 8); } else#endif { // calculate the MSE between current and previous MB, it will be used as a metric of channel distortion ssd0 = CalculateSad (& mb->origY[0][0], 16, &colMbY[0][0], 16, 16, 16); ssd0 += CalculateSad (& mb->origC[0][0], 16, &colMbC[0][0], 16, 8, 8); ssd0 += CalculateSad (& mb->origC[0][0] + 8, 16, &colMbC[0][0] + 8, 16, 8, 8); } } //If RDO is disabled, the best inter-mode is selected by the above function#ifndef DISABLE_RDO mdInterModeDecision(mb, refBufList, nRefFrames, picWidth, picType, encPar->rdo, ssd0, & interCost);#else mdInterModeDecision(mb, refBufList, nRefFrames, picWidth, picType, 0, ssd0, & interCost);#endif interCost.sad = interSad; mb->actualInterSad = interSad; // DBG // prefer inter by 4 lambda interCost.sad -= mb->lambda * 4;#ifndef DISABLE_RDO if ((encPar->rdo & 0x0F) != MODE_DECISION_RDO) {#endif interCost.cost = interCost.sad;#ifndef DISABLE_RDO }#endif } // -------------------------------------------------------------------------- // Find the best 16x16 intra prediction intra16x16Cost = initCostMeasure; if (mb->qp >= MIN_QP + 12) mb->intra16x16enabled = 1; else mb->intra16x16enabled = 0; if (mb->intra16x16enabled) { // : skip whole 16x16 check when inter cost small if ( ((pMeProf->lc3.low_complex_prof3) && (interCost.sad>TH_IPR_16x16) ) || (! pMeProf->lc3.low_complex_prof3) || (encPar->sIntraRefresh == 1)) {#ifndef DISABLE_RDO if(encPar->sIntraRefresh) mdIntraPredLuma16x16(mb, picWidth, picType, MAX_COST, encPar->rdo, & intra16x16Cost, encPar->low_complex_prof3); else mdIntraPredLuma16x16(mb, picWidth, picType, interCost.sad, encPar->rdo, & intra16x16Cost, encPar->low_complex_prof3);#else if(encPar->sIntraRefresh) mdIntraPredLuma16x16(mb, picWidth, picType, MAX_COST, 0, & intra16x16Cost, encPar->low_complex_prof3); else mdIntraPredLuma16x16(mb, picWidth, picType, interCost.sad, 0, & intra16x16Cost, encPar->low_complex_prof3);#endif } } // Find the best 4x4 intra prediction /* Compute error threshold for doing 4x4 intra search */ if (!IS_SLICE_I(picType) #ifndef DISABLE_RDO && (encPar->rdo & 0x0F) != MODE_DECISION_RDO#endif ) thr = -0.000933 * (mb->qp-12) * (mb->qp-12) - 0.004673 * (mb->qp-12) + 2.133227; else thr = MAX_COST; // -------------------------------------------------------------------------- // Get intra 4x4 predictions and choose best of 4x4 mode and 16x16 mode. // Only if inter error is small enough, 4x4 intra is not checked. intra4x4Cost = initCostMeasure; if (IS_SLICE_I(picType) || !mb->intra16x16enabled || thr*interCost.sad > intra16x16Cost.sad && !(encPar->sIntraRefresh == 1) ) { // : intra pred if (( (pMeProf->lc3.low_complex_prof3) && (intra16x16Cost.sad>TH_IPR_4x4) ) || (! pMeProf->lc3.low_complex_prof3) || (encPar->sIntraRefresh == 1) ) {#ifndef DISABLE_RDO if(encPar->sIntraRefresh) mdIntraPredLuma4x4(mb, picWidth, picType, MAX_COST, encPar->rdo & 0x0F, & intra4x4Cost, pMeProf->lc3.low_complex_prof3); else mdIntraPredLuma4x4(mb, picWidth, picType, interCost.sad, encPar->rdo & 0x0F, & intra4x4Cost, pMeProf->lc3.low_complex_prof3); #else if(encPar->sIntraRefresh) mdIntraPredLuma4x4(mb, picWidth, picType, MAX_COST, 0, & intra4x4Cost, pMeProf->lc3.low_complex_prof3); else mdIntraPredLuma4x4(mb, picWidth, picType, interCost.sad, 0, & intra4x4Cost, pMeProf->lc3.low_complex_prof3);#endif // save i4x4 modes here, buffer "current" will be used for other purpose for (j = 0; j < 4; j ++) for (i = 0; i < 4; i ++) i4x4Modes[j][i] = mb->current[j][i].i4x4Mode; } } #ifndef DISABLE_RDO mdIntraModeDecision(mb, refBufList, picWidth, picType, encPar->rdo, ssd0, & intra16x16Cost, & intra4x4Cost, & intraCost);#else mdIntraModeDecision(mb, refBufList, picWidth, picType, 0, ssd0, & intra16x16Cost, & intra4x4Cost, & intraCost);#endif // -------------------------------------------------------------------------- // Choose the better one between intra and inter if (IS_SLICE_I(picType) || (mdGetCost(mb, &intraCost,scale) < mdGetCost(mb, &interCost,scale))) { int mbType, i, numNonPredicted; mb->type = MBK_INTRA; // calculate the actual SAD by excluding the syntax bits mbType = ((IS_SLICE_P(picType)) ? 5 : 0) + streamGetMbTypeIntra (mb->intraType, mb->intra16x16mode, 0, 0, 0); mb->intraSyntaxBits = uvlcBitsUnsigned[mbType]; // bits on sending 4x4 intra prediction modes if (mb->intraType == MBK_INTRA_TYPE1) { numNonPredicted = 0; for (i = 0; i < 16; i ++) if (mb->ipTab[i] >= 0) numNonPredicted ++; mb->intraSyntaxBits += 16 + numNonPredicted * 3; } mb->minSad = intraCost.sad; mb->minActualSad = mb->actualIntraSad; mb->minMSE = intraCost.mse; } else { mb->type = MBK_INTER; mb->minSad = interCost.sad; mb->minActualSad = mb->actualInterSad; mb->minMSE = interCost.mse; } if(pbRC->bit_rate > 0) { if ( (mb->type == MBK_INTER) && (mb->modeMvRef[MOT_16x16][0].ref == 0) && (mb->modeMvRef[MOT_16x16][0].mv.x == mb->skipPredMv.x) && (mb->modeMvRef[MOT_16x16][0].mv.y == mb->skipPredMv.y) && mbNum>0) pbRC->currentFrame_MBQp[mbNum]=pbRC->currentFrame_MBQp[mbNum-1]; else pbRC->currentFrame_MBQp[mbNum]=mb->qp; } // get the data ready for encoding if (mb->type == MBK_INTRA) { if (mb->intraType == MBK_INTRA_TYPE2) for (j = 0; j < BLK_PER_MB; j ++) for (i = 0; i < BLK_PER_MB; i ++) i4x4Modes[j][i] = IPR_MODE_DC; for (j = 0; j < BLK_PER_MB; j ++) { for (i = 0; i < BLK_PER_MB; i ++) { mb->current[j][i].mv.x = 0; mb->current[j][i].mv.y = 0; mb->current[j][i].ref = -1; // available but intra mb->current[j][i].i4x4Mode = i4x4Modes[j][i]; } } // perform chroma prediction#ifndef DISABLE_RDO if ((encPar->rdo & 0x0F) != MODE_DECISION_RDO)#endif { iprGetPredChroma(mb->predIntraC, chromaModeAvail, mb->recoU, mb->recoV, picWidth >> 1, mb->mbAvailMapIntra); chromaIntraSad = mdIntraPredChroma(mb, chromaModeAvail, pMeProf->hadamard); } } else { int8 interI4x4Mode; // get the inter pixel predictors mcpGetPred(mb, refBufList); // set the i4x4Mode according to constrainedIntra interI4x4Mode = (int8)((constrainedIntra) ? IPR_MODE_NA : IPR_MODE_DC); for (j = 0; j < BLK_PER_MB; j ++) for (i = 0; i < BLK_PER_MB; i ++) mb->current[j][i].i4x4Mode = interI4x4Mode; } // if Intra coded, forced Intra Refresh is postponed. if (forcedIRNo > 0 && mb->type == MBK_INTRA) { if (forcedIR[mbNum] < 2*FORCE_INTRA_FREQUENCY) forcedIR[mbNum] += forcedIRNo+1; } // update the channel distortion if (channelDistortion) { if (mb->type == MBK_INTRA) channelDistortion[mb->idxY*mbkPerLine+mb->idxX] = intraCost.cDistortion; else channelDistortion[mb->idxY*mbkPerLine+mb->idxX] = interCost.cDistortion; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -