📄 umc_h264_ermb.cpp
字号:
// update flags if block quantized to empty
if (curr_slice->m_use_transform_for_intra_decision) {
if (!bCoded) {
uCBPLuma &= ~CBP4x4Mask[uBlock];
}
// TODO: ????? What should we copy here ????? SB
// Why in both cases (CODED/NOT CODED the same is copied????
#ifdef H264_RD_OPT
#else
Copy4x4(pPredBuf + 256, 16*sizeof(PixType), pReconBuf, pitchPix*sizeof(PixType));
#endif
} else {
if (!bCoded){
uCBPLuma &= ~CBP4x4Mask[uBlock];
// update reconstruct frame for the empty block
Copy4x4(pPredBuf, 16*sizeof(PixType), pReconBuf, pitchPix*sizeof(PixType));
} else if(!transform_bypass) {
// inverse transform for reconstruct AND...
// add inverse transformed coefficients to original predictor
// to obtain reconstructed block, store in reconstruct frame
// buffer
ippiDequantTransformResidualAndAdd_H264(pPredBuf,
pTransformResult,
NULL,
pReconBuf,
16,
pitchPix,
uMBQP,
((iNumCoeffs < -1) || (iNumCoeffs > 0)),
m_PicParamSet.bit_depth_luma);
}
}
} // block not declared empty
// proceed to the next block
uOffset += m_EncBlockOffsetInc[is_cur_mb_field][uBlock];
} // for uBlock in luma plane
}
#if defined TRACE_INTRA
if(uMB == TRACE_INTRA) {
printMatr(m_pReconstructFrame->m_pYPlane + m_pMBOffsets[uMB].uLumaOffset[m_is_cur_pic_afrm][is_cur_mb_field], pitchPixels, 16, 16, 0, "RecPlane");
}
#endif // TRACE_INTRA
// update coded block flags
cur_mb.LocalMacroblockInfo->cbp_luma = uCBPLuma;
// 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.
return 1;
} // CEncAndRec4x4IntraMB
////////////////////////////////////////////////////////////////////////////////
// CEncAndRec16x16IntraMB
//
// Encode and Reconstruct all blocks in one 16x16 Intra macroblock
//
////////////////////////////////////////////////////////////////////////////////
template <class PixType, class CoeffsType>
Ipp32u H264CoreEncoder<PixType, CoeffsType>::CEncAndRec16x16IntraMB(H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice)
{
Ipp32u uBlock; // block number, 0 to 23
Ipp32u uOffset; // to upper left corner of block from start of plane
Ipp32u uMBQP; // QP of current MB
Ipp32u uMB;
Ipp32u uCBPLuma; // coded flags for all 4x4 blocks
Ipp32u uCBPChroma; // coded flags for all chroma blocks
Ipp32u uIntraSAD; // intra MB SAD
CoeffsType* pDCBuf; // chroma & luma dc coeffs pointer
PixType* pPredBuf; // prediction block pointer
PixType* pReconBuf; // prediction block pointer
Ipp16s* pDiffBuf; // difference block pointer
Ipp16s* pTempDiffBuf; // difference block pointer
CoeffsType *pTransformResult; // for transform results.
Ipp16s* pMassDiffBuf; // difference block pointer
CoeffsType* pQBuf; // quantized block pointer
PixType* pSrcPlane; // start of plane to encode
Ipp32s pitchPixels; // buffer pitch in pixels
Ipp8u bCoded; // coded block flag
Ipp32s iNumCoeffs; // Number of nonzero coeffs after quant (negative if DC is nonzero)
Ipp32s iLastCoeff; // Number of nonzero coeffs after quant (negative if DC is nonzero)
Ipp32u RLE_Offset; // Index into BlockRLE array
H264CurrentMacroblockDescriptor<PixType, CoeffsType> &cur_mb = curr_slice->m_cur_mb;
Ipp32s is_cur_mb_field = curr_slice->m_is_cur_mb_field;
EnumSliceType slice_type = curr_slice->m_slice_type;
pitchPixels = cur_mb.mbPitchPixels;
uCBPLuma = cur_mb.LocalMacroblockInfo->cbp_luma;
uCBPChroma = cur_mb.LocalMacroblockInfo->cbp_chroma;
uMBQP = getLumaQP(cur_mb.LocalMacroblockInfo->QP, m_PicParamSet.bit_depth_luma);
pDiffBuf = (Ipp16s*) (curr_slice->m_pMBEncodeBuffer + 512);
pTransformResult = (CoeffsType*)(pDiffBuf + 16);
pQBuf = (CoeffsType*) (pTransformResult + 16);
pDCBuf = (CoeffsType*) (pQBuf + 16); // Used for both luma and chroma DC blocks
pMassDiffBuf = (Ipp16s*) (pDCBuf + 16);
// uIntraSAD = rd_quant_intra[uMBQP] * 24; // 'handicap' using reconstructed data
uIntraSAD = 0;
uMB = cur_mb.uMB;
bool transform_bypass = m_SeqParamSet.qpprime_y_zero_transform_bypass_flag && uMBQP == 0;
//--------------------------------------------------------------------------
// encode Y plane blocks (0-15)
//--------------------------------------------------------------------------
// initialize pointers and offset
pSrcPlane = m_pCurrentFrame->m_pYPlane;
uOffset = m_pMBOffsets[uMB].uLumaOffset[m_is_cur_pic_afrm][is_cur_mb_field];
RLE_Offset = Y_DC_RLE; // Used in 16x16 Intra mode only
pPredBuf = cur_mb.mb16x16.prediction; // 16-byte aligned work buffer
Ipp32s pitchPix;
#ifdef H264_RD_OPT
pReconBuf = cur_mb.mb16x16.reconstruct; // 16-byte aligned work buffer
pitchPix = 16;
#else
pReconBuf = m_pReconstructFrame->m_pYPlane; // 16-byte aligned work buffer
pitchPix = pitchPixels;
#endif
// for INTRA 16x16 MBs computation of luma prediction was done as
// a byproduct of sad calculation prior to this function being
// called; the predictor blocks are already at pPredBuf.
// Initialize the AC coeff flag value
cur_mb.MacroblockCoeffsInfo->lumaAC = 0;
// compute the 4x4 luma DC transform coeffs
ippiSumsDiff16x16Blocks4x4(pSrcPlane + uOffset, pitchPixels, pPredBuf, 16, pDCBuf, pMassDiffBuf);
#if defined TRACE_INTRA_16X16
if(uMB == TRACE_INTRA_16X16) {
printf("ermb 16x16 intra: uMB = %d, tr_bypass = %d, uCBPLuma = %d\n", uMB, transform_bypass, uCBPLuma);
printMatr(pSrcPlane + uOffset, pitchPixels, 16, 16, 0, "SrcPlane");
printMatr(pPredBuf, 16, 16, 16, 0, "PredBuf");
printMatr(pDCBuf, 16, 1, 16, 0, "DC");
printMatr(pMassDiffBuf, 4, 64, 4, 0, "MassDiff");
}
#endif // TRACE_INTRA_16X16
if(!transform_bypass) {
// apply second transform on the luma DC transform coeffs
ippiTransformQuantLumaDC_H264(pDCBuf,pQBuf,uMBQP,&iNumCoeffs,1, enc_single_scan[is_cur_mb_field],&iLastCoeff);
}else {
for(Ipp32s i = 0; i < 4; i++) {
for(Ipp32s j = 0; j < 4; j++) {
Ipp32s x, y;
x = j*16;
y = i*64;
pDCBuf[i*4 + j] = pMassDiffBuf[x+y];
}
}
ippiCountCoeffs(pDCBuf, &iNumCoeffs, enc_single_scan[is_cur_mb_field], &iLastCoeff, 16);
}
#if defined TRACE_INTRA_16X16
if(uMB == TRACE_INTRA_16X16) {
printMatr(pDCBuf, pitchPixels, 1, 16, 0, "DC modified");
}
#endif // TRACE_INTRA_16X16
// insert the quantized luma Ipp64f transform DC coeffs into
// RLE buffer
// record RLE info
if (m_PicParamSet.entropy_coding_mode)
{
Ipp32s ctxIdxBlockCat = BLOCK_LUMA_DC_LEVELS;
ScanSignificant_CABAC(pDCBuf,ctxIdxBlockCat,16,
dec_single_scan[is_cur_mb_field],
&curr_slice->Block_CABAC[RLE_Offset]);
bCoded = curr_slice->Block_CABAC[RLE_Offset].uNumSigCoeffs;
}
else
{
ippiEncodeCoeffsCAVLC_H264(pDCBuf,
0,
dec_single_scan[is_cur_mb_field],
iLastCoeff,
&curr_slice->Block_RLE[RLE_Offset].uTrailing_Ones,
&curr_slice->Block_RLE[RLE_Offset].uTrailing_One_Signs,
&curr_slice->Block_RLE[RLE_Offset].uNumCoeffs,
&curr_slice->Block_RLE[RLE_Offset].uTotalZeros,
curr_slice->Block_RLE[RLE_Offset].iLevels,
curr_slice->Block_RLE[RLE_Offset].uRuns);
bCoded = curr_slice->Block_RLE[RLE_Offset].uNumCoeffs;
}
if(!transform_bypass) {
ippiTransformDequantLumaDC_H264(pDCBuf, uMBQP);
}
// loop over all 4x4 blocks in Y plane for the MB
for (uBlock = 0; uBlock < 16; uBlock++ ){
pPredBuf = cur_mb.mb16x16.prediction + xoff[uBlock] + yoff[uBlock]*16;
#ifdef H264_RD_OPT
pReconBuf = cur_mb.mb16x16.reconstruct + xoff[uBlock] + yoff[uBlock]*16;
#else
pReconBuf = m_pReconstructFrame->m_pYPlane+uOffset;
#endif
cur_mb.MacroblockCoeffsInfo->numCoeff[uBlock] = 0; // This will be updated if the block is coded
if (m_PicParamSet.entropy_coding_mode) {
curr_slice->Block_CABAC[uBlock].uNumSigCoeffs = 0;
} else {
curr_slice->Block_RLE[uBlock].uNumCoeffs = 0;
curr_slice->Block_RLE[uBlock].uTrailing_Ones = 0;
curr_slice->Block_RLE[uBlock].uTrailing_One_Signs = 0;
curr_slice->Block_RLE[uBlock].uTotalZeros = 15;
}
// check if block is coded
bCoded = ((uCBPLuma & CBP4x4Mask[uBlock])?(1):(0));
if (!bCoded){
// update reconstruct frame for the empty block
Copy4x4(pPredBuf, 16*sizeof(PixType), pReconBuf, pitchPix*sizeof(PixType));
}else{ // block not declared empty, encode
pTempDiffBuf = pMassDiffBuf+ xoff[uBlock]*4 + yoff[uBlock]*16;
if(!transform_bypass) {
ippiTransformQuantResidual_H264(pTempDiffBuf, pTransformResult, uMBQP,&iNumCoeffs,(slice_type == INTRASLICE),
enc_single_scan[is_cur_mb_field],&iLastCoeff);
}else{
for(Ipp32s i = 0; i < 16; i++){
pTransformResult[i] = pTempDiffBuf[i];
}
ippiCountCoeffs(pTransformResult, &iNumCoeffs, enc_single_scan[is_cur_mb_field], &iLastCoeff, 16);
}
// restore luma DC transform coeff if 16x16 intra mode
// Also, saves the value of iNonEmpty for later use
// TBD: Maybe this should be part of QDQ or RLE?
cur_mb.MacroblockCoeffsInfo->lumaAC |= ((iNumCoeffs < -1) || (iNumCoeffs > 0));
//pDQBuf[0] = pDCBuf[block_subblock_mapping[uBlock]];
// if everything quantized to zero, skip RLE
if (!iNumCoeffs){
// the block is empty so it is not coded
bCoded = 0;
} else {
// Preserve the absolute number of coeffs.
cur_mb.MacroblockCoeffsInfo->numCoeff[uBlock] = (T_NumCoeffs)((iNumCoeffs < 0) ? -(iNumCoeffs+1) : iNumCoeffs);
if (m_PicParamSet.entropy_coding_mode){
Ipp32s ctxIdxBlockCat = BLOCK_LUMA_AC_LEVELS;
ScanSignificant_CABAC(pTransformResult,ctxIdxBlockCat,15,
dec_single_scan[is_cur_mb_field],
&curr_slice->Block_CABAC[uBlock]);
bCoded = curr_slice->Block_CABAC[uBlock].uNumSigCoeffs;
} else {
ippiEncodeCoeffsCAVLC_H264(pTransformResult,//pDiffBuf,
1,
dec_single_scan[is_cur_mb_field],
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -