📄 umc_h264_ermb.cpp
字号:
pDCBuf[i*num_cols+j] = pMassDiffBuf[i*bPitch + j*16];
}
}
ippiCalcNonZero(pDCBuf, num_blocks, &iNumCoeffs);
}
// DC values in this block if iNonEmpty is 1.
cur_mb.MacroblockCoeffsInfo->chromaNC |= (iNumCoeffs != 0);
// record RLE info
if (m_PicParamSet.entropy_coding_mode){
Ipp32s ctxIdxBlockCat = BLOCK_CHROMA_DC_LEVELS;
switch( m_PicParamSet.chroma_format_idc ){
case 1:
ScanSignificant_CABAC(pDCBuf,ctxIdxBlockCat,4,dec_single_scan_p,&curr_slice->Block_CABAC[RLE_Offset]);
break;
case 2:
ScanSignificant_CABAC(pDCBuf,ctxIdxBlockCat,8,dec_single_scan_p422,&curr_slice->Block_CABAC[RLE_Offset]);
break;
case 3:
break;
}
}else{
switch( m_PicParamSet.chroma_format_idc ){
case 1:
ippiEncodeChromaDcCoeffsCAVLC_H264 (pDCBuf,
&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);
break;
case 2:
ippiEncodeChroma422DC_CoeffsCAVLC_H264 (pDCBuf,
&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);
break;
}
}
// Inverse transform and dequantize for chroma DC
if(!transform_bypass ){
switch( m_PicParamSet.chroma_format_idc ){
case 1:
ippiTransformDequantChromaDC_H264 (pDCBuf, uMBQP);
break;
case 2:
ippiTransformDequantChromaDC422_H264 (pDCBuf, uMBQP, NULL);
break;
}
}
//Encode croma AC
Ipp32s coeffsCost = 0;
pPredBuf_copy = pPredBuf;
pReconBuf_copy = pReconBuf;
for (uBlock = startBlock; uBlock < uLastBlock; uBlock ++) {
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 = ((uCBPChroma & CBP4x4Mask[uBlock-16])?(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 + (uBlock-startBlock)*16;
pTransformResult = pTransform + (uBlock-startBlock)*16;
if(!transform_bypass) {
ippiTransformQuantResidual_H264(pTempDiffBuf, pTransformResult,uMBQP,&iNumCoeffs,(slice_type == INTRASLICE),
enc_single_scan[is_cur_mb_field],&iLastCoeff);
coeffsCost += CalculateCoeffsCost(pTransformResult, 15, &dec_single_scan[is_cur_mb_field][1]);
}else {
for(Ipp32s i = 0; i < 16; i++) {
pTransformResult[i] = pTempDiffBuf[i];
}
ippiCountCoeffs(pTempDiffBuf, &iNumCoeffs, enc_single_scan[is_cur_mb_field], &iLastCoeff, 16);
}
cur_mb.MacroblockCoeffsInfo->numCoeff[uBlock] = (T_NumCoeffs)((iNumCoeffs < 0) ? -(iNumCoeffs+1) : iNumCoeffs);
// if everything quantized to zero, skip RLE
if (cur_mb.MacroblockCoeffsInfo->numCoeff[uBlock]){ // the block is empty so it is not coded
if (m_PicParamSet.entropy_coding_mode){
Ipp32s ctxIdxBlockCat = BLOCK_CHROMA_AC_LEVELS;
ScanSignificant_CABAC(pTransformResult,ctxIdxBlockCat,15,
dec_single_scan[is_cur_mb_field],
&curr_slice->Block_CABAC[uBlock]);
cur_mb.MacroblockCoeffsInfo->numCoeff[uBlock] = curr_slice->Block_CABAC[uBlock].uNumSigCoeffs;
} else {
ippiEncodeCoeffsCAVLC_H264 (pTransformResult,// pDiffBuf,
1,
dec_single_scan[is_cur_mb_field],
iLastCoeff,
&curr_slice->Block_RLE[uBlock].uTrailing_Ones,
&curr_slice->Block_RLE[uBlock].uTrailing_One_Signs,
&curr_slice->Block_RLE[uBlock].uNumCoeffs,
&curr_slice->Block_RLE[uBlock].uTotalZeros,
curr_slice->Block_RLE[uBlock].iLevels,
curr_slice->Block_RLE[uBlock].uRuns);
cur_mb.MacroblockCoeffsInfo->numCoeff[uBlock] = curr_slice->Block_RLE[uBlock].uNumCoeffs;
}
}
}
pPredBuf += chromaPredInc[m_PicParamSet.chroma_format_idc-1][uBlock-startBlock]; //!!!
#ifdef H264_RD_OPT
pReconBuf += chromaPredInc[m_PicParamSet.chroma_format_idc-1][uBlock-startBlock]; //!!!
#else
pReconBuf += m_EncBlockOffsetInc[is_cur_mb_field][uBlock];
#endif
}
if(!transform_bypass && coeffsCost <= (CHROMA_COEFF_MAX_COST<<(m_PicParamSet.chroma_format_idc-1)) ){ //Reset all ac coeffs
// if(cur_mb.MacroblockCoeffsInfo->chromaNC&1) //if we have DC coeffs
// memset( pTransform, 0, (64*sizeof(CoeffsType))<<(m_PicParamSet.chroma_format_idc-1));
for(uBlock = startBlock; uBlock < uLastBlock; uBlock++){
cur_mb.MacroblockCoeffsInfo->numCoeff[uBlock] = 0;
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;
}
}
}
pPredBuf = pPredBuf_copy;
pReconBuf = pReconBuf_copy;
for (uBlock = startBlock; uBlock < uLastBlock; uBlock ++) {
cur_mb.MacroblockCoeffsInfo->chromaNC |= 2*(cur_mb.MacroblockCoeffsInfo->numCoeff[uBlock]!=0);
if (!cur_mb.MacroblockCoeffsInfo->numCoeff[uBlock] && !pDCBuf[ chromaDCOffset[m_PicParamSet.chroma_format_idc-1][uBlock-startBlock] ]){
uCBPChroma &= ~CBP4x4Mask[uBlock-16];
Copy4x4(pPredBuf, 16*sizeof(PixType), pReconBuf, pitchPix*sizeof(PixType));
}else if(!transform_bypass){
ippiDequantTransformResidualAndAdd_H264(
pPredBuf,
pTransform + (uBlock-startBlock)*16,
&pDCBuf[ chromaDCOffset[m_PicParamSet.chroma_format_idc-1][uBlock-startBlock] ],
pReconBuf,
16,
pitchPix,
uMBQP,
(cur_mb.MacroblockCoeffsInfo->numCoeff[uBlock]!=0),
m_SeqParamSet.bit_depth_chroma);
}
pPredBuf += chromaPredInc[m_PicParamSet.chroma_format_idc-1][uBlock-startBlock]; //!!!
#ifdef H264_RD_OPT
pReconBuf += chromaPredInc[m_PicParamSet.chroma_format_idc-1][uBlock-startBlock]; //!!!
#else
pReconBuf += m_EncBlockOffsetInc[is_cur_mb_field][uBlock];
#endif
} // for uBlock in chroma plane
} while (uBlock < uFinalBlock);
//Reset other chroma
uCBPChroma &= ~(0xffffffff<<(uBlock-16));
cur_mb.LocalMacroblockInfo->cbp_chroma = uCBPChroma;
if (cur_mb.MacroblockCoeffsInfo->chromaNC == 3)
cur_mb.MacroblockCoeffsInfo->chromaNC = 2;
}
template <class PixType, class CoeffsType>
Ipp32u H264CoreEncoder<PixType, CoeffsType>::CEncAndRec4x4IntraMB(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 uMBType; // current MB type
Ipp32u uMB;
Ipp32u uCBPLuma; // coded flags for all 4x4 blocks
Ipp32u uIntraSAD; // intra MB SAD
Ipp16s* pMassDiffBuf; // difference block pointer
CoeffsType* pDCBuf; // chroma & luma dc coeffs pointer
PixType* pPredBuf; // prediction block pointer
PixType* pReconBuf; // prediction block pointer
Ipp16s* pDiffBuf; // difference block pointer
CoeffsType* pTransformResult; // Result of the transformation.
CoeffsType* pQBuf; // quantized block pointer
PixType* pSrcPlane; // start of plane to encode
Ipp32s pitchPixels; // buffer pitch
Ipp32s iMBCost; // recode MB cost counter
Ipp32s iBlkCost[2]; // coef removal counter for left/right 8x8 luma blocks
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 uTotalCoeffs = 0; // Used to detect single expensive coeffs.
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;
uMB = cur_mb.uMB;
pitchPixels = cur_mb.mbPitchPixels;
uCBPLuma = cur_mb.LocalMacroblockInfo->cbp_luma;
uMBQP = getLumaQP(cur_mb.LocalMacroblockInfo->QP, m_PicParamSet.bit_depth_luma);
uMBType = cur_mb.GlobalMacroblockInfo->mbtype;
pDiffBuf = (Ipp16s*) (curr_slice->m_pMBEncodeBuffer + 512);
pTransformResult = (CoeffsType*)(pDiffBuf + 64);
pQBuf = (CoeffsType*) (pTransformResult + 64);
pDCBuf = (CoeffsType*) (pQBuf + 16); // Used for both luma and chroma DC blocks
pMassDiffBuf= (Ipp16s*) (pDCBuf+ 16);
// uIntraSAD = rd_quant_intra[uMBQP] * 24; // TODO ADB 'handicap' using reconstructed data
uIntraSAD = 0;
iMBCost = 0;
iBlkCost[0] = 0;
iBlkCost[1] = 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];
bool transform_bypass = m_SeqParamSet.qpprime_y_zero_transform_bypass_flag && uMBQP == 0;
Ipp32s pitchPix;
#ifdef H264_RD_OPT
pitchPix = 16;
#else
pitchPix = pitchPixels;
#endif
#if defined TRACE_INTRA
if(uMB == TRACE_INTRA) {
fprintf(stderr,"ermb intra: uMB = %d, tr_bypass = %d, uCBPLuma = 0x%x\n", uMB, transform_bypass, uCBPLuma);
printMatr(pSrcPlane + uOffset, pitchPixels, 16, 16, 0, "SrcPlane");
if(pGetMB8x8TSPackFlag(cur_mb.GlobalMacroblockInfo))
printMatr(cur_mb.mb8x8.prediction, 16, 16, 16, 0, "PredBuf");
else
printMatr(cur_mb.mb4x4.prediction, 16, 16, 16, 0, "PredBuf");
}
#endif // TRACE_INTRA
if(pGetMB8x8TSPackFlag(cur_mb.GlobalMacroblockInfo)) {
pSetMB8x8TSFlag(cur_mb.GlobalMacroblockInfo, 1);
//loop over all 8x8 blocks in Y plane for the MB
for (uBlock = 0; uBlock < 4; uBlock ++){
Ipp32s idxb, idx, idxe;
idxb = uBlock<<2;
idxe = idxb+4;
pPredBuf = cur_mb.mb8x8.prediction + xoff[4*uBlock] + yoff[4*uBlock]*16;
#ifdef H264_RD_OPT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -