📄 umc_h264_ermb.cpp
字号:
pReconBuf = cur_mb.mb8x8.reconstruct + xoff[4*uBlock] + yoff[4*uBlock]*16;
#else
pReconBuf = m_pReconstructFrame->m_pYPlane + uOffset;
#endif
if (m_PicParamSet.entropy_coding_mode)
{
cur_mb.MacroblockCoeffsInfo->numCoeff[uBlock] = 0; // These will be updated if the block is coded
curr_slice->Block_CABAC[uBlock].uNumSigCoeffs = 0;
} else {
for( idx = idxb; idx<idxe; idx++ ){
curr_slice->Block_RLE[idx].uNumCoeffs = 0;
curr_slice->Block_RLE[idx].uTrailing_Ones = 0;
curr_slice->Block_RLE[idx].uTrailing_One_Signs = 0;
curr_slice->Block_RLE[idx].uTotalZeros = 16;
cur_mb.MacroblockCoeffsInfo->numCoeff[idx] = 0;
}
}
if (!curr_slice->m_use_transform_for_intra_decision){
uIntraSAD += AIModeSelectOneMB_8x8(curr_slice,
pSrcPlane + uOffset,
pReconBuf,
uBlock,
cur_mb.intra_types,
pPredBuf);
}
// check if block is coded
bCoded = ((uCBPLuma & CBP8x8Mask[uBlock])?(1):(0));
if (!bCoded){
// update reconstruct frame for the empty block
Copy8x8(pPredBuf, 16*sizeof(PixType), pReconBuf, pitchPix*sizeof(PixType));
} else { // block not declared empty, encode
// compute difference of predictor and source pels
// note: asm version does not use pDiffBuf
// output is being passed in the mmx registers
if (!curr_slice->m_use_transform_for_intra_decision){
Diff8x8(pPredBuf, pSrcPlane + uOffset, pitchPixels*sizeof(PixType), pDiffBuf);
if(!transform_bypass) {
// forward transform and quantization, in place in pDiffBuf
ippiTransformLuma8x8Fwd_H264(pDiffBuf, pTransformResult);
ippiQuantLuma8x8_H264(pTransformResult,pTransformResult,QP_DIV_6[uMBQP], 0,
enc_single_scan_8x8[is_cur_mb_field], m_SeqParamSet.seq_scaling_matrix_8x8[0][QP_MOD_6[uMBQP]], //Use scaling matrix for INTRA
&iNumCoeffs, &iLastCoeff);
}
else {
for(Ipp32s i = 0; i < 64; i++) {
pTransformResult[i] = pDiffBuf[i];
}
ippiCountCoeffs(pTransformResult, &iNumCoeffs, enc_single_scan_8x8[is_cur_mb_field], &iLastCoeff, 64);
}
}else{
iNumCoeffs = curr_slice->m_iNumCoeffs8x8[ uBlock ];
iLastCoeff = curr_slice->m_iLastCoeff8x8[ uBlock ];
pTransformResult = &cur_mb.mb8x8.transform[ uBlock*64 ];
}
// if everything quantized to zero, skip RLE
if (!iNumCoeffs ){ // the block is empty so it is not coded
bCoded = 0;
} else {
uTotalCoeffs += ((iNumCoeffs < 0) ? -(iNumCoeffs*2) : iNumCoeffs);
// record RLE info
if (m_PicParamSet.entropy_coding_mode)
{
Ipp32s ctxIdxBlockCat = BLOCK_LUMA_64_LEVELS;
// Preserve the absolute number of coeffs.
cur_mb.MacroblockCoeffsInfo->numCoeff[uBlock] = (T_NumCoeffs)ABS(iNumCoeffs);
ScanSignificant_CABAC(pTransformResult,ctxIdxBlockCat,64,
dec_single_scan_8x8[is_cur_mb_field],
&curr_slice->Block_CABAC[uBlock]);
bCoded = curr_slice->Block_CABAC[uBlock].uNumSigCoeffs;
}else{
CoeffsType buf4x4[4][16];
Ipp32s i4x4;
//Reorder 8x8 block for coding with CAVLC
for(i4x4=0; i4x4<4; i4x4++ ) {
Ipp32s i;
for(i = 0; i<16; i++ )
buf4x4[i4x4][dec_single_scan[is_cur_mb_field][i]] =
pTransformResult[dec_single_scan_8x8[is_cur_mb_field][4*i+i4x4]];
}
bCoded = 0;
//Encode each block with CAVLC 4x4
for(i4x4 = 0; i4x4<4; i4x4++ ) {
Ipp32s i;
iLastCoeff = 0;
idx = idxb + i4x4;
//Check for last coeff
for(i = 0; i<16; i++ ) if( buf4x4[i4x4][dec_single_scan[is_cur_mb_field][i]] != 0 ) iLastCoeff=i;
ippiEncodeCoeffsCAVLC_H264 (buf4x4[i4x4],
0, //Luma
dec_single_scan[is_cur_mb_field],
iLastCoeff,
&curr_slice->Block_RLE[idx].uTrailing_Ones,
&curr_slice->Block_RLE[idx].uTrailing_One_Signs,
&curr_slice->Block_RLE[idx].uNumCoeffs,
&curr_slice->Block_RLE[idx].uTotalZeros,
curr_slice->Block_RLE[idx].iLevels,
curr_slice->Block_RLE[idx].uRuns);
bCoded += curr_slice->Block_RLE[idx].uNumCoeffs;
cur_mb.MacroblockCoeffsInfo->numCoeff[idx] = curr_slice->Block_RLE[idx].uNumCoeffs;
}
}
}
// update flags if block quantized to empty
if (curr_slice->m_use_transform_for_intra_decision)
{
if (!bCoded)
{
uCBPLuma &= ~CBP8x8Mask[uBlock];
}
// TODO: ????? What should we copy here ????? SB
// Why in both cases (CODED/NOT CODED the same is copied????
#ifdef H264_RD_OPT
// Copy8x8(pPredBuf + 256, 16*sizeof(PixType), pRecPlane + uOffset, pitchPixels*sizeof(PixType));
#else
Copy8x8(pPredBuf + 256, 16*sizeof(PixType), pReconBuf, pitchPix*sizeof(PixType));
#endif
}else{
// update flags if block quantized to empty
if (!bCoded){
uCBPLuma &= ~CBP8x8Mask[uBlock];
// update reconstruct frame for the empty block
Copy8x8(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
if(iNumCoeffs != 0) {
ippiQuantLuma8x8Inv_H264(pTransformResult, QP_DIV_6[uMBQP], m_SeqParamSet.seq_scaling_inv_matrix_8x8[0][QP_MOD_6[uMBQP]]);
ippiTransformLuma8x8InvAddPred_H264(pPredBuf, 16, pTransformResult, pReconBuf, pitchPix, m_PicParamSet.bit_depth_luma);
}
} else {
// Transform bypass => lossless
// RecPlane == SrcPlane => there is no need to copy.
}
} // block not declared empty
} //curr_slice->m_use_transform_for_intra_decision
uOffset += m_EncBlockOffsetInc[is_cur_mb_field][uBlock] * 2;
} // for uBlock in luma plane
}else{
// loop over all 4x4 blocks in Y plane for the MB
for (uBlock = 0; uBlock < 16; uBlock++ ){
pPredBuf = cur_mb.mb4x4.prediction + xoff[uBlock] + yoff[uBlock]*16;
#ifdef H264_RD_OPT
pReconBuf = cur_mb.mb4x4.reconstruct + xoff[uBlock] + yoff[uBlock]*16;
#else
pReconBuf = m_pReconstructFrame->m_pYPlane + uOffset;
#endif
cur_mb.MacroblockCoeffsInfo->numCoeff[uBlock] = 0; // These 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 = 16;
}
// find advanced intra prediction block, store in PredBuf
// Select best AI mode for the block, using reconstructed
// predictor pels. This function also stores the block
// predictor pels at pPredBuf.
if (!curr_slice->m_use_transform_for_intra_decision){
uIntraSAD += AIModeSelectOneBlock(
curr_slice,
pSrcPlane + uOffset,
pReconBuf,
uBlock,
cur_mb.intra_types,
pPredBuf);
}
// 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
// compute difference of predictor and source pels
// note: asm version does not use pDiffBuf
// output is being passed in the mmx registers
if (!curr_slice->m_use_transform_for_intra_decision){
Diff4x4(pPredBuf, pSrcPlane + uOffset, pitchPixels*sizeof(PixType), pDiffBuf);
#if defined TRACE_INTRA
if(uMB == TRACE_INTRA) {
printf("uBlock = %d\n", uBlock);
printMatr(pSrcPlane + uOffset, pitchPixels, 4, 4, 0, "Src B");
printMatr(pPredBuf, 16, 4, 4, 0, "PredBuf B");
printMatr(pDiffBuf, 4, 4, 4, 0, "pDiffBuf");
}
#endif // TRACE_INTRA
if(!transform_bypass) {
// forward transform, in place in iDiffBuf
// note: asm version does not use pDiffBuf
// input and output are being passed in the mmx reg.s
// quantization and dequantization
// note: asm version does not use pDiffBuf and pDQBuf
// these values are being passed in the mmx registers
ippiTransformQuantResidual_H264(pDiffBuf,pTransformResult, uMBQP,&iNumCoeffs,(slice_type == INTRASLICE),
enc_single_scan[is_cur_mb_field],&iLastCoeff);
}
else {
for(Ipp32s i = 0; i < 16; i++) {
pTransformResult[i] = pDiffBuf[i];
}
ippiCountCoeffs(pTransformResult, &iNumCoeffs, enc_single_scan[is_cur_mb_field],&iLastCoeff, 16);
}
}else{
iNumCoeffs = curr_slice->m_iNumCoeffs4x4[ uBlock ];
iLastCoeff = curr_slice->m_iLastCoeff4x4[ uBlock ];
pTransformResult = &cur_mb.mb4x4.transform[ uBlock*16 ];
}
#if defined TRACE_INTRA
if(uMB == TRACE_INTRA) {
fprintf(stderr,"iNumCoeffs = %d, iLastCoeff = %d\n", iNumCoeffs, iLastCoeff);
printMatr(pTransformResult, 16, 1, 16, 0, "pTransformResult");
}
#endif // TRACE_INTRA
// 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)ABS(iNumCoeffs);
if (m_PicParamSet.entropy_coding_mode){
Ipp32s ctxIdxBlockCat = BLOCK_LUMA_LEVELS;
ScanSignificant_CABAC(pTransformResult,ctxIdxBlockCat,16,
dec_single_scan[is_cur_mb_field],
&curr_slice->Block_CABAC[uBlock]);
bCoded = curr_slice->Block_CABAC[uBlock].uNumSigCoeffs;
} else {
// record RLE info
ippiEncodeCoeffsCAVLC_H264(pTransformResult,
0,
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] = bCoded = curr_slice->Block_RLE[uBlock].uNumCoeffs;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -