📄 umc_h264_core_enc.cpp
字号:
curr_slice->m_pMBEncodeBuffer);
uBestIntraSAD = uAIMBSAD_16x16;
uBestIntraMBType = MBTYPE_INTRA_16x16;
// Estimate 4x4 intra mode SAD for the MB using original pels
// as predictors. Also selects a mode for each block as a
// byproduct, storing in AIMode for the MB, but it is not used
// as the mode selction will be repeated later using (correct)
// reconstructed pels as predictors if 4x4 intra mode is chosen.
AdvancedIntraModeSelectOneMacroblock(curr_slice, uMB, uBestIntraSAD, &uAIMBSAD);
//FPV TODO ADD 8x8?
// choose better intra (4x4 or 16x16)
if (uAIMBSAD < uBestIntraSAD)
{
uBestIntraSAD = uAIMBSAD;
uBestIntraMBType = MBTYPE_INTRA;
}
} else { // either macroblock has no edges or interSAD below threshold
// Compute 16x16 intra mode SAD for the MB, producing luma
// predictor blocks (at pMBEncodeBuffer) and selected mode
// (in AIMode, all blocks) to be used in the encode loop if
// 16x16 intra mode is chosen.
Intra16x16SelectAndPredict(curr_slice, uMB, &uAIMBSAD_16x16,
curr_slice->m_pMBEncodeBuffer);
uBestIntraSAD = uAIMBSAD_16x16;
uBestIntraMBType = MBTYPE_INTRA_16x16;
}
if (uBestIntraSAD < curr_slice->m_uMBInterSAD)
{
cur_mb.GlobalMacroblockInfo->mbtype = static_cast<MBTypeValue>(uBestIntraMBType);
cur_mb.LocalMacroblockInfo->cbp_luma = 0xffff;
cur_mb.LocalMacroblockInfo->cbp_chroma = 0xffffffff;
curr_slice->m_Intra_MB_Counter++;
}
else {
cur_mb.GlobalMacroblockInfo->mbtype = static_cast<MBTypeValue>(curr_slice->m_InterMBType);
cur_mb.LocalMacroblockInfo->cbp_luma = curr_slice->m_uInterCBP4x4;
pSetMB8x8TSPackFlag(cur_mb.GlobalMacroblockInfo, curr_slice->m_InterMB8x8PackFlag);
}
} else { // intra slice
// intra slice, type is INTRA, no empty blocks yet
// For Intra pictures, if the macroblock has edges we check
// both 4x4 and 16x16 intra SADs. Otherwise, we just check the
// 16x16 intra SAD.
if (MBHasEdges)
{
// Compute 16x16 intra mode SAD for the MB, producing luma
// predictor blocks (at pMBEncodeBuffer) and selected mode
// (in AIMode, all blocks) to be used in the encode loop if
// 16x16 intra mode is chosen.
Intra16x16SelectAndPredict(curr_slice, uMB, &uAIMBSAD_16x16,
curr_slice->m_pMBEncodeBuffer);
uBestIntraMBType = MBTYPE_INTRA_16x16;
// Estimate 4x4 intra mode SAD for the MB using original pels
// as predictors. Also selects a mode for each block as a
// byproduct, storing in AIMode for the MB, but it is not used
// as the mode selection will be repeated later using (correct)
// reconstructed pels as predictors if 4x4 intra mode is chosen.
AdvancedIntraModeSelectOneMacroblock(curr_slice, uMB, uAIMBSAD, &uAIMBSAD);
// choose better intra (4x4 or 16x16)
if (uAIMBSAD_16x16 < uAIMBSAD){
uBestIntraMBType = MBTYPE_INTRA;
}
} else {
// Compute 16x16 intra mode SAD for the MB, producing luma
// predictor blocks (at pMBEncodeBuffer) and selected mode
// (in AIMode, all blocks) to be used in the encode loop if
// 16x16 intra mode is chosen.
Intra16x16SelectAndPredict(curr_slice, uMB, &uAIMBSAD_16x16,
curr_slice->m_pMBEncodeBuffer);
uBestIntraMBType = MBTYPE_INTRA_16x16;
}
cur_mb.GlobalMacroblockInfo->mbtype = static_cast<MBTypeValue>(uBestIntraMBType);
cur_mb.LocalMacroblockInfo->cbp_luma = 0xffff;
cur_mb.LocalMacroblockInfo->cbp_chroma = 0xffffffff;
curr_slice->m_uMBInterSAD = MAX_SAD; // very large SAD
curr_slice->m_Intra_MB_Counter++;
}
#ifdef _INTRA_MODE_SWITCH_
curr_slice->m_uMBIntra16x16SAD = uAIMBSAD_16x16; // Save for mode possible switch later
#endif
// Code the macroblock, all planes
// coefficients -> pRLEBuffer
cur_mb.LocalMacroblockInfo->cbp_bits = 0;
cur_mb.LocalMacroblockInfo->cbp_bits_chroma = 0;
cur_mb.uMB = uMB;
CEncAndRecMB(curr_slice);
status = Put_MB(curr_slice);
if (status != UMC_OK)
{
goto done;
}
Ipp8u *pEndBits;
Ipp32u uEndBitOffset;
pBitstream->GetState(&pEndBits, &uEndBitOffset);
Ipp32u mb_bits = (Ipp32u) (pEndBits - pStartBits)*8;
if (uEndBitOffset >= uStartBitOffset)
mb_bits += uEndBitOffset - uStartBitOffset;
else
mb_bits -= uStartBitOffset - uEndBitOffset;
if (!m_PicParamSet.entropy_coding_mode && (mb_bits > MB_RECODE_THRESH) && m_info.rate_controls.method == H264_RCM_QUANT)
{
// OK, this is bad, it's not compressing very much!!!
// TBD: Tune this decision to QP... Higher QPs will progressively trash PSNR,
// so if they are still using a lot of bits, then PCM coding is extra attractive.
// We're going to be recoding this MB, so reset some stuff.
pBitstream->SetState(pStartBits, uStartBitOffset); // Reset the BS
// Zero out unused bits in buffer before OR in next op
// This removes dependency on buffer being zeroed out.
*pStartBits = (Ipp8u)((*pStartBits >> (8-uStartBitOffset)) << (8-uStartBitOffset));
curr_slice->m_iLastXmittedQP = iLastQP; // Restore the last xmitted QP
curr_slice->m_uSkipRun = uSaved_Skip_Run; // Restore the skip run
// If the QP has only been adjusted up 0 or 1 times, and QP != 51
if (((cur_mb.LocalMacroblockInfo->QP -
m_PicParamSet.pic_init_qp + curr_slice->m_slice_qp_delta) < 2) &&
(cur_mb.LocalMacroblockInfo->QP != 51))
{
// Quantize more and try again!
cur_mb.LocalMacroblockInfo->QP++;
uRecompressMB = 1;
} else {
// Code this block as a PCM MB next time around.
uUsePCM = 1;
uRecompressMB = 0;
// Reset the MB QP value to the "last transmitted QP"
// Since no DeltaQP will be transmitted for a PCM block
// This is important, since the Loop Filter will use the
// this value in filtering this MB
cur_mb.LocalMacroblockInfo->QP = curr_slice->m_iLastXmittedQP;
}
} else
uRecompressMB = 0;
} while (uRecompressMB); // End of the MB recompression loop.
// If the above MB encoding failed to efficiently predict the MB, then
// code it as raw pixels using the mb_type = PCM
if (uUsePCM)
{
cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_PCM;
cur_mb.LocalMacroblockInfo->cbp_luma = 0xffff;
memset(cur_mb.MacroblockCoeffsInfo->numCoeff, 16, 24);
Ipp32s k; // block number, 0 to 15
for (k = 0; k < 16; k++) {
cur_mb.intra_types[k] = 2;
cur_mb.MVs[LIST_0]->MotionVectors[k] = null_mv;
cur_mb.MVs[LIST_1]->MotionVectors[k] = null_mv;
cur_mb.RefIdxs[LIST_0]->RefIdxs[k] = -1;
cur_mb.RefIdxs[LIST_1]->RefIdxs[k] = -1;
}
Put_MBHeader(curr_slice); // PCM values are written in the MB Header.
}
/*
if (!m_pbitstream->CheckBsLimit())
{
// If the buffer is filled, break out of encoding loop
// Encoder::CompressFrame will write a blank frame to the bitstream.
goto done;
}*/
if (m_PicParamSet.entropy_coding_mode)
{
if ((uMB & 1) != 0)
{
pBitstream->EncodeFinalSingleBin_CABAC( (uMB==(uFirstMB + uNumMBs - 1))
|| (m_pCurrentFrame->m_mbinfo.mbs[uMB + 1].slice_id != slice_num) );
}
ReconstuctCBP(&cur_mb);
}
} // loop over MBs
#ifndef NO_FINAL_SKIP_RUN
// Check if the last N MBs were skip blocks. If so, write a final skip run
// NOTE! This is _optional_. The encoder is not required to do this, and
// decoders need to be able to handle it either way.
// Even though skip runs are not written for I Slices, m_uSkipRun can only be
// non-zero for non-I slices, so the following test is OK.
if (curr_slice->m_uSkipRun !=0 && m_info.entropy_coding_mode==0) {
pBitstream->PutVLCCode(curr_slice->m_uSkipRun);
}
#endif // NO_FINAL_SKIP_RUN
done:
if (m_PicParamSet.entropy_coding_mode)
pBitstream->TerminateEncode_CABAC();
// use core timing infrastructure to measure/report deblock filter time
// by measuring the time to get from here to the start of EndPicture.
return status;
} // Compress_Slice
// ======================================================================
// Free Core Memory
template <class PixType, class CoeffsType>
Status H264CoreEncoder<PixType, CoeffsType>::Free_Core_Memory()
{
m_pReconstructFrame = 0;
// new structure(s) hold pointer
if (m_pParsedDataNew)
{
ippsFree(m_pParsedDataNew);
m_pParsedDataNew = NULL;
}
// Destroy treadprivate slice data.
if(m_Slices != NULL) {
delete [] m_Slices;
m_Slices = NULL;
}
// destroy limited slice info array
if (m_pLimitedSliceInfo)
ippsFree(m_pLimitedSliceInfo);
m_nAllocatedLimitedSliceInfo = 0;
m_pLimitedSliceInfo = NULL;
return UMC_OK;
}
///////////////////////////////////////####
///// Functions called on initialization
template <class PixType, class CoeffsType>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -