⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umc_h264_core_enc.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                if (m_info.transform_8x8_mode_flag && (m_Analyse & ANALYSE_I_8x8)) {
                    pSetMB8x8TSFlag(curr_slice->m_cur_mb.GlobalMacroblockInfo, true);
                    AdvancedIntraModeSelectOneMacroblock8x8(curr_slice, uMB, best_sad, &uAIMBSAD_8x8);
                    //Save intra_types
                    memcpy( intra_types_save, curr_slice->m_cur_mb.intra_types, 16*sizeof(T_AIMode));
                    if( uAIMBSAD_8x8 < best_sad ){
                        best_sad = uAIMBSAD_8x8;
                        uBestIntraMBType = MBTYPE_INTRA;
                        bIntra8x8 = true;
                    }
                    pSetMB8x8TSFlag(curr_slice->m_cur_mb.GlobalMacroblockInfo, false);
                }
                if (m_Analyse & ANALYSE_I_4x4) {
                    AdvancedIntraModeSelectOneMacroblock(curr_slice, uMB, best_sad, &uAIMBSAD_4x4);
                    cur_mb.mb[MBTYPE_INTRA].cbp = curr_slice->m_uIntraCBP4x4;
                    cur_mb.mb[MBTYPE_INTRA].sad = uAIMBSAD_4x4;
#ifdef  H264_RD_OPT
                    memcpy(curr_slice->m_cur_mb.mb[MBTYPE_INTRA].intra_types, curr_slice->m_cur_mb.intra_types, 16*sizeof(T_AIMode));
#endif
                    if (uAIMBSAD_4x4 < best_sad) {
                        uBestIntraMBType = MBTYPE_INTRA;
                        best_sad = uAIMBSAD_4x4;
                        bIntra8x8 = false;
                    }
                }
#ifndef H264_RD_OPT
            }
#endif
        }
        curr_slice->m_uMBIntraSAD = best_sad;
        cur_mb.GlobalMacroblockInfo->mbtype = static_cast<MBTypeValue>(uBestIntraMBType);
        pSetMB8x8TSPackFlag(curr_slice->m_cur_mb.GlobalMacroblockInfo, bIntra8x8);
        if (uBestIntraMBType == MBTYPE_INTRA && !bIntra8x8)
            cur_mb.LocalMacroblockInfo->cbp_luma = curr_slice->m_uIntraCBP4x4;
        else if (uBestIntraMBType == MBTYPE_INTRA && bIntra8x8) {
            cur_mb.LocalMacroblockInfo->cbp_luma = curr_slice->m_uIntraCBP8x8;
            //Restore intra_types
            memcpy(curr_slice->m_cur_mb.intra_types, intra_types_save, 16*sizeof(T_AIMode));
        } else
            cur_mb.LocalMacroblockInfo->cbp_luma = 0xffff;
        cur_mb.LocalMacroblockInfo->cbp_chroma = 0xffffffff;
        curr_slice->m_uMBInterSAD = MAX_SAD;     // very large SAD
    }
    if (m_PicParamSet.chroma_format_idc == 0) {
        // Monochrome
        cur_mb.LocalMacroblockInfo->cbp_chroma = 0; // Clear chroma blocks.
    }
#ifdef _INTRA_MODE_SWITCH_
    curr_slice->m_uMBIntra16x16SAD = uAIMBSAD_16x16;    // Save for mode possible switch later
#endif

    cur_mb.LocalMacroblockInfo->best_distortion =  best_sad;
    return best_sad;
}

//////////////////////////////////
// Compress one slice
template <class PixType, class CoeffsType>
Status H264CoreEncoder<PixType,CoeffsType>::Compress_Slice(H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice,
                                                           bool is_first_mb)
{
    H264CurrentMacroblockDescriptor<PixType, CoeffsType> &cur_mb = curr_slice->m_cur_mb;
    CH264pBs<PixType,CoeffsType>  *pBitstream = curr_slice->m_pbitstream;
    Ipp32s slice_num = curr_slice->m_slice_number;
    EnumSliceType slice_type = curr_slice->m_slice_type;
    Ipp8u uUsePCM = 0;
#ifdef H264_RD_OPT
    double lambda;
#endif

//    Ipp32s mbtype_stat[32];
//    memset( mbtype_stat, 0, 32*sizeof(Ipp32s));

    Ipp8u *pStartBits;
    Ipp32u uStartBitOffset;

    Ipp32u uRecompressMB;
    Ipp8u  iLastQP;
    Ipp32u uSaved_Skip_Run;

    Ipp8u bSeenFirstMB = false;

    Status status = UMC_OK;

    Ipp32u uNumMBs = m_HeightInMBs * m_WidthInMBs;
    Ipp32u uFirstMB = m_field_index*uNumMBs;

    Ipp32s MBYAdjust=0;
    if (m_field_index)
    {
        MBYAdjust  = m_HeightInMBs;
    }

    curr_slice->m_InitialOffset = m_InitialOffsets[m_pCurrentFrame->m_bottom_field_flag[m_field_index]];
    curr_slice->m_is_cur_mb_field = m_pCurrentFrame->m_PictureStructureForDec < FRM_STRUCTURE;
    curr_slice->m_is_cur_mb_bottom_field = m_pCurrentFrame->m_bottom_field_flag[m_field_index] == 1;

//    curr_slice->m_use_transform_for_intra_decision = m_info.use_transform_for_intra_decision ?
//            (curr_slice->m_slice_type == INTRASLICE) : false;
    curr_slice->m_use_transform_for_intra_decision = 1;

    // loop over all MBs in the picture
    for (Ipp32u uMB = uFirstMB; uMB < uFirstMB + uNumMBs; uMB++)
    {
        // Is this MB in the current slice?  If not, move on...
        if (m_pCurrentFrame->m_mbinfo.mbs[uMB].slice_id != slice_num) {
            continue;
        } else if (!bSeenFirstMB)
        {
            // Reset xpos and ypos in framedata struct
            // This is necessary because the same slice may be recoded multiple times.

            // reset intra MB counter per slice
            curr_slice->m_Intra_MB_Counter = 0;
            curr_slice->m_MB_Counter = 0;

            // Fill in the first mb in slice field in the slice header.
            curr_slice->m_first_mb_in_slice = is_first_mb ? 0 : uMB - uFirstMB;

            // Fill in the current deblocking filter parameters.
            curr_slice->m_slice_alpha_c0_offset = (Ipp8s)m_info.deblocking_filter_alpha;
            curr_slice->m_slice_beta_offset = (Ipp8s)m_info.deblocking_filter_beta;
            curr_slice->m_disable_deblocking_filter_idc =  m_info.deblocking_filter_idc;
            curr_slice->m_cabac_init_idc = m_info.cabac_init_idc;

            // Write a slice header
            pBitstream->PutSliceHeader(m_SliceHeader,
                                       m_PicParamSet,
                                       m_SeqParamSet,
                                       m_PicClass,
                                       curr_slice);
            bSeenFirstMB = true;

            // Fill in the correct value for m_iLastXmittedQP, used to correctly code
            // the per MB QP Delta
            curr_slice->m_iLastXmittedQP = m_PicParamSet.pic_init_qp + curr_slice->m_slice_qp_delta;
            Ipp32s SliceQPy = curr_slice->m_iLastXmittedQP;
#ifdef H264_RD_OPT
//            lambda = pow(2.0,MAX(0,(SliceQPy-12))/3.0);
//            lambda = pow(2.0,(SliceQPy-12)/3.0);
/*            if( slice_type == INTRASLICE ) lambda *= 0.85;
            else
*/            lambda *= 0.85;
            //if( slice_type == BPREDSLICE ) lambda *= IPP_MAX(2, IPP_MIN(4,SliceQPy/6)); //B slices
#endif

            if (m_info.entropy_coding_mode)
            {
                if (slice_type==INTRASLICE)
                    pBitstream->InitializeContextVariablesIntra_CABAC(SliceQPy);
                else
                    pBitstream->InitializeContextVariablesInter_CABAC(SliceQPy, curr_slice->m_cabac_init_idc);
            }

            // Initialize the MB skip run counter
            curr_slice->m_uSkipRun = 0;
        }

        cur_mb.lambda = int( pow(2.0,MAX(0,(curr_slice->m_iLastXmittedQP-12))/3.0)*0.85 );
        cur_mb.uMB = curr_slice->m_CurMBAddr = uMB;
        cur_mb.mbPtr = m_pCurrentFrame->m_pYPlane + m_pMBOffsets[uMB].uLumaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field];
        cur_mb.mbPitchPixels =  m_pCurrentFrame->pitchPixels()<<curr_slice->m_is_cur_mb_field;
        curr_slice->m_CurMB_X = (curr_slice->m_CurMBAddr % m_WidthInMBs);
        curr_slice->m_CurMB_Y = (curr_slice->m_CurMBAddr / m_WidthInMBs)- MBYAdjust;
        UpdateCurrentMBInfo(curr_slice);

        pSetMB8x8TSFlag(curr_slice->m_cur_mb.GlobalMacroblockInfo, 0);

        curr_slice->m_MB_Counter++;
        pBitstream->GetState(&pStartBits, &uStartBitOffset);
        iLastQP = curr_slice->m_iLastXmittedQP;
        uSaved_Skip_Run = curr_slice->m_uSkipRun;   // To restore it if we recompress
        uUsePCM = 0;    // Don't use the PCM mode initially.

        UpdateNeighbouringAddresses(curr_slice);
        UpdateNeighbouringBlocks(curr_slice);

        cur_mb.mb[MBTYPE_INTRA].sad = cur_mb.mb[MBTYPE_INTRA_16x16].sad = cur_mb.mb[MBTYPE_INTER].sad = 0xffffffff;
        cur_mb.mb[MBTYPE_INTRA].ssd = cur_mb.mb[MBTYPE_INTRA_16x16].ssd = cur_mb.mb[MBTYPE_INTER].ssd = 0xffffffff;
        cur_mb.mb[MBTYPE_INTRA].bits = cur_mb.mb[MBTYPE_INTRA_16x16].bits = cur_mb.mb[MBTYPE_INTER].bits = 0xffffffff; //(1<<31)-1;

        do {    // this is to recompress MBs that are too big.

            MB_Decision(curr_slice, uMB);

            Ipp32s mb_bits;
            Ipp32s bit_offset;
            if( m_PicParamSet.entropy_coding_mode ){
                bit_offset = pBitstream->m_nReadyBits;
                if(pBitstream->m_nReadyBits == 9) bit_offset=8;
            }
#ifdef H264_RD_OPT
            Ipp32s xi = 3;
            Ipp8s mbType = cur_mb.GlobalMacroblockInfo->mbtype;
            if( !IS_INTRA_MBTYPE(mbType) ) mbType = MBTYPE_INTER;
            Ipp32u bestSAD = cur_mb.mb[mbType].sad;
            H264MotionVector MBmvs[16*4];
            T_RefIdx         MBridx[16*2];
            //Copy INTER state
            memcpy(&MBmvs[0],cur_mb.MVs[LIST_0]->MotionVectors,sizeof(H264MotionVector)*16);
            memcpy(&MBmvs[16],cur_mb.MVs[LIST_1]->MotionVectors,sizeof(H264MotionVector)*16);
            memcpy(&MBmvs[32],cur_mb.MVs[LIST_0+2]->MotionVectors,sizeof(H264MotionVector)*16);
            memcpy(&MBmvs[48],cur_mb.MVs[LIST_1+2]->MotionVectors,sizeof(H264MotionVector)*16);
            memcpy(&MBridx[0],cur_mb.RefIdxs[LIST_0]->RefIdxs,sizeof(T_RefIdx)*16);
            memcpy(&MBridx[16],cur_mb.RefIdxs[LIST_1]->RefIdxs,sizeof(T_RefIdx)*16);
            if( m_PicParamSet.entropy_coding_mode ){
               pBitstream->SaveContext_CABAC();
            }
            do{
#endif
            // Code the macroblock, all planes
            // coefficients -> pRLEBuffer
            cur_mb.LocalMacroblockInfo->cbp_bits = 0;
            cur_mb.LocalMacroblockInfo->cbp_bits_chroma = 0;
            uSaved_Skip_Run = curr_slice->m_uSkipRun;
            CEncAndRecMB(curr_slice) ;

            mb_bits = 0;
            status = Put_MB(curr_slice);
            if (status != UMC_OK) 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) );
                mb_bits = bit_offset - pBitstream->m_nReadyBits;
            }

            Ipp8u *pEndBits;
            Ipp32u uEndBitOffset;
            pBitstream->GetState(&pEndBits, &uEndBitOffset);

            mb_bits += (Ipp32u) (pEndBits - pStartBits)*8;
            if (uEndBitOffset >= uStartBitOffset)
                mb_bits += uEndBitOffset - uStartBitOffset;
            else
                mb_bits -= uStartBitOffset - uEndBitOffset;

#ifdef H264_RD_OPT
//            if( slice_type != INTRASLICE ) break;
            mbType = cur_mb.GlobalMacroblockInfo->mbtype;
            if( !IS_INTRA_MBTYPE(mbType) ) mbType = MBTYPE_INTER;
            //if SADs are similar take RD optimized
            cur_mb.mb[mbType].bits = mb_bits;
            cur_mb.mb[mbType].skip_run = curr_slice->m_uSkipRun;
            memcpy( cur_mb.mb[mbType].intra_types, cur_mb.intra_types, 16);
            memcpy( cur_mb.mb[mbType].stream, pStartBits, (pEndBits - pStartBits + 1));
            cur_mb.mb[mbType].stream_size = (pEndBits - pStartBits + 1);
            cur_mb.mb[mbType].stream_offset = uEndBitOffset;
            memcpy(&(cur_mb.mb[mbType].locInfo),cur_mb.LocalMacroblockInfo,sizeof(H264MacroblockLocalInfo));
            memcpy(&(cur_mb.mb[mbType].globInfo),cur_mb.GlobalMacroblockInfo,sizeof(H264MacroblockGlobalInfo));
            memcpy(&(cur_mb.mb[mbType].coeffInfo), cur_mb.MacroblockCoeffsInfo, sizeof(H264MacroblockCoeffsInfo));
            memcpy(&cur_mb.mb[mbType].MBmvs[0],cur_mb.MVs[LIST_0]->MotionVectors,sizeof(H264MotionVector)*16);
            memcpy(&cur_mb.mb[mbType].MBmvs[16],cur_mb.MVs[LIST_1]->MotionVectors,sizeof(H264MotionVector)*16);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -