📄 umc_h264_ermb.cpp
字号:
// so that they can be used by the 16x16 Intra Mode. *((Ipp32u*)pPredBuf) = SaveIntraPred[0]; *((Ipp32u*)(pPredBuf+16)) = SaveIntraPred[1]; *((Ipp32u*)(pPredBuf+32)) = SaveIntraPred[2]; *((Ipp32u*)(pPredBuf+48)) = SaveIntraPred[3]; return 0; // Bail and recode as Inter... }#endif //-------------------------------------------------------------------------- // encode U plane blocks (16-19) then V plane blocks (20-23) //-------------------------------------------------------------------------- m_pCurrentFrame->pMBData[uMB].uChromaNC = 0; uOffset = m_pCurrentFrame->pMBOffsets[uMB].uChromaOffset + m_pCurrentFrame->uv_line_shift; int left = m_pCurrentFrame->uMBxpos > 0; // shows whether pixels are available to the left of the MB. int top = m_pCurrentFrame->uMBypos > 0; // shows whether pixels are available above the MB. int available = (top<<1)|left; // Because JVT jointly codes the Intra prediction type for both // U and V MBs (they use the same type), we need to jointly determine // the best type, and save the predictor values for both in the // pPredBuf to be used below. This is OK, since this is typically used // as a 16x16 buffer and the U and V predictions are each 8x8 blocks. // The 8x8 blocks are stored U above V, and the buffer pitch is 16. AIModeSelectChromaMBs_8x8( m_pCurrentFrame->m_pUPlane + uOffset, m_pReconstructFrame->m_pUPlane + uOffset, m_pCurrentFrame->m_pVPlane + uOffset, m_pReconstructFrame->m_pVPlane + uOffset, uPitch, uMBEdgeType, available, &m_pCurrentFrame->pMBData[uMB].uChromaType, m_pCurrentFrame->pMBEncodeBuffer, m_pCurrentFrame->pMBEncodeBuffer+(8*16)); // initialize pointers for the U plane blocks Ipp32u uLastBlock = 20; pSrcPlane = m_pCurrentFrame->m_pUPlane; pRecPlane = m_pReconstructFrame->m_pUPlane; // encode first chroma U plane then V plane do { T_NumCoeffs *pNumCoeffs; // This holds pointer to appropriate array uOffset = m_pCurrentFrame->pMBOffsets[uMB].uChromaOffset + m_pCurrentFrame->uv_line_shift; uIndex = m_pCurrentFrame->pMBOffsets[uMB].uFirstChromaBlockIndex; // Adjust the pPredBuf to point at the V plane predictor when appropriate: // (blocks 20-23 and an INTRA Y plane mode...) if (uBlock == 20) { pPredBuf = m_pCurrentFrame->pMBEncodeBuffer+(8*16); RLE_Offset = V_DC_RLE; pNumCoeffs = m_pCurrentFrame->pVNumCoeffs; } else { pPredBuf = m_pCurrentFrame->pMBEncodeBuffer; RLE_Offset = U_DC_RLE; pNumCoeffs = m_pCurrentFrame->pUNumCoeffs; } // Process the 2x2 block of DC coeffs // "pre-Calc" DC coeffs ippiSumsDiff8x8Blocks4x4_8u16s_C1( pSrcPlane + uOffset, // source pels uPitch, // source pitch pPredBuf, // predictor pels 16, pDCBuf, // result buffer pMassDiffBuf); // 2x2 forward transform ippiTransformQuantChromaDC_H264_16s_C1I(pDCBuf, pQBuf,QPtoChromaQP[uMBQP],&iNumCoeffs,(m_SliceHeader.slice_type == INTRASLICE),1); // DC values in this block if iNonEmpty is 1. m_pCurrentFrame->pMBData[uMB].uChromaNC |= (iNumCoeffs != 0); // record RLE info if (m_PicParamSet.entropy_coding_mode) { int ctxIdxBlockCat = BLOCK_CHROMA_DC_LEVELS; ScanSignificant_CABAC(pDCBuf,ctxIdxBlockCat,4,dec_single_scan_p,&m_pCurrentFrame->Block_CABAC[RLE_Offset]); bCoded = m_pCurrentFrame->Block_CABAC[RLE_Offset].uNumSigCoeffs; } else { ippiEncodeChromaDcCoeffsCAVLC_H264_16s ( pDCBuf, &m_pCurrentFrame->Block_RLE[RLE_Offset].uTrailing_Ones, &m_pCurrentFrame->Block_RLE[RLE_Offset].uTrailing_One_Signs, &m_pCurrentFrame->Block_RLE[RLE_Offset].uNumCoeffs, &m_pCurrentFrame->Block_RLE[RLE_Offset].uTotalZeros, m_pCurrentFrame->Block_RLE[RLE_Offset].iLevels, m_pCurrentFrame->Block_RLE[RLE_Offset].uRuns); bCoded = m_pCurrentFrame->Block_RLE[RLE_Offset].uNumCoeffs; } //bCoded =RLE( // pDCBuf, // quantized coeffs in scan order // 4, // number of coeffs // &m_pCurrentFrame->Block_RLE[RLE_Offset] // where to put RLE data // ); ippiTransformDequantChromaDC_H264_16s_C1I (pDCBuf, QPtoChromaQP[uMBQP]); // loop over all 4x4 blocks in one chroma plane for the MB for (; uBlock < uLastBlock; uBlock ++) { pNumCoeffs[uIndex] = 0; // This will be updated if the block is coded if (m_PicParamSet.entropy_coding_mode) { m_pCurrentFrame->Block_CABAC[uBlock].uNumSigCoeffs = 0; } else { m_pCurrentFrame->Block_RLE[uBlock].uNumCoeffs = 0; m_pCurrentFrame->Block_RLE[uBlock].uTrailing_Ones = 0; m_pCurrentFrame->Block_RLE[uBlock].uTrailing_One_Signs = 0; m_pCurrentFrame->Block_RLE[uBlock].uTotalZeros = 15; } // check if block is coded bCoded = ((uCBP4x4 & CBP4x4Mask[uBlock])?(1):(0)); if (!bCoded) { // update reconstruct frame for the empty block Copy4x4( pPredBuf, // predictor block uPitch, pRecPlane + uOffset); // reconstruct frame } else { // block not declared empty, encode // compute difference of predictor and source pels // note: asm version does not used pDiffBuf // output is being passed in the mmx registers //Diff4x4( // pPredBuf, // predictor pels // pSrcPlane + uOffset, // source pels // uPitch, // source pitch // pDiffBuf); // result buffer // forward transform, in place in iDiffBuf // note: asm version does not used pDiffBuf // input and output are being passed in the mmx reg.s // quantization and dequantization // note: asm version does not used pDiffBuf and pDQBuf // these values are being passed in the mmx registers //ippiQuantTransformResidual_H264_16s_C1I(pDiffBuf,uMBQP,&iNumCoeffs,&uLastCoeff,(m_SliceHeader.slice_type == INTRASLICE)); pTempDiffBuf = pMassDiffBuf+(uBlock-uLastBlock+4)*16; ippiTransformQuantResidual_H264_16s_C1I(pTempDiffBuf,uMBQP,&iNumCoeffs,(m_SliceHeader.slice_type == INTRASLICE), enc_single_scan[m_PicParamSet.picture_structure != FRAME_PICTURE],&uLastCoeff); // if everything quantized to zero, skip RLE if (!((iNumCoeffs < -1) || (iNumCoeffs > 0))) { // the block is empty so it is not coded bCoded = 0; } else { // AC Values if iNonEmpty is not 0 or -1 m_pCurrentFrame->pMBData[uMB].uChromaNC |= 2*((iNumCoeffs < -1) || (iNumCoeffs > 0)); // Preserve the absolute number of coeffs. pNumCoeffs[uIndex] = (T_NumCoeffs)((iNumCoeffs < 0) ? -(iNumCoeffs+1) : iNumCoeffs); // record RLE info if (m_PicParamSet.entropy_coding_mode) { int ctxIdxBlockCat = BLOCK_CHROMA_AC_LEVELS; ScanSignificant_CABAC(pTempDiffBuf,ctxIdxBlockCat,15, dec_single_scan[m_PicParamSet.picture_structure != FRAME_PICTURE], &m_pCurrentFrame->Block_CABAC[uBlock]); bCoded = m_pCurrentFrame->Block_CABAC[uBlock].uNumSigCoeffs; } else { ippiEncodeCoeffsCAVLC_H264_16s ( pTempDiffBuf,// pDiffBuf, 1, dec_single_scan[m_PicParamSet.picture_structure != FRAME_PICTURE], uLastCoeff, &m_pCurrentFrame->Block_RLE[uBlock].uTrailing_Ones, &m_pCurrentFrame->Block_RLE[uBlock].uTrailing_One_Signs, &m_pCurrentFrame->Block_RLE[uBlock].uNumCoeffs, &m_pCurrentFrame->Block_RLE[uBlock].uTotalZeros, m_pCurrentFrame->Block_RLE[uBlock].iLevels, m_pCurrentFrame->Block_RLE[uBlock].uRuns); pNumCoeffs[uIndex] = bCoded = m_pCurrentFrame->Block_RLE[uBlock].uNumCoeffs; } //bCoded = RLE( // pDiffBuf, // quantized coeffs in scan order // 15, // number of coeffs // &m_pCurrentFrame->Block_RLE[uBlock] // where to put RLE data // ); } // If the block wasn't coded and the DC coefficient is zero if (!bCoded && !pDCBuf[uBlock & 3]) { // block quantized to empty, update flags uCBP4x4 &= ~CBP4x4Mask[uBlock]; // update reconstruct frame for the empty block Copy4x4( pPredBuf, // predictor block uPitch, pRecPlane + uOffset); // reconstruct frame } else { // inverse transform AND... // add inverse transformed coefficients to original predictor // to obtain reconstructed block, store in reconstruct frame // buffer ippiDequantTransformResidualAndAdd_H264_16s_C1I ( pPredBuf, pTempDiffBuf,// pDiffBuf, &pDCBuf[uBlock & 3], pRecPlane + uOffset, 16, uPitch, QPtoChromaQP[uMBQP], ((iNumCoeffs < -1) || (iNumCoeffs > 0))); } } // block not declared empty // next block offset uOffset += m_EncBlockOffsetInc[uBlock]; // next index uIndex += (uBlock&1) ? (uWidthIn4x4Blocks>>1)-1 : 1; // advance pPredBuf by 4 after chroma block 0 and 2; and by // 3*16+12 (row pitch is 16) after block 1. pPredBuf += 4 + (uBlock&1)*(3*16+8); } // for uBlock in chroma plane if (uBlock == 20) { // initialize pointers for the V plane blocks uLastBlock = 24; pSrcPlane = m_pCurrentFrame->m_pVPlane; pRecPlane = m_pReconstructFrame->m_pVPlane; } } while (uBlock < 24); // update coded block flags m_pCurrentFrame->pMBData[uMB].uCBP4x4 = uCBP4x4; if (m_pCurrentFrame->pMBData[uMB].uChromaNC == 3) m_pCurrentFrame->pMBData[uMB].uChromaNC = 2; // for each block of the MB initialize the AI mode (for INTER MB) // or motion vectors (for INTRA MB) to values which will be // correct predictors of that type. MV and AI mode prediction // depend upon this instead of checking MB type. T_ECORE_MV NullMV = {0, 0}; T_ECORE_BIGMV NullDMV = {0, 0}; uIndex = m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex; for (Ipp32u i = 0; i < 16; i ++) { m_pCurrentFrame->pMVL0[uIndex] = NullMV; m_pCurrentFrame->pMVL1[uIndex] = NullMV; m_pCurrentFrame->pDMVL0[uIndex] = NullDMV; m_pCurrentFrame->pDMVL1[uIndex] = NullDMV; m_pCurrentFrame->pRefIdxL0[uIndex] = -1; m_pCurrentFrame->pRefIdxL1[uIndex] = -1; uIndex += m_EncBlockIndexInc[i]; } return 1;} // CEncAndRec4x4IntraMB////////////////////////////////////////////////////////////////////////////////// CEncAndRec16x16IntraMB//// Encode and Reconstruct all blocks in one 16x16 Intra macroblock//////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -