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

📄 umc_h264_core_enc.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:

    // 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;
#endif

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.

/*    fprintf(stderr, "Real Blocks: %d\n", slice_type);
    for( Ipp32s i = 0; i<32; i++ ){
        fprintf(stderr,"%d %d | ",i,mbtype_stat[i]);
    }
    fprintf(stderr,"\n");
*/
    return status;

}   // Compress_Slice

template <class PixType, class CoeffsType>
Ipp32s H264CoreEncoder<PixType,CoeffsType>::ComputeMBFrameFieldCost(H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice,
                                                                    bool is_frame)
{
    curr_slice->m_CurMB_X = ((curr_slice->m_CurMBAddr>>1) % m_WidthInMBs);
    if ((curr_slice->m_CurMBAddr&1)==0)
    {
        curr_slice->m_CurMB_Y = ((curr_slice->m_CurMBAddr>>1) / m_WidthInMBs)*2;
    } else {
        curr_slice->m_CurMB_Y = ((curr_slice->m_CurMBAddr>>1) / m_WidthInMBs)*2;
        if (!is_frame)
            curr_slice->m_CurMB_Y ++;
    }

    UpdateCurrentMBInfo(curr_slice);

    SetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[curr_slice->m_CurMBAddr], is_frame ? 0 : 1);
    SetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[curr_slice->m_CurMBAddr+1], is_frame ? 0 : 1);
    curr_slice->m_is_cur_mb_field = pGetMBFieldDecodingFlag(curr_slice->m_cur_mb.GlobalMacroblockInfo);
    UpdateNeighbouringAddresses(curr_slice);
    UpdateNeighbouringBlocks(curr_slice);

    return MB_Decision(curr_slice, curr_slice->m_CurMBAddr);
}

template <class PixType, class CoeffsType>
void H264CoreEncoder<PixType,CoeffsType>::MBFrameFieldSelect(H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice)
{
    H264MBAddr &curMBAddr = curr_slice->m_CurMBAddr;
#if 1
    Ipp32u uOffset = m_pMBOffsets[curMBAddr].uLumaOffset[true][false];
    PixType * curr = m_pCurrentFrame->m_pYPlane + uOffset;
    Ipp32s pitchPixels = m_pCurrentFrame->pitchPixels();
    Ipp32s pitchBytes = m_pCurrentFrame->pitchBytes();
    Ipp32s frame_sad = SAD16x16(curr, pitchBytes, curr + pitchPixels, pitchBytes) + SAD16x16(curr + 16*pitchPixels, pitchBytes, curr + 17*pitchPixels, pitchBytes);
    Ipp32s field_sad = SAD16x16(curr, pitchBytes << 2, curr + (pitchPixels << 2), pitchBytes << 2) + SAD16x16(curr + pitchPixels, pitchBytes << 2, curr + (pitchPixels << 2) + pitchPixels, pitchBytes << 2);

    if ((frame_sad - field_sad) > 0)
    {
        SetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[curMBAddr],   1);
        SetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[curMBAddr+1], 1);
    } else {
        SetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[curMBAddr],   0);
        SetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[curMBAddr+1], 0);
    }

#elif 1
    Ipp32u field_sad = ComputeMBFrameFieldCost(false);
    curMBAddr++;
    field_sad += ComputeMBFrameFieldCost(false);
    curMBAddr--;

    Ipp32u frame_sad = ComputeMBFrameFieldCost(true);
    curMBAddr++;
    frame_sad += ComputeMBFrameFieldCost(true);
    curMBAddr--;

    if (field_sad < frame_sad)
    {
        SetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[curMBAddr],1);
        SetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[curMBAddr+1],1);
        curr_slice->m_is_cur_mb_field = pGetMBFieldDecodingFlag(cur_mb.GlobalMacroblockInfo);
    }

#else
        SetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[curMBAddr],0);
        SetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[curMBAddr+1],0);
#endif
}

template <class PixType, class CoeffsType>
Status H264CoreEncoder<PixType,CoeffsType>::Compress_Slice_MBAFF(H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice)
{
    Ipp32s slice_num = curr_slice->m_slice_number;
    Ipp32u uAIMBSAD;            // MB prediction SAD for INTRA 4x4 mode
    Ipp32u uAIMBSAD_16x16;      // MB prediction SAD for INTRA 16x16 mode
    Ipp32u uBestIntraSAD;
    Ipp8u  uMBQP;
    Ipp32u uMinIntraSAD;
    MB_Type uBestIntraMBType;
    Ipp8u   uUsePCM = 0;

    Ipp8u *pStartBits;
    Ipp32u uStartBitOffset;

    Ipp32u uRecompressMB;
    Ipp8s  iLastQP;
    Ipp32u uSaved_Skip_Run;

    Ipp8u bSeenFirstMB = false;

    Status status = UMC_OK;

    H264CurrentMacroblockDescriptor<PixType, CoeffsType> &cur_mb = curr_slice->m_cur_mb;
    H264MBAddr &curMBAddr = curr_slice->m_CurMBAddr;
    CH264pBs<PixType,CoeffsType>  *pBitstream = curr_slice->m_pbitstream;
    Ipp32u uNumMBs = m_HeightInMBs * m_WidthInMBs;
    Ipp32u uFirstMB = m_field_index*uNumMBs;

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

    // 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 = uMB >> 1;

            // 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;

            if (m_info.entropy_coding_mode)
            {
                if (curr_slice->m_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;
        }

        curr_slice->m_CurMBAddr = uMB;
        if ((uMB&1)==0) MBFrameFieldSelect(curr_slice);
        curr_slice->m_CurMB_X = ((curr_slice->m_CurMBAddr>>1) % m_WidthInMBs);
        if ((curr_slice->m_CurMBAddr&1)==0)
        {
            curr_slice->m_CurMB_Y = ((curr_slice->m_CurMBAddr>>1) / m_WidthInMBs)*2;
        }
        else
        {
            if (!GetMBFieldDecodingFlag(m_pCurrentFrame->m_mbinfo.mbs[curr_slice->m_CurMBAddr]))
                curr_slice->m_CurMB_Y ++;
        }
        UpdateCurrentMBInfo(curr_slice);

        pSetMB8x8TSFlag(cur_mb.GlobalMacroblockInfo, 0);

        curr_slice->m_MB_Counter++;
        curr_slice->m_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);

        curr_slice->m_is_cur_mb_field = pGetMBFieldDecodingFlag(cur_mb.GlobalMacroblockInfo);
        curr_slice->m_InitialOffset = m_InitialOffsets[curr_slice->m_is_cur_mb_field & curMBAddr];
        curr_slice->m_is_cur_mb_bottom_field = (curr_slice->m_is_cur_mb_field & curMBAddr) == 1;

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

            uMBQP = getLumaQP51(cur_mb.LocalMacroblockInfo->QP, m_PicParamSet.bit_depth_luma);

            cur_mb.LocalMacroblockInfo->cbp_chroma =
            cur_mb.LocalMacroblockInfo->cbp_luma =
                cur_mb.LocalMacroblockInfo->cbp_bits =
                cur_mb.LocalMacroblockInfo->cbp_bits_chroma =
                cur_mb.LocalMacroblockInfo->cbp =
                cur_mb.LocalMacroblockInfo->intra_chroma_mode = 0;
            cur_mb.LocalMacroblockInfo->sbdir[0] =
                cur_mb.LocalMacroblockInfo->sbdir[1] =
                cur_mb.LocalMacroblockInfo->sbdir[2] =
                cur_mb.LocalMacroblockInfo->sbdir[3] = D_DIR_FWD;

            Ipp32s MBHasEdges;

            // Use edge detection to determine if the MB is a flat region
            ippiEdgesDetect16x16(m_pCurrentFrame->m_pYPlane + m_pMBOffsets[uMB].uLumaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field],
                m_pCurrentFrame->pitchBytes()<<curr_slice->m_is_cur_mb_field,uMBQP/2,EdgePelCountTable[uMBQP],&MBHasEdges);

            if (curr_slice->m_slice_type != INTRASLICE)
            {
                // find the best INTER mode and vectors for all blocks in MB
                // results to MBDataCurrent and MVCurrent
                CMEOneMB(curr_slice, uMB, &curr_slice->m_uMBInterSAD);

                // MB type classification
                // Only need to change anything if INTRA is chosen, as the ME
                // function filled in MB info for best INTER mode and cbp's.

                // save INTER results for possible later switch back to INTER
                curr_slice->m_uInterCBP4x4 = cur_mb.LocalMacroblockInfo->cbp_luma;
                curr_slice->m_InterMBType = static_cast<MB_Type>(cur_mb.GlobalMacroblockInfo->mbtype);
                curr_slice->m_InterMB8x8PackFlag = pGetMB8x8TSPackFlag(cur_mb.GlobalMacroblockInfo);
                uMinIntraSAD = rd_quant_intra_min[uMBQP];

                // For non-Intra pictures, if the macroblock has edges and
                // m_uMBInterSAD is above a minimum threshold, we will check
                // both 4x4 and 16x16 intra SADs. Otherwise, we just check the
                // 16x16 intra SAD.
                if (MBHasEdges && (curr_slice->m_uMBInterSAD >= uMinIntraSAD))
                {
                    // 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,

⌨️ 快捷键说明

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