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

📄 umc_h264_core_enc.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                        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 + -