📄 umc_h264_aic.cpp
字号:
uEdgeType = pModeSelParams->uEdgeType | uEncNotEdge[uBlock]; // get AI mode of block above and block to left to use to add bit cost // of signaling each mode for this block to SAD. Take care not to go // beyond the AIMode array, at top and left picture edges. if ((uEdgeType & MBEdgeTypeIsNotLeftEdge) == 0) ModeLeft = -1;#ifdef NOINTRALEFTDEP else { // If this block is on the left MB edge, assume we don't know anything about the block to the left. if (!(uEncNotEdge[uBlock] & MBEdgeTypeIsNotLeftEdge)) ModeLeft = 2; else ModeLeft = *(pMode-1); }#else else ModeLeft = *(pMode-1);#endif // NOINTRALEFTDEP if ((uEdgeType & MBEdgeTypeIsNotTopEdge) == 0) ModeAbove = -1; else ModeAbove = *(pMode - pModeSelParams->uWidthIn4x4Blocks); uMinSAD = 0x0fffffff; // Get the above and left predictor pels to PredPel GetBlockPredPels(uEdgeType, pRefBlock, pModeSelParams->uPitch, uBlock, PredPel); // If all the predictor pels are equal, all modes will // give the same results. // if (pPred) check_num_modes = NUM_AI_MODES; // else // check_num_modes = 3; Mode = 0; // first mode checked for (; Mode < check_num_modes; Mode++) { if (ModeAbove == -1) { // If pixels above are not available, then vertical and some diagonal modes are not available if (!((Mode == 1) || (Mode == 2) || (Mode == 8))) continue; } if (ModeLeft == -1) { // If pixels to the left are not available, then horizontal and some diagonal modes not available if (!((Mode == 0) || (Mode == 2) || (Mode == 3) || (Mode == 7))) continue; } if (!(uEdgeType & MBEdgeTypeIsNotUpperLeftCorner)) { // If the upper left corner is not available, then some diagonal modes not available if ((Mode == 4) || (Mode == 5) || (Mode == 6)) continue; } // The most probable mode is the Minimum of the two predictors ProbMode = MIN(ModeAbove, ModeLeft); if (ProbMode == -1) { // Unless one or both of the predictors is "outside" ProbMode = 2; // In this case it defaults to mode 2 (DC Prediction). } // The probability of the current mode is 0 if it equals the Most Probable Mode if (ProbMode == Mode) { uProb = 0; } else if (Mode < ProbMode ) { // Otherwise, the mode probability increases uProb = Mode + 1; // (the opposite of intuitive notion of probability) } else { // with the order of the the remaining modes. uProb = Mode; } // VSI: Tune this constant further... // 1 bit for a predicted mode/4 bits if mispredicted uSAD = (((uProb != 0) ? 4 : 1 ) * rd_quant[pModeSelParams->uQP])>>3; if (uSAD < uMinSAD) { // get predictor block GetPredBlock(Mode, &uPred[Mode*64], PredPel); uSAD += SAD4x4Block_P16(pSrcBlock, &uPred[Mode*64], pModeSelParams->uPitch); // if best so far update return vars if (uSAD < uMinSAD) { uMinSAD = uSAD; *pMode = Mode; } } } // for mode // force mode for debug/test // *pMode = 2; // uMinSAD = 0; if (pPred) { // copy selected predictor pels to provided buffer (pitch=16) Ipp32u* pSrc = (Ipp32u*)&uPred[(*pMode)*64]; Ipp32u* pDst = (Ipp32u*)pPred; pDst[0] = pSrc[0]; pDst[1*4] = pSrc[1*4]; pDst[2*4] = pSrc[2*4]; pDst[3*4] = pSrc[3*4]; } return uMinSAD;} // AIModeSelectOneBlocktypedef enum { PRED16x16_VERT=0, PRED16x16_HORZ=1, PRED16x16_DC=2, PRED16x16_PLANAR=3} Enum16x16PredType;// These are numbered by the chroma pred mode bitstream codes used,// which may not match the documentation "Mode n" used to describe the modes// in the JVT FCD.typedef enum { PRED8x8_DC=0, PRED8x8_HORZ=1, PRED8x8_VERT=2, PRED8x8_PLANAR=3} Enum8x8PredType;typedef enum { LEFT_AVAILABLE = 1, // Pixels to the left from the MB are available. TOP_AVAILABLE = 2 // Pixels above the MB are available.} PixelsAvailabilityType;//////////////////////////////////////////////////////////////////////////////////// AIModeSelectOneMB_16x16//// Choose the best advanced intra mode for coding the MB, return at// *pMode. Also return the SAD for the chosen mode. Also// save predictor pels for the MB in provided buffer.//////////////////////////////////////////////////////////////////////////////////Ipp32u AIModeSelectOneMB_16x16( Ipp8u* pSrc, // pointer to upper left pel of source MB Ipp8u* pRef, // pointer to same MB in reference picture Ipp32u uPitch, // of source and ref data Ipp32u uEdgeType, // MB on picture edge? Ipp32u available, // flags showing the available pixels around the MB T_AIMode *pMode, // selected mode goes here Ipp8u *pPredBuf // predictor pels for selected mode goes here ){ Ipp32u uSAD[4] = {0,0,0,0}; // MB SAD accumulators bool bOnTopEdge; bool bOnLeftEdge; bool bUpperLeftCorner; Ipp8u* pAbove; Ipp8u* pLeft; Ipp8u uVertPred[64]; // 4 4x4 predictor blocks Ipp8u uHorizPred[64]; // 4 4x4 predictor blocks Ipp8u uDCPred[16]; // 1 4x4 predictor block Ipp8u *pPlanarPred = 0; Ipp8u *pSrcBlock = 0; Ipp32u *pCopyDst; Ipp32u *pCopySrc; Ipp32u i, row; Ipp32u uBlock; Ipp32u uSum = 0; // to get DC predictor Ipp32u uSmallestSAD; Enum16x16PredType Best16x16Type;#ifdef TEST_16x16MS_BY_COMPARE Ipp8u uTestPredBuffer[256]; T_AIMode TestMode; Ipp32u uTestSAD;#endif // TEST_16x16MS_BY_COMPARE bOnTopEdge = 0 == (uEdgeType & MBEdgeTypeIsNotTopEdge); bOnLeftEdge = 0 == (uEdgeType & MBEdgeTypeIsNotLeftEdge); bUpperLeftCorner = 0 == (uEdgeType & MBEdgeTypeIsNotUpperLeftCorner); int topAvailable = !bOnTopEdge && (available&TOP_AVAILABLE) != 0; int leftAvailable = !bOnLeftEdge && (available&LEFT_AVAILABLE) != 0; // Initialize uVertPred with prediction from above if (!topAvailable) { // nothing above, set SAD very large uSAD[PRED16x16_VERT] = 0xffffffff; } else { pAbove = pRef - uPitch; // fill each of 4 predictor blocks from above, using 32-bit copy // operations for efficiency pCopyDst = (Ipp32u *)uVertPred; for (i=0; i<4; i++) { pCopySrc = (Ipp32u *)pAbove; *(pCopyDst + 0) = *pCopySrc; *(pCopyDst + 4) = *pCopySrc; *(pCopyDst + 8) = *pCopySrc; *(pCopyDst + 12) = *pCopySrc; // Accumulate sum for DC predictor uSum += *pAbove + *(pAbove+1) + *(pAbove+2) + *(pAbove+3); pCopyDst++; pAbove += 4; } } // Initialize uHorizPred with prediction from left if (!leftAvailable) { // nothing to the left, set SAD very large uSAD[PRED16x16_HORZ] = 0xffffffff; } else { pLeft = pRef - 1; // fill each of 4 predictor blocks from left for (i=0; i<16; i++, pLeft += uPitch) { uHorizPred[i*4+0] = *pLeft; uHorizPred[i*4+1] = *pLeft; uHorizPred[i*4+2] = *pLeft; uHorizPred[i*4+3] = *pLeft; uSum += *pLeft; // accumulate for DC predictor } } // Initialize uDCPred with average of above and left // divide by 32 to get average if (!leftAvailable && !topAvailable) { uSum = 128; } else { // For MB on left or top edge not at upper left, accumulated sum // is sum of 16, so double it for the following divide by 32. if (bOnTopEdge || bOnLeftEdge) uSum <<= 1; uSum = (uSum + 16) >> 5; } memset(uDCPred, (Ipp8u)uSum, 16); // Get planar prediction, save 16x16 Ipp8u result at pPredBuf, if (leftAvailable && topAvailable && !bUpperLeftCorner) PlanarPredictLuma(uEdgeType, pRef, uPitch, pPredBuf); else uSAD[PRED16x16_PLANAR] = 0xffffffff; // Mode select: Loop through all luma blocks, accumulate a MB SAD for // each mode. for (uBlock=0; uBlock<16; uBlock++) { if ((uBlock & 3) == 0) { // init pPlanarPred for new row of blocks pPlanarPred = pPredBuf + uBlock*16; pSrcBlock = pSrc + uBlock*uPitch; } uSAD[PRED16x16_DC] += SAD4x4Block4(pSrcBlock, uPitch, uDCPred, 4); if (topAvailable) uSAD[PRED16x16_VERT] += SAD4x4Block4(pSrcBlock, uPitch, &uVertPred[(uBlock & 3)*4], 16); if (leftAvailable) uSAD[PRED16x16_HORZ] += SAD4x4Block4(pSrcBlock, uPitch, &uHorizPred[(uBlock>>2)*16], 4); if (leftAvailable && topAvailable && !bUpperLeftCorner) uSAD[PRED16x16_PLANAR] += SAD4x4Block4(pSrcBlock, uPitch, pPlanarPred, 16); // next block pSrcBlock += 4; pPlanarPred += 4; } // choose smallest uSmallestSAD = uSAD[PRED16x16_DC]; Best16x16Type = PRED16x16_DC; if (uSAD[PRED16x16_VERT] < uSmallestSAD) { uSmallestSAD = uSAD[PRED16x16_VERT]; Best16x16Type = PRED16x16_VERT; } if (uSAD[PRED16x16_HORZ] < uSmallestSAD) { uSmallestSAD = uSAD[PRED16x16_HORZ]; Best16x16Type = PRED16x16_HORZ; } if (uSAD[PRED16x16_PLANAR] < uSmallestSAD) { uSmallestSAD = uSAD[PRED16x16_PLANAR]; Best16x16Type = PRED16x16_PLANAR; } // Set MB type for smallest, fill PredBuf with predictors switch (Best16x16Type) { case PRED16x16_VERT: // copy from uVertPred to PredBuf, duplicating for each row of the MB for (row=0; row<16; row++) { memcpy(pPredBuf + row*16, uVertPred, 16); } break; case PRED16x16_HORZ: // copy from uHorizPred to PredBuf for (row=0; row<16; row++) { memset(pPredBuf+row*16, uHorizPred[row*4], 16); } break; case PRED16x16_DC: // set all prediction pels to the single predictor memset(pPredBuf, uDCPred[0], 256); break; case PRED16x16_PLANAR: // nothing to do, planar prediction already filled PredBuf break; default: assert(0); // Can't find a suitable intra prediction mode!!! break; } // switch *pMode = (T_AIMode)Best16x16Type; return uSmallestSAD;} // C_AIModeSelectOneMB_16x16//////////////////////////////////////////////////////////////////////////////////// C_AIModeSelectChromaMBs_8x8//// Choose the best intra mode for coding the U & V 8x8 MBs, return at// *pMode. Also return the combined SAD for the chosen mode. Also// save predictor pels for the MBs in provided buffer.//////////////////////////////////////////////////////////////////////////////////Ipp32u AIModeSelectChromaMBs_8x8( Ipp8u* pUSrc, // pointer to upper left pel of U source MB Ipp8u* pURef, // pointer to same MB in U reference picture Ipp8u* pVSrc, // pointer to upper left pel of V source MB Ipp8u* pVRef, // pointer to same MB in V reference picture Ipp32u uPitch, // of source and ref data Ipp32u uEdgeType, // MB on picture edge? Ipp32u available, // flags showing the available pixels around the MB Ipp8u *pMode, // selected mode goes here Ipp8u *pUPredBuf, // U predictor pels for selected mode go here Ipp8u *pVPredBuf // V predictor pels for selected mode go here ){ Ipp32u uSAD[4] = {0,0,0,0}; // MB SAD accumulators bool bOnTopEdge; bool bOnLeftEdge; bool bUpperLeftCorner; Ipp8u uVertPred[2][32]; // predictors from above, 2 4x4 Predictor blocks, U & V Ipp8u uHorizPred[2][32]; // predictors from left, 2 4x4 Predictor blocks, U & V Ipp8u uDCPred[2][64]; // DC prediction, 1 8x8 predictor block, U & V Ipp32u uSum[2][4] = { {0, 0, 0, 0}, {0, 0, 0, 0} }; // for DC, U & V - 4 predictors (a - d) each Ipp8u *pAbove; Ipp8u *pLeft; Ipp8u *pPred = 0; Ipp8u *pSrcBlock = 0; Ipp32u *pCopySrc; Ipp32u *pCopyDst; Ipp32u i, j, uBlock, plane; Ipp32u uSmallestSAD; Enum8x8PredType Best8x8Type; bOnTopEdge = 0 == (uEdgeType & MBEdgeTypeIsNotTopEdge); bOnLeftEdge = 0 == (uEdgeType & MBEdgeTypeIsNotLeftEdge); bUpperLeftCorner = 0 == (uEdgeType & MBEdgeTypeIsNotUpperLeftCorner); int topAvailable = !bOnTopEdge && (available&TOP_AVAILABLE) != 0; int leftAvailable = !bOnLeftEdge && (available&LEFT_AVAILABLE) != 0; // Initialize uVertPred with prediction from above if (!topAvailable) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -