📄 umc_h264_core_enc.cpp
字号:
memcpy(&cur_mb.mb[mbType].MBmvs[32],cur_mb.MVs[LIST_0+2]->MotionVectors,sizeof(H264MotionVector)*16);
memcpy(&cur_mb.mb[mbType].MBmvs[48],cur_mb.MVs[LIST_1+2]->MotionVectors,sizeof(H264MotionVector)*16);
memcpy(&cur_mb.mb[mbType].MBridx[0],cur_mb.RefIdxs[LIST_0]->RefIdxs,sizeof(T_RefIdx)*16);
memcpy(&cur_mb.mb[mbType].MBridx[16],cur_mb.RefIdxs[LIST_1]->RefIdxs,sizeof(T_RefIdx)*16);
if( mbType == MBTYPE_INTRA ){
cur_mb.mb[mbType].ssd = SSD16x16(cur_mb.mbPtr, cur_mb.mbPitchPixels, cur_mb.mb4x4.reconstruct, 16 );
}else if( mbType == MBTYPE_INTRA_16x16 ){
cur_mb.mb[mbType].ssd = SSD16x16(cur_mb.mbPtr, cur_mb.mbPitchPixels, cur_mb.mb16x16.reconstruct, 16 );
}else{
cur_mb.mb[mbType].ssd = SSD16x16(cur_mb.mbPtr, cur_mb.mbPitchPixels, cur_mb.mbInter.reconstruct, 16 );
}
cur_mb.mb[mbType].ssd += lambda*mb_bits;
// if( mbType == MBTYPE_INTRA ) cur_mb.mb[mbType].ssd += lambda*24*24; //handicap from JVT
// printf("uMB=%d mb_bits=%d mbtype=%d sad/ssd 16x16=%d %d 4x4=%d %d\n",uMB, mb_bits, mbType, cur_mb.mb[MBTYPE_INTRA_16x16].sad, cur_mb.mb[MBTYPE_INTRA_16x16].ssd, cur_mb.mb[MBTYPE_INTRA].sad, cur_mb.mb[MBTYPE_INTRA].ssd );
if( m_PicParamSet.entropy_coding_mode ){
cur_mb.mb[mbType].bitstream->CopyContext_CABAC(*pBitstream);
}
// if( xi == 3 && mbType==MBTYPE_INTRA ){
if( xi == 3 ){
//Save mb params
pBitstream->SetState(pStartBits, uStartBitOffset);
*pStartBits = (Ipp8u)((*pStartBits >> (8-uStartBitOffset)) << (8-uStartBitOffset));
if( m_PicParamSet.entropy_coding_mode ){
pBitstream->RestoreContext_CABAC();
}
//curr_slice->m_iLastXmittedQP = iLastQP; // Restore the last xmitted QP
curr_slice->m_uSkipRun = uSaved_Skip_Run; // Restore the skip run
cur_mb.LocalMacroblockInfo->cbp_chroma = 0xffffffff;
if( mbType == MBTYPE_INTRA ){
cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
cur_mb.LocalMacroblockInfo->cbp_luma = 0xffff;
}else{
cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA;
cur_mb.LocalMacroblockInfo->cbp_luma = curr_slice->m_uIntraCBP4x4;
memcpy( cur_mb.intra_types, cur_mb.mb[MBTYPE_INTRA].intra_types, 16);
}
// }else if( slice_type != INTRASLICE && IS_INTRA_MBTYPE(mbType) && cur_mb.mb[MBTYPE_INTER].sad < bestSAD*1.4 ){
}else if( slice_type != INTRASLICE && xi == 2 ){
pBitstream->SetState(pStartBits, uStartBitOffset);
*pStartBits = (Ipp8u)((*pStartBits >> (8-uStartBitOffset)) << (8-uStartBitOffset));
if( m_PicParamSet.entropy_coding_mode ){
pBitstream->RestoreContext_CABAC();
}
cur_mb.LocalMacroblockInfo->cbp_chroma = 0xffffffff;
cur_mb.GlobalMacroblockInfo->mbtype = curr_slice->m_InterMBType;
cur_mb.LocalMacroblockInfo->cbp_luma = curr_slice->m_uInterCBP4x4;
curr_slice->m_uSkipRun = uSaved_Skip_Run; // Restore the skip run
cur_mb.LocalMacroblockInfo->intra_chroma_mode = 0;
memcpy(cur_mb.MVs[LIST_0]->MotionVectors,&MBmvs[0],sizeof(H264MotionVector)*16);
memcpy(cur_mb.MVs[LIST_1]->MotionVectors,&MBmvs[16],sizeof(H264MotionVector)*16);
memcpy(cur_mb.MVs[LIST_0+2]->MotionVectors,&MBmvs[32],sizeof(H264MotionVector)*16);
memcpy(cur_mb.MVs[LIST_1+2]->MotionVectors,&MBmvs[48],sizeof(H264MotionVector)*16);
memcpy(cur_mb.RefIdxs[LIST_0]->RefIdxs,&MBridx[0],sizeof(T_RefIdx)*16);
memcpy(cur_mb.RefIdxs[LIST_1]->RefIdxs,&MBridx[16],sizeof(T_RefIdx)*16);
}else break;
xi--;
}while(xi>0);
// **Take the best RD optimized
// Take with less bits
if( xi != 3 ){
// printf("uMB=%d %f mb_bits= I16: %d I4: %d sad/ssd I16=%d %d I4=%d %d err: I16=%f I4=%f\n",uMB,lambda,cur_mb.mb[MBTYPE_INTRA_16x16].bits,cur_mb.mb[MBTYPE_INTRA].bits , cur_mb.mb[MBTYPE_INTRA_16x16].sad, cur_mb.mb[MBTYPE_INTRA_16x16].ssd, cur_mb.mb[MBTYPE_INTRA].sad, cur_mb.mb[MBTYPE_INTRA].ssd, err2, err1 );
/* if( cur_mb.mb[MBTYPE_INTER].bits < cur_mb.mb[MBTYPE_INTRA_16x16].bits && cur_mb.mb[MBTYPE_INTER].bits < cur_mb.mb[MBTYPE_INTRA].bits ){
mbType = curr_slice->m_InterMBType;
}else if( cur_mb.mb[MBTYPE_INTRA].bits < cur_mb.mb[MBTYPE_INTRA_16x16].bits ) {
mbType = MBTYPE_INTRA;
} else {
mbType = MBTYPE_INTRA_16x16;
}
*/
if( slice_type != INTRASLICE && cur_mb.mb[MBTYPE_INTER].ssd < cur_mb.mb[MBTYPE_INTRA_16x16].ssd && cur_mb.mb[MBTYPE_INTER].ssd < cur_mb.mb[MBTYPE_INTRA].ssd ){
mbType = curr_slice->m_InterMBType;
}else if( cur_mb.mb[MBTYPE_INTRA].ssd < cur_mb.mb[MBTYPE_INTRA_16x16].ssd ) {
mbType = MBTYPE_INTRA;
} else {
mbType = MBTYPE_INTRA_16x16;
}
// printf(" min type = %d %d %d strm_size=%d %x\n", mbType, cur_mb.mb[MBTYPE_INTRA].bits, cur_mb.mb[MBTYPE_INTRA_16x16].bits, cur_mb.mb[mbType].stream_size,pStartBits+cur_mb.mb[mbType].stream_size-1);
if( mbType != cur_mb.GlobalMacroblockInfo->mbtype ){
cur_mb.GlobalMacroblockInfo->mbtype = mbType;
if( !IS_INTRA_MBTYPE(mbType) ) mbType = MBTYPE_INTER;
curr_slice->m_uSkipRun = cur_mb.mb[mbType].skip_run;
memcpy(cur_mb.LocalMacroblockInfo,&(cur_mb.mb[mbType].locInfo),sizeof(H264MacroblockLocalInfo));
memcpy(cur_mb.GlobalMacroblockInfo,&(cur_mb.mb[mbType].globInfo),sizeof(H264MacroblockGlobalInfo));
memcpy(cur_mb.MacroblockCoeffsInfo, &(cur_mb.mb[mbType].coeffInfo),sizeof(H264MacroblockCoeffsInfo));
memcpy( pStartBits, cur_mb.mb[mbType].stream, cur_mb.mb[mbType].stream_size);
Ipp8u* pEndBits = pStartBits+cur_mb.mb[mbType].stream_size-1;
Ipp32u uEndBitOffset = cur_mb.mb[mbType].stream_offset;
*pEndBits = (Ipp8u)((*pEndBits >> (8-uEndBitOffset)) << (8-uEndBitOffset));
pBitstream->SetState( pEndBits, uEndBitOffset);
memcpy( cur_mb.intra_types, cur_mb.mb[mbType].intra_types, 16);
if( m_PicParamSet.entropy_coding_mode ){
pBitstream->CopyContext_CABAC(*(cur_mb.mb[mbType].bitstream));
}
mb_bits = cur_mb.mb[mbType].bits;
memcpy(cur_mb.MVs[LIST_0]->MotionVectors,&cur_mb.mb[mbType].MBmvs[0],sizeof(H264MotionVector)*16);
memcpy(cur_mb.MVs[LIST_1]->MotionVectors,&cur_mb.mb[mbType].MBmvs[16],sizeof(H264MotionVector)*16);
memcpy(cur_mb.MVs[LIST_0+2]->MotionVectors,&cur_mb.mb[mbType].MBmvs[32],sizeof(H264MotionVector)*16);
memcpy(cur_mb.MVs[LIST_1+2]->MotionVectors,&cur_mb.mb[mbType].MBmvs[48],sizeof(H264MotionVector)*16);
memcpy(cur_mb.RefIdxs[LIST_0]->RefIdxs,&cur_mb.mb[mbType].MBridx[0],sizeof(T_RefIdx)*16);
memcpy(cur_mb.RefIdxs[LIST_1]->RefIdxs,&cur_mb.mb[mbType].MBridx[16],sizeof(T_RefIdx)*16);
}
}
mbType = cur_mb.GlobalMacroblockInfo->mbtype;
//copy reconstruct
if( IS_INTRA_MBTYPE(mbType) ){
if( mbType == MBTYPE_INTRA ){
if( pGetMB8x8TSFlag(cur_mb.GlobalMacroblockInfo) ){
ippiCopy16x16_8u_C1R( (Ipp8u*)cur_mb.mb8x8.reconstruct, 16*sizeof(PixType), (Ipp8u*)cur_mb.mbPtr, cur_mb.mbPitchPixels*sizeof(PixType));
}else{
ippiCopy16x16_8u_C1R( (Ipp8u*)cur_mb.mb4x4.reconstruct, 16*sizeof(PixType), (Ipp8u*)cur_mb.mbPtr, cur_mb.mbPitchPixels*sizeof(PixType));
}
}else{
ippiCopy16x16_8u_C1R( (Ipp8u*)cur_mb.mb16x16.reconstruct, 16*sizeof(PixType), (Ipp8u*)cur_mb.mbPtr, cur_mb.mbPitchPixels*sizeof(PixType));
}
ippiCopy8x8_8u_C1R( (Ipp8u*)cur_mb.mbChromaIntra.reconstruct, 16*sizeof(PixType),
(Ipp8u*)m_pCurrentFrame->m_pUPlane + m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field],
cur_mb.mbPitchPixels*sizeof(PixType));
ippiCopy8x8_8u_C1R( (Ipp8u*)(cur_mb.mbChromaIntra.reconstruct+8), 16*sizeof(PixType),
(Ipp8u*)m_pCurrentFrame->m_pVPlane + m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field],
cur_mb.mbPitchPixels*sizeof(PixType));
if( m_info.chroma_format_idc == 2 ){
ippiCopy8x8_8u_C1R( (Ipp8u*)cur_mb.mbChromaIntra.reconstruct+8*16, 16*sizeof(PixType),
(Ipp8u*)m_pCurrentFrame->m_pYPlane + m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field]+8*cur_mb.mbPitchPixels,
cur_mb.mbPitchPixels*sizeof(PixType));
ippiCopy8x8_8u_C1R( (Ipp8u*)(cur_mb.mbChromaIntra.reconstruct+8+8*16), 16*sizeof(PixType),
(Ipp8u*)m_pCurrentFrame->m_pVPlane + m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field]+8*cur_mb.mbPitchPixels,
cur_mb.mbPitchPixels*sizeof(PixType));
}
}else{
ippiCopy16x16_8u_C1R( (Ipp8u*)cur_mb.mbInter.reconstruct, 16*sizeof(PixType), (Ipp8u*)cur_mb.mbPtr, cur_mb.mbPitchPixels*sizeof(PixType));
ippiCopy8x8_8u_C1R( (Ipp8u*)cur_mb.mbChromaInter.reconstruct, 16*sizeof(PixType),
(Ipp8u*)m_pCurrentFrame->m_pUPlane + m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field],
cur_mb.mbPitchPixels*sizeof(PixType));
ippiCopy8x8_8u_C1R( (Ipp8u*)(cur_mb.mbChromaInter.reconstruct+8), 16*sizeof(PixType),
(Ipp8u*)m_pCurrentFrame->m_pVPlane + m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field],
cur_mb.mbPitchPixels*sizeof(PixType));
if( m_info.chroma_format_idc == 2 ){
ippiCopy8x8_8u_C1R( (Ipp8u*)cur_mb.mbChromaInter.reconstruct+8*16, 16*sizeof(PixType),
(Ipp8u*)m_pCurrentFrame->m_pYPlane + m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field]+8*cur_mb.mbPitchPixels,
cur_mb.mbPitchPixels*sizeof(PixType));
ippiCopy8x8_8u_C1R( (Ipp8u*)(cur_mb.mbChromaInter.reconstruct+8+8*16), 16*sizeof(PixType),
(Ipp8u*)m_pCurrentFrame->m_pVPlane + m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field]+8*cur_mb.mbPitchPixels,
cur_mb.mbPitchPixels*sizeof(PixType));
}
}
#endif /* H264_RD_OPT */
// printf("%d;%d\n", uMB, mb_bits);
// mbtype_stat[cur_mb.GlobalMacroblockInfo->mbtype]++;
#ifdef H264_STAT
hstats.addMB( slice_type, curr_slice->m_cur_mb.GlobalMacroblockInfo->mbtype, curr_slice->m_cur_mb.GlobalMacroblockInfo->sbtype, pGetMB8x8TSFlag(cur_mb.GlobalMacroblockInfo), mb_bits);
#endif
// Should not recompress for CABAC
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){
// 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -