📄 umc_h264_aic.cpp
字号:
// nothing above, set SAD very large uSAD[PRED8x8_VERT] = 0xffffffff; } else { for (plane = 0; plane < 2; plane++) { pAbove = plane ? pVRef - uPitch : pURef - uPitch; // Get predictors from above and // copy into 4x4 blocks for SAD calculations for (i=0; i<8; i++) { uVertPred[plane][i] = pAbove[i]; uSum[plane][i>>2] += pAbove[i]; // accumulate to A & B for DC predictor uSum[plane][2+(i>>2)] += pAbove[i]; // accumulate to C & D for DC predictor } // Now copy down to 3 more lines 32-bits at a time. pCopySrc = (Ipp32u *)&uVertPred[plane][0]; pCopyDst = (Ipp32u *)&uVertPred[plane][8]; for (i=0; i<3; i++) { *pCopyDst = *pCopySrc; *(pCopyDst+1) = *(pCopySrc+1); pCopyDst += 2; } } } // Initialize uHorizPred with prediction from left if (!leftAvailable) { // nothing to the left, set SAD very large uSAD[PRED8x8_HORZ] = 0xffffffff; } else { for (plane = 0; plane < 2; plane++) { Ipp32u tmpSum = uSum[plane][1]; uSum[plane][2] = 0; // Reset Block C to zero in this case. pLeft = plane ? pVRef - 1 : pURef - 1; // Get predictors from the left // and copy into 4x4 blocks for SAD calculations for (i=0; i<8; i++) { j = i*4; uSum[plane][2*(i>>2)] += *pLeft; // accumulate to A or C for DC predictor uSum[plane][2*(i>>2)+1] += *pLeft; // accumulate to B or D for DC predictor uHorizPred[plane][j] = *pLeft; uHorizPred[plane][j+1] = uHorizPred[plane][j+2] = uHorizPred[plane][j+3] = uHorizPred[plane][j]; pLeft += uPitch; } if (!bOnTopEdge) // Conditionally restore the previous sum uSum[plane][1] = tmpSum; // unless this is on the top edge } } // DC prediction, store predictor in all 64 pels of the predictor block // for each plane. if (!topAvailable && !leftAvailable) { memset(uDCPred, 128, 128); // Fill the 8x8 block, both Planes } else { for (plane = 0; plane < 2; plane++) { // Divide & round A & D properly, depending on how many terms // are in the sum. if (!(bOnTopEdge || bOnLeftEdge)) { // 8 Pixels uSum[plane][0] = (uSum[plane][0] + 4) >> 3; uSum[plane][3] = (uSum[plane][3] + 4) >> 3; } else { // 4 pixels uSum[plane][0] = (uSum[plane][0] + 2) >> 2; uSum[plane][3] = (uSum[plane][3] + 2) >> 2; } // Always 4 pixels uSum[plane][1] = (uSum[plane][1] + 2) >> 2; uSum[plane][2] = (uSum[plane][2] + 2) >> 2; // Fill the correct pixel values into the uDCPred buffer for (i = 0; i < 4; i++) { memset(&uDCPred[plane][8*i], (Ipp8u)uSum[plane][0], 4); memset(&uDCPred[plane][8*i+4], (Ipp8u)uSum[plane][1], 4); memset(&uDCPred[plane][32+8*i], (Ipp8u)uSum[plane][2], 4); memset(&uDCPred[plane][32+8*i+4], (Ipp8u)uSum[plane][3], 4); } } } // Get planar prediction, save 8x8 Ipp8u result at pPredBuf, if (topAvailable && leftAvailable && !bUpperLeftCorner) { PlanarPredictChroma(uEdgeType, pURef, uPitch, pUPredBuf); PlanarPredictChroma(uEdgeType, pVRef, uPitch, pVPredBuf); } else uSAD[PRED8x8_PLANAR] = 0xffffffff; // Mode select: Loop through all chroma blocks, accumulate a MB SAD for // each mode. for (plane=0; plane<2; plane++) { for (uBlock=0; uBlock<4; uBlock++) { if ((uBlock & 1) == 0) { // init pPlanarPred for new row of blocks pPred = plane ? pVPredBuf + uBlock*32 : pUPredBuf + uBlock*32; // Pitch is 16 pSrcBlock = plane ? pVSrc + uBlock*uPitch*2 : pUSrc + uBlock*uPitch*2; } uSAD[PRED8x8_DC] += SAD4x4Block4(pSrcBlock, uPitch, &uDCPred[plane][((uBlock>>1)*32)+((uBlock&1)*4)], 8); if (topAvailable) uSAD[PRED8x8_VERT] += SAD4x4Block4(pSrcBlock, uPitch, &uVertPred[plane][(uBlock & 1)*4], 8); if (leftAvailable) uSAD[PRED8x8_HORZ] += SAD4x4Block4(pSrcBlock, uPitch, &uHorizPred[plane][(uBlock>>1)*16], 4); if (topAvailable && leftAvailable && !bUpperLeftCorner) uSAD[PRED8x8_PLANAR] += SAD4x4Block4(pSrcBlock, uPitch, pPred, 16); // next block pSrcBlock += 4; pPred += 4; } } // choose smallest uSmallestSAD = uSAD[PRED8x8_DC]; Best8x8Type = PRED8x8_DC; if (uSAD[PRED8x8_VERT] < uSmallestSAD) { uSmallestSAD = uSAD[PRED8x8_VERT]; Best8x8Type = PRED8x8_VERT; } if (uSAD[PRED8x8_HORZ] < uSmallestSAD) { uSmallestSAD = uSAD[PRED8x8_HORZ]; Best8x8Type = PRED8x8_HORZ; } if (uSAD[PRED8x8_PLANAR] < uSmallestSAD) { uSmallestSAD = uSAD[PRED8x8_PLANAR]; Best8x8Type = PRED8x8_PLANAR; } // Set MB type for smallest, fill PredBuf with predictors switch (Best8x8Type) { case PRED8x8_VERT: for (plane=0; plane<2; plane++) { // Prediction from above, fill rows of prediction blocks with the // corresponding pels from above. pCopySrc = (Ipp32u *)uVertPred[plane]; pCopyDst = plane ? (Ipp32u *)pVPredBuf : (Ipp32u *)pUPredBuf; for (i=0; i<8; i++) { *pCopyDst = *pCopySrc; // 4 bytes left block *(pCopyDst + 1) = *(pCopySrc+1); // 4 bytes right block pCopyDst += 4; // pitch is 16 } } break; case PRED8x8_HORZ: for (plane=0; plane<2; plane++) { // Prediction from left. Fill rows of prediction blocks with the // corresponding pels from the left. pCopySrc = (Ipp32u *)uHorizPred[plane]; pCopyDst = plane ? (Ipp32u *)pVPredBuf : (Ipp32u *)pUPredBuf; for (i=0; i<8; i++) { *pCopyDst = *(pCopyDst + 1)= *pCopySrc; // 4 bytes left & right block pCopySrc++; pCopyDst += 4; // pitch is 16 } } break; case PRED8x8_DC: for (plane=0; plane<2; plane++) { // top row pPred = plane ? pVPredBuf : pUPredBuf; // Copy 8 rows pCopySrc = (Ipp32u *)uDCPred[plane]; pCopyDst = (Ipp32u *)pPred; for (i=0; i<8; i++) { *pCopyDst = *pCopySrc++; // 4 bytes left block *(pCopyDst + 1) = *pCopySrc++; // 4 bytes right block pCopyDst += 4; // pitch is 16 } } break; case PRED8x8_PLANAR: // nothing to do, planar prediction already filled PredBuf break; default: assert( 0 /*Can't find the best intra prediction 8x8!!!*/); break; } // switch *pMode = (Ipp8u)Best8x8Type; return uSmallestSAD;} // C_AIModeSelectChromaMBs_8x8//////////////////////////////////////////////////////////////////////////////////// PlanarPredictLuma [This function conforms with the JVT FCD, but the #if 0'd// version above is probably correct.]//// Find the planar prediction for this 16x16 MB, store at pPredBuf.//// Uses 15 pels from the reconstructed macroblock above and 15 pels from the// reconstructed macroblock to the left and 1 pel from the macroblock to the NW// to form a 16x16 prediction macroblock.//// L0,a0 a1 a2 a3 a4 a5 a6 a7 -- a9 a10 a11 a12 a13 a14 a15 a16// L1 x x x x x x x x x x x x x x x x// L2 x x x x x x x x x x x x x x x x// ...// L7 x x x x x x x x x x x x x x x x// -- x x x x x x x x x x x x x x x x// L9 x x x x x x x x x x x x x x x x// ...// L16 x x x x x x x x x x x x x x x x//// Above predictors are a0..a7 & a9..a16, left predictors are L0..L7 & L9..L15,// x indicates pels to be predicted.//// 1. Obtain weighted sum of differences of above predictors:// H = 8*(a16-a0) + 7*(a15-a1) + 6*(a14-a2) + ... + 1*(a9-a7)// 2. Obtain weighted sum of differences of left predictors:// V = 8*(L16-L0) + 7*(L15-L1) + 6*(L14-L2) + ... + 1*(L9-L7)// 3. Calculate a,b,c terms (level, horiz slope factor, vert slope factor):// a = (a16 + L16) *16// b = (5*H + 32) >> 6// c = (5*V + 32) >> 6// 4. Use a,b,c to calculate a predictor at each x,y of the 16x16 macroblock,// where x is horizontal index and y is vertical index:// pred = ((a + (i-7)*b + (j-7)*c) + 16)>>5//// Note this function will reference pels above and to the left of the// current macroblock so should not be called at top or left picture edge.//////////////////////////////////////////////////////////////////////////////////void PlanarPredictLuma( Ipp32u , // uEdgeType, // edge type for the macroblock Ipp8u* pBlock, // pointer to upper left pel of block Ipp32u uPitch, // of reference plane Ipp8u *pPredBuf){ Ipp8u ap[17], lp[17]; Ipp32s iH; Ipp32s iV; Ipp32s x, y; Ipp32s a,b,c; Ipp32s temp; for (x=0;x<17;x++) { ap[x]=(pBlock-Ipp32s(uPitch)-1)[x]; lp[x]=(pBlock+Ipp32s(uPitch)*(x-1))[-1]; } iH = 0; iV = 0; for (x=1; x<=8; x++) { iH += x*(ap[8+x] - ap[8-x]); iV += x*(lp[8+x] - lp[8-x]); } a = (ap[16] + lp[16])*16; b = (5*iH + 32)>>6; c = (5*iV + 32)>>6; for (y=0; y<16; y++) for (x=0; x<16; x++) { temp= (a+(x-7)*b+(y-7)*c+16)>>5; temp= (temp>255)?255:temp; temp= (temp<0)?0:temp; pPredBuf[x + y*16]=(Ipp8u) temp; }} // C_PlanarPredictLuma//////////////////////////////////////////////////////////////////////////////////// PlanarPredictChroma [This function conforms with the JVT FCD, but the #if 0'd// version above is probably correct.]//// Find the planar prediction for this 8x8 MB, store at pPredBuf.//// Uses 7 pels from the reconstructed macroblock above and 7 pels from the// reconstructed macroblock to the left and 1 pel from the macroblock to the NW// to form a 8x8 prediction macroblock.//// L0,a0 a1 a2 a3 -- a5 a6 a7 a8// L1 x x x x x x x x// L2 x x x x x x x x// L3 x x x x x x x x// -- x x x x x x x x// L5 x x x x x x x x// L6 x x x x x x x x// L7 x x x x x x x x// L8 x x x x x x x x//// Above predictors are a0..a3 & a5..a8, left predictors are L0..L3 & L5..L8,// x indicates pels to be predicted.//// 1. Obtain weighted sum of differences of above predictors:// H = 4*(a8-a0) + 3*(a7-a1) + 2*(a6-a2) + 1*(a5-a3)// 2. Obtain weighted sum of differences of left predictors:// V = 4*(L8-L0) + 3*(L7-L1) + 2*(L6-L2) + 1*(L5-L3)// 3. Calculate a,b,c terms (level, horiz slope factor, vert slope factor):// a = (a8 + L8) *16// b = (17*H + 16) >> 5// c = (17*V + 16) >> 5// 4. Use a,b,c to calculate a predictor at each i, j of the 8x8 macroblock,// where x is horizontal index and y is vertical index:// pred = ((a + (i-3)*b + (j-3)*c) + 16)>>5//// Note this function will reference pels above and to the left of the// current macroblock so should not be called at top or left picture edge.//////////////////////////////////////////////////////////////////////////////////void PlanarPredictChroma( Ipp32u , //uEdgeType, // edge type for the macroblock Ipp8u* pBlock, // pointer to upper left pel of block Ipp32u uPitch, // of reference plane Ipp8u *pPredBuf){ Ipp8u ap[9], lp[9]; Ipp32s iH; Ipp32s iV; Ipp32s i, j; Ipp32s a,b,c; Ipp32s temp; for (i=0;i<9;i++) { ap[i]=(pBlock-Ipp32s(uPitch)-1)[i]; lp[i]=(pBlock+Ipp32s(uPitch)*(i-1))[-1]; } iH = 0; iV = 0; for (i=1; i<=4; i++) { iH += i*(ap[4+i] - ap[4-i]); iV += i*(lp[4+i] - lp[4-i]); } a = (ap[8] + lp[8])*16; b = (17*iH + 16)>>5; c = (17*iV + 16)>>5; for (j=0; j<8; j++) for (i=0; i<8; i++) { temp= (a+(i-3)*b+(j-3)*c+16)>>5; temp= (temp>255)?255:temp; temp= (temp<0)?0:temp; pPredBuf[i + j*16]=(Ipp8u) temp; }} // C_PlanarPredictChroma} //namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -