📄 umc_h264_core_enc.cpp
字号:
if (status != UMC_OK) { goto done; } } // Encode Luma block residuals Ipp32u i; for (i=0; i<16; i++) { // Loop over the all of the luma 4x4 blocks // skip if no coeff in MB if (((m_pCurrentFrame->pMBData[uMB].uMBType == MBTYPE_INTRA_16x16) && (m_pCurrentFrame->pMBData[uMB].uLumaAC)) || (m_pCurrentFrame->pMBData[uMB].uCBP & (1<<(i>>2)))) { //if (m_info.entropy_coding_mode) // status = PutCABAC_MBCoefficients_Luma(uMB, i, uIndex); //else status = PutVLC_MBCoefficients_Luma(uMB, i, uIndex); if (status != UMC_OK) { goto done; } } uIndex += m_EncBlockIndexInc[i]; } // Now do chroma blocks if (m_pCurrentFrame->pMBData[uMB].uChromaNC) { // DC Residuals? //if (m_info.entropy_coding_mode) // status = PutCABAC_MBCoefficients_DC(uMB, U_DC_RLE); //else status = PutVLC_MBCoefficients_DC(uMB, U_DC_RLE); if (status != UMC_OK) { goto done; } //if (m_info.entropy_coding_mode) // status = PutCABAC_MBCoefficients_DC(uMB, V_DC_RLE); //else status = PutVLC_MBCoefficients_DC(uMB, V_DC_RLE); if (status != UMC_OK) { goto done; } } if (m_pCurrentFrame->pMBData[uMB].uChromaNC == 2) { // AC Residuals? Ipp32u i; for (i=16; i<24; i++) { //if (m_info.entropy_coding_mode) // status = PutCABAC_MBCoefficients_Chroma(uMB, i); //else status = PutVLC_MBCoefficients_Chroma(uMB, i); if (status != UMC_OK) { goto done; } } } m_pbitstream->GetState(&pCoeffEndBits, &uCoeffEndBitOffset); uCoeffBits = (Ipp32u) (pCoeffEndBits - pCoeffStartBits)*8; if (uCoeffEndBitOffset >= uCoeffStartBitOffset) uCoeffBits += uCoeffEndBitOffset - uCoeffStartBitOffset; else uCoeffBits -= uCoeffStartBitOffset - uCoeffEndBitOffset; if (uCoeffBits+uHdrBits > (MB_RECODE_THRESH) && m_rate_control_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. m_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)); m_uLastXmittedQP = uLastQP; // Restore the last xmitted QP 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 (((m_pCurrentFrame->pMBData[uMB].uMBQP - m_PicParamSet.pic_init_qp + m_SliceHeader.slice_qp_delta) < 2) && (m_pCurrentFrame->pMBData[uMB].uMBQP != 51)){ // Quantize more and try again! m_pCurrentFrame->pMBData[uMB].uMBQP++; 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 m_pCurrentFrame->pMBData[uMB].uMBQP = (Ipp8u) m_uLastXmittedQP; } } else uRecompressMB = 0; if (m_rate_control) m_rate_control->PostMacroblockRateControl(uMB,m_pbitstream->GetBitsEncoded(), m_uLastXmittedQP,m_pCurrentFrame->pMBData[uMB].uCBP); } 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) { Ipp32u uBlock; // block number, 0 to 15 Ipp32u uIndex; // block-dependent, into AI, MV & num coeff arrays m_pCurrentFrame->pMBData[uMB].uMBType = MBTYPE_PCM; m_pCurrentFrame->pMBData[uMB].uCBP4x4 = 0xffff; uIndex = m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex;// VSI -- TODO -- Should the previous MV and RefIdxs be cleared here? Seems not. for (uBlock=0; uBlock<16; uBlock++) { m_pCurrentFrame->pYNumCoeffs[uIndex] = 16; m_pCurrentFrame->pAIMode[uIndex] = 2;// m_pCurrentFrame->pMVPrevL0[uIndex].iMVx = 0;// m_pCurrentFrame->pMVPrevL0[uIndex].iMVy = 0; m_pCurrentFrame->pMVL0[uIndex].iMVx = 0; m_pCurrentFrame->pMVL0[uIndex].iMVy = 0; m_pCurrentFrame->pDMVL0[uIndex].iMVx = 0; m_pCurrentFrame->pDMVL0[uIndex].iMVy = 0;// m_pCurrentFrame->pMVPrevL1[uIndex].iMVx = 0;// m_pCurrentFrame->pMVPrevL1[uIndex].iMVy = 0; m_pCurrentFrame->pMVL1[uIndex].iMVx = 0; m_pCurrentFrame->pMVL1[uIndex].iMVy = 0; m_pCurrentFrame->pRefIdxL0[uIndex] = -1; // Different RefIdx m_pCurrentFrame->pRefIdxL1[uIndex] = -1;// m_pCurrentFrame->pRefIdxPrevL0[uIndex] = 0;// m_pCurrentFrame->pRefIdxPrevL1[uIndex] = 0; uIndex += m_EncBlockIndexInc[uBlock]; } uIndex = m_pCurrentFrame->pMBOffsets[uMB].uFirstChromaBlockIndex; for (uBlock=16; uBlock<20; uBlock++) { m_pCurrentFrame->pUNumCoeffs[uIndex] = 16; m_pCurrentFrame->pVNumCoeffs[uIndex] = 16; uIndex += (uBlock&1) ? (uWidthIn4x4Blocks>>1)-1 : 1; }// if (m_info.entropy_coding_mode)// PutCABAC_MBHeader(uMB); // PCM values are written in the MB Header.// else PutVLC_MBHeader(uMB); // PCM values are written in the MB Header. } // set x and y position vars for next MB m_pCurrentFrame->uMBxpos += 16; if ((m_pCurrentFrame->uMBxpos>>4) == uWidthInMBs) { // current MB is on right edge m_pCurrentFrame->uMBxpos = 0; m_pCurrentFrame->uMBypos += 16; }/* 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) { m_pbitstream->EncodeFinalSingleBin_CABAC(uMB==uFirstMB + uNumMBs - 1); ReconstuctCBP(uMB); } } // 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 (m_uSkipRun !=0 && m_info.entropy_coding_mode==0) { m_pbitstream->PutVLCCode(m_uSkipRun); }#endif // NO_FINAL_SKIP_RUN // save the frame class#ifdef TIMING_DETAIL // update the ME counters which are returned m_uIntegerSearchCounter = m_pCurrentFrame->uIntegerSearchCounter; m_uSubpelSearchCounter = m_pCurrentFrame->uSubpelSearchCounter; m_uDirectBCounter = m_pCurrentFrame->uDirectBCounter;#endifdone: if (m_PicParamSet.entropy_coding_mode) m_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// ======================================================================StatusH264VideoEncoder::Force_MB_Type ( const MB_Type mb_type, const Ipp32u MBIndex ){ // Force the macroblock to be of type mb_type. Call this before // calling Compress_Segment to force the core to produce the // specified type. m_pCurrentFrame->pMBData[MBIndex].uMBType = mb_type; return UMC_OK;}// Free Core MemoryStatusH264VideoEncoder::Free_Core_Memory(){ return UMC_OK;}///////////////////////////////////////####///// Functions called on initializationStatus H264VideoEncoder::Allocate_Core_Memory( const Ipp32u , // num_slices, const Ipp32u , // frame_WidthInMBs, const Ipp32u , // frame_HeightInMBs, CBaseBitstream *bs){#if 0 for(int i=0; i < 16; i++) C1MV_offset[i] = (i & 3) + (i >> 2)*(m_info.src_width>>2); // temporal solution#endif // initialize look-up tables Init_LUTs(); Init_VLC_LUTs(); Init_CABAC(bs); return UMC_OK;}//////////////////////////////////////////////////////////////////////////////////// Init_LUTs//////////////////////////////////////////////////////////////////////////////////void H264VideoEncoder::Init_LUTs(){ Ipp32s i; // MV and AI array index -- initialize table, indexed by current // block (0-23), with the value to add to the array index to advance // to the array member for the next block // Block offset -- initialize table, indexed by current block (0-23) // with the value to add to the offset of the block into the plane // to advance to the next block // luma blocks for (i = 0; i < 16; i++) { // 4 Cases to cover: if (!(i & 1)) { // Even # blocks, next block to the right m_EncBlockIndexInc[i] = 1; m_EncBlockOffsetInc[i] = 4; } else if (!(i & 2)) { // (1,5,9 & 13), down and one to the left m_EncBlockIndexInc[i] = uWidthIn4x4Blocks - 1; m_EncBlockOffsetInc[i] = (uPitch<<2) - 4; } else if (i == 7) { // beginning of next row m_EncBlockIndexInc[i] = uWidthIn4x4Blocks - 3; m_EncBlockOffsetInc[i] = (uPitch<<2) - 12; } else { // (3 & 11) up and one to the right m_EncBlockIndexInc[i] = -(Ipp32s)(uWidthIn4x4Blocks - 1); m_EncBlockOffsetInc[i] = -(Ipp32s)((uPitch<<2) - 4); } } // chroma blocks for (i = 16; i < 23; i++) { if (1 == (i & 1)) { m_EncBlockIndexInc[i] = uWidthIn4x4Blocks*2 - 2; m_EncBlockOffsetInc[i] = (uPitch<<2) - 4; } else { m_EncBlockIndexInc[i] = 2; m_EncBlockOffsetInc[i] = 4; } }} // Init_LUTs///////////////////////////////////////@@@@///// Functions called on from Start_PictureStatusH264VideoEncoder::Start_Picture( const EnumPicClass * pic_class, const H264SeqParamSet * seq_parms, const H264PicParamSet * pic_parms, const H264SliceHeader * slice_header_param, CH264pBs *bitstream, EnumPicCodType // pic_type){ Status ps = UMC_OK;#ifdef TIMING_DETAIL m_uIntegerSearchCounter = 0; m_uSubpelSearchCounter = 0; m_uDirectBCounter = 0; m_uAIModeSelectCounter_4x4 = 0; m_uAIModeSelectCounter_16x16 = 0; m_uEncodeCounter = 0; m_uEdgeDetectCounter = 0; m_uDeblockFilterCounter = 0; m_pCurrentFrame->uIntegerSearchCounter = 0; m_pCurrentFrame->uDirectBCounter = 0; m_pCurrentFrame->uSubpelSearchCounter = 0;#endif m_pbitstream = bitstream; m_SliceHeader = *slice_header_param; m_PicClass = *pic_class; m_SeqParamSet = *seq_parms; m_PicParamSet = *pic_parms; //uHeightInMBs = m_PicParamSet.mb_height; //uHeightIn4x4Blocks = m_PicParamSet.mb_height*4; int uNumMBs = uHeightInMBs*uWidthInMBs; m_pCurrentFrame->uSliceLength = uNumMBs / m_pCurrentFrame->uNumSlices; m_pCurrentFrame->uSliceRemainder = uNumMBs % m_pCurrentFrame->uNumSlices; m_pCurrentFrame->uPitch = (m_PicParamSet.picture_structure == FRAME_PICTURE)? m_pCurrentFrame->fPitch : m_pCurrentFrame->fPitch*2; m_pCurrentFrame->y_line_shift = (m_PicParamSet.picture_structure != BOTTOM_FIELD)? 0 : m_pCurrentFrame->fPitch; m_pCurrentFrame->uv_line_shift = m_pCurrentFrame->y_line_shift; m_pCurrentFrame->use_implicit_weighted_bipred = (m_PicParamSet.weighted_bipred_idc == 2); Init_LUTs(); InitializeMBData(); if (m_rate_control_method == H264_RCM_MPEG2) { int slice_qp = PictureRateControl(); m_SliceHeader.slice_qp_delta = (Ipp8s)(slice_qp - m_PicParamSet.pic_init_qp); } MB_Type defMBType = (m_SliceHeader.slice_type == PREDSLICE)? MBTYPE_INTER_8x8_REF0: MBTYPE_INTER_8x8; for (Ipp32u uMB = 0; uMB < uWidthInMBs * uHeightInMBs; uMB++) { // initialize QP settings and MB type // initialize MBType to 8x8 type, chosen because the type is checked as // encode proceeds to possibly skip steps, this skips nothing. m_uLastXmittedQP = m_PicParamSet.pic_init_qp + m_SliceHeader.slice_qp_delta; m_pCurrentFrame->pMBData[uMB].uMBQP = m_PicParamSet.pic_init_qp + m_SliceHeader.slice_qp_delta; m_pCurrentFrame->pMBData[uMB].uMBType = defMBType; } // reset intra MB counter m_Intra_MB_Counter = 0; m_MB_Counter = 0; // MB position to start m_pCurrentFrame->uMBxpos = 0; m_pCurrentFrame->uMBypos = 0; // TBD RJR: refer to tcpp start_picture (has TR stuff + .. // also check KNI and/or edtq start_picture for what to do //m_pCurrentFrame->SetPicCodType(pic_type); return ps;}/////////////////////////////////////////////////////////////////////////////// End_Picture//// Any processing needed after each picture/////////////////////////////////////////////////////////////////////////////void H264VideoEncoder::End_Picture (){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -