📄 umc_h264_aic.cpp
字号:
Ipp32s N; Ipp8u* pSrcPlane; // start of plane to encode Ipp8u* pRecPlane; // start of reconstructed plane Ipp32u uPitch; // buffer pitch Ipp32u uOffset; // to upper left corner of block from start of plane // Encode MB_Type N = CALC_PCM_MB_TYPE(m_SliceHeader.slice_type); length = m_pbitstream->PutVLCCode(N); // Write the pcm_alignment bit(s) if necessary. m_pbitstream->ByteAlignWithOnes(); // Now, write the pcm_bytes and update the reconstructed buffer... uOffset = m_pCurrentFrame->pMBOffsets[uMB].uLumaOffset + m_pCurrentFrame->y_line_shift; pSrcPlane = &m_pCurrentFrame->m_pYPlane[uOffset]; pRecPlane = &m_pReconstructFrame->m_pYPlane[uOffset]; uPitch = m_pCurrentFrame->uPitch; // Y plane first for (row=0; row<16; row++) { for (col=0; col<16; col++) { if (!pSrcPlane[col]) // Replace forbidden zero samples with 1. pSrcPlane[col] = 1; // Write sample to BS m_pbitstream->PutBits(pSrcPlane[col], 8); } memcpy(pRecPlane, pSrcPlane, 16); // Copy row to reconstructed buffer pSrcPlane += uPitch; pRecPlane += uPitch; } uOffset = m_pCurrentFrame->pMBOffsets[uMB].uChromaOffset + m_pCurrentFrame->uv_line_shift; pSrcPlane = &m_pCurrentFrame->m_pUPlane[uOffset]; pRecPlane = &m_pReconstructFrame->m_pUPlane[uOffset]; // U plane next for (row=0; row<8; row++) { for (col=0; col<8; col++) { if (!pSrcPlane[col]) // Replace forbidden zero samples with 1. pSrcPlane[col] = 1; // Write sample to BS m_pbitstream->PutBits(pSrcPlane[col], 8); } memcpy(pRecPlane, pSrcPlane, 8); // Copy row to reconstructed buffer pSrcPlane += uPitch; pRecPlane += uPitch; } pSrcPlane = &m_pCurrentFrame->m_pVPlane[uOffset]; pRecPlane = &m_pReconstructFrame->m_pVPlane[uOffset]; // V plane last for (row=0; row<8; row++) { for (col=0; col<8; col++) { if (!pSrcPlane[col]) // Replace forbidden zero samples with 1. pSrcPlane[col] = 1; // Write sample to BS m_pbitstream->PutBits(pSrcPlane[col], 8); } memcpy(pRecPlane, pSrcPlane, 8); // Copy row to reconstructed buffer pSrcPlane += uPitch; pRecPlane += uPitch; }} // Encode_PCM_MBstatic const Ipp8u uBlockURPredOK[] = { // luma 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0xff, 0, 0xff, 0, 0xff, 0};// lookup table indexed by block number, return true if block is on the// right edge of the macroblockstatic const bool bBlockOnRightEdge[] = { // luma false, false, false, false, false, true, false, true, false, false, false, false, false, true, false, true,};//////////////////////////////////////////////////////////////////////////////////// GetBlockPredPels//// Obtains the above and left prediction pels for the 4x4 block,// following edge rules.//// The prediction pel buffer is ordered as follows://// [0]: M// [1..8]: A..H// [9..12] I..L//// Predictors M and E..H are used only for the diagonal modes// (modes 3 and greater).//////////////////////////////////////////////////////////////////////////////////static void GetBlockPredPels( Ipp32u uEdgeType, // edge type for the block Ipp8u* pRefBlock, // pointer to block in reference picture Ipp32u uPitch, // of source data Ipp32u uBlock, // 0..15 for luma blocks only Ipp8u* PredPel // result here ){ bool bLeft, bTop; bool bRight; Ipp32s i; bLeft = (uEdgeType & MBEdgeTypeIsNotLeftEdge) == 0; bTop = (uEdgeType & MBEdgeTypeIsNotTopEdge) == 0; // get predictor pels from above and left blocks, following edge rules if (bTop && bLeft) { P_A = P_B = P_C = P_D = 128; P_I = P_J = P_K = P_L = 128; } else if (bTop && !bLeft) { for (i = 0; i < 4; i++) { PredPel[i+1] = PredPel[i+9] = (pRefBlock + i*uPitch)[-1]; } } else if (!bTop && bLeft) { for (i = 0; i < 4; i++) { PredPel[i+1] = PredPel[i+9] =(pRefBlock - uPitch)[i]; } } else { for (i = 0; i < 4; i++) { PredPel[i+1] = (pRefBlock - uPitch)[i]; PredPel[i+9] = (pRefBlock + i*uPitch)[-1]; } // for diagonal modes P_M = (pRefBlock - uPitch)[-1]; } if (!bTop) { // Get EFGH, predictors pels above and to the right of the block. // Use D when EFGH are not valid, which is when the block is on // the right edge of the MB and the MB is at the right edge of // the picture; or when the block is on the right edge of the MB // but not in the top row. bRight = (uEdgeType & MBEdgeTypeIsNotRightEdge) == 0; if (uBlockURPredOK[uBlock] == 0 || (bRight && bBlockOnRightEdge[uBlock])) { P_E = P_F = P_G = P_H = P_D; } else { P_E = (pRefBlock - uPitch)[4]; P_F = (pRefBlock - uPitch)[5]; P_G = (pRefBlock - uPitch)[6]; P_H = (pRefBlock - uPitch)[7]; } }} // GetBlockPredPels//////////////////////////////////////////////////////////////////////////////////// GetPredBlock//// Find advanced intra prediction block, store in PredBuf, which has a pitch// of sizeof(Ipp8u)*16.//////////////////////////////////////////////////////////////////////////////////static void GetPredBlock( Ipp32u uMode, // advanced intra mode of the block Ipp8u *pPredBuf, Ipp8u* PredPel // predictor pels ){ Ipp32u i, j, sum; Ipp8u u8PredVal; // for the specified mode create the prediction block from the predictor // pels switch (uMode) { case 0: // mode 0: vertical prediction (from above) for (j = 0; j < 4; j++) { for (i = 0; i < 4; i++) { pPredBuf[i] = PredPel[i+1]; // ABCD } pPredBuf += 16; } break; case 1: // mode 1: horizontal prediction (from left) for (j = 0; j < 4; j++) { for (i = 0; i < 4; i++) { pPredBuf[i] = PredPel[j+9]; // IJKL } pPredBuf += 16; } break; case 2: // mode 2: DC prediction sum = 0; for (i = 0; i < 4; i++) { sum += PredPel[i+9]; // IJKL sum += PredPel[i+1]; // ABCD } u8PredVal = (Ipp8u)((sum + 4) / 8); for (j = 0; j < 4; j++) { for (i = 0; i < 4; i++) { // Warning: The WinCE compiler generated incorrect code (storing // predictor in the first byte only) when the following line of // code was: // pPredBuf[i] = (Ipp8u)sum; pPredBuf[i] = u8PredVal; } pPredBuf += 16; } break; case 3: // mode 3: diagonal down/left prediction P_a = (P_A + ((P_B) << 1) + P_C + 2) >> 2; P_b = P_e = (P_B + ((P_C) << 1) + P_D + 2) >> 2; P_c = P_f = P_i = (P_C + ((P_D) << 1) + P_E + 2) >> 2; P_d = P_g = P_j = P_m = (P_D + ((P_E) << 1) + P_F + 2) >> 2; P_h = P_k = P_n = (P_E + ((P_F) << 1) + P_G + 2) >> 2; P_l = P_o = (P_F + ((P_G) << 1) + P_H + 2) >> 2; P_p = (P_G + ((P_H) << 1) + P_H + 2) >> 2; break; case 4: // mode 4: diagonal down/right prediction P_m = (P_J + ((P_K) << 1) + P_L + 2) >> 2; P_i = P_n = (P_I + ((P_J) << 1) + P_K + 2) >> 2; P_e = P_j = P_o = (P_M + ((P_I) << 1) + P_J + 2) >> 2; P_a = P_f = P_k = P_p = (P_A + ((P_M) << 1) + P_I + 2) >> 2; P_b = P_g = P_l = (P_M + ((P_A) << 1) + P_B + 2) >> 2; P_c = P_h = (P_A + ((P_B) << 1) + P_C + 2) >> 2; P_d = (P_B + ((P_C) << 1) + P_D + 2) >> 2; break; case 5 : // mode 5: vertical-right prediction P_a = P_j = (P_M + P_A + 1) >> 1; P_b = P_k = (P_A + P_B + 1) >> 1; P_c = P_l = (P_B + P_C + 1) >> 1; P_d = (P_C + P_D + 1) >> 1; P_e = P_n = (P_I + ((P_M) << 1) + P_A + 2) >> 2; P_f = P_o = (P_M + ((P_A) << 1) + P_B + 2) >> 2; P_g = P_p = (P_A + ((P_B) << 1) + P_C + 2) >> 2; P_h = (P_B + ((P_C) << 1) + P_D + 2) >> 2; P_i = (P_M + ((P_I) << 1) + P_J + 2) >> 2; P_m = (P_I + ((P_J) << 1) + P_K + 2) >> 2; break; case 6 : // mode 6: horizontal-down prediction P_a = P_g = (P_M + P_I + 1) >> 1; P_b = P_h = (P_I + ((P_M) << 1) + P_A + 2) >> 2; P_c = (P_M + ((P_A) << 1) + P_B + 2) >> 2; P_d = (P_A + ((P_B) << 1) + P_C + 2) >> 2; P_e = P_k = (P_I + P_J + 1) >> 1; P_f = P_l = (P_M + ((P_I) << 1) + P_J + 2) >> 2; P_i = P_o = (P_J + P_K + 1) >> 1; P_j = P_p = (P_I + ((P_J) << 1) + P_K + 2) >> 2; P_m = (P_K + P_L + 1) >> 1; P_n = (P_J + ((P_K) << 1) + P_L + 2) >> 2; break; case 7 : // mode 7: vertical-left prediction P_a = (P_A + P_B + 1) >> 1; P_b = P_i = (P_B + P_C + 1) >> 1; P_c = P_j = (P_C + P_D + 1) >> 1; P_d = P_k = (P_D + P_E + 1) >> 1; P_l = (P_E + P_F + 1) >> 1; P_e = (P_A + ((P_B) << 1) + P_C + 2) >> 2; P_f = P_m = (P_B + ((P_C) << 1) + P_D + 2) >> 2; P_g = P_n = (P_C + ((P_D) << 1) + P_E + 2) >> 2; P_h = P_o = (P_D + ((P_E) << 1) + P_F + 2) >> 2; P_p = (P_E + ((P_F) << 1) + P_G + 2) >> 2; break; case 8 : // mode 8: horizontal-up prediction P_a = (P_I + P_J + 1) >> 1; P_b = (P_I + ((P_J) << 1) + P_K + 2) >> 2; P_c = P_e = (P_J + P_K + 1) >> 1; P_d = P_f = (P_J + ((P_K) << 1) + P_L + 2) >> 2; P_g = P_i = (P_K + P_L + 1) >> 1; P_h = P_j = (P_K + ((P_L) << 1) + P_L + 2) >> 2; P_k = P_l = P_m = P_n = P_o = P_p = (P_L); break; default: break; } // switch} // GetPredBlock//////////////////////////////////////////////////////////////////////////////////// AIPredictBlock//// Find advanced intra prediction block, store in PredBuf, which has a pitch// of sizeof(Ipp8u)*16.//////////////////////////////////////////////////////////////////////////////////void C_AIPredictBlock( Ipp32u uMode, // advanced intra mode of the block Ipp32u uEdgeType, // edge type for the block Ipp32u uBlock, Ipp8u* pBlock, // pointer to upper left pel of block Ipp32u uPitch, // of reference plane Ipp8u *pPredBuf ){ Ipp8u PredPel[13]; // Get the above and left predictor pels to PredPel GetBlockPredPels(uEdgeType, pBlock, uPitch, uBlock, PredPel); // get predictor block to PrebBuf GetPredBlock(uMode, pPredBuf, PredPel);} // C_AIPredictBlock//////////////////////////////////////////////////////////////////////////////////// AIModeSelectOneBlock//// Choose the best advanced intra mode for coding one block, store at// *pMode. Also return the RD-adjusted SAD for the chosen mode. Also// save predictor pels in provided buffer when the buffer pointer is// not NULL.//// Used both in ME phase, for INTRA/INTER decision using original source// pels for predictors, and later in block encoding using reconstructed// pels for predictors.////// In the ME phase (signaled by pPred==NULL) only modes 0,1,2 are checked// in the interest of CPU performance. The resulting best SAD is good enough// for MB mode selection.//////////////////////////////////////////////////////////////////////////////////#define UNINITIALIZED 999999Ipp32u AIModeSelectOneBlock( T_4x4IntraModeSelParams *pModeSelParams, Ipp8u* pSrcBlock, // pointer to upper left pel of source block Ipp8u* pRefBlock, // pointer to same block in reference picture Ipp32u uBlock, // which 4x4 of the MB (0..15) T_AIMode *pMode, // selected mode goes here Ipp8u *pPred // predictor pels for selected mode goes here // if not NULL ){ Ipp32u uSAD; Ipp32u uEdgeType; // edge type for the block T_AIMode Mode, ModeAbove, ModeLeft, ProbMode; Ipp32u uMinSAD; Ipp8u uPred[16*NUM_AI_MODES*4]; // predictor pels, all modes, each 4 rows, pitch=16 Ipp8u uProb; Ipp32s check_num_modes; Ipp8u PredPel[13];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -