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

📄 umc_h264_core_enc.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
//               INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//        Copyright (c) 2004 - 2007 Intel Corporation. All Rights Reserved.
//

#include <string.h>
#include <stddef.h>
#include <math.h>
#include "ippdefs.h"
#include "umc_h264_video_encoder.h"
#include "umc_h264_core_enc.h"
#include "umc_h264_tables.h"
#include "umc_h264_to_ipp.h"
#include "umc_h264_bme.h"
#include "umc_h264_deblocking_tools.h"

// Table to obtain edge info for a 4x4 block of a MB. The table entry when
// OR'd with the edge info for the MB, results in edge info for the block.
//
//  H264 4x4 Block ordering in a 16x16 Macroblock and edge assignments
//
//  ULC = Upper Left Corner, U = Upper Edge
//  L = Left Edge, R = Right Edge
//
//               luma (Y)                chroma (U)          chroma (V)
//
//        +-U--+-U--+-U--+-U--+         +-U--+-U--+         +-U--+-U--+
//        |    |    |    |    |         |    |    |         |    |    |
// ULC--> L 0  | 1  | 4  | 5  R  ULC--> L 16 | 17 R  ULC--> L 20 | 21 R
//        |    |    |    |    |         |    |    |         |    |    |
//        +----+----+----+----+         +----+----+         +----+----+
//        |    |    |    |    |         |    |    |         |    |    |
//        L 2  | 3  | 6  | 7  R         L 18 | 19 R         L 22 | 23 R
//        |    |    |    |    |         |    |    |         |    |    |
//        +----+----+----+----+         +----+----+         +----+----+
//        |    |    |    |    |
//        L 8  | 9  | 12 | 13 R
//        |    |    |    |    |
//        +----+----+----+----+
//        |    |    |    |    |
//        L 10 | 11 | 14 | 15 R
//        |    |    |    |    |
//        +----+----+----+----+
//
//  This table provides easy look-up by block number to determine
//  which edges is does NOT border on.
namespace UMC_H264_ENCODER
{

// Number of bits (header plus residual) that triggers a MB to be recoded with a higher QP (up to twice) or in PCM mode.
#define MB_RECODE_THRESH        2750

// Slices with Intra MBs over this percentage may be recoded as Intra
#define INTRA_PERCENTAGE_THRESHOLD 0.75

#if ((defined(__GNUC__) && defined(__APPLE__) && !defined(__ICC)))
template<class PixType, class CoeffsType>
Ipp8s H264CoreEncoder<PixType,CoeffsType>::GetReferenceField(Ipp8s *pFields,Ipp8s RefIndex)
{
    if (RefIndex<0) return -1;
    else{
                VM_ASSERT(pFields[RefIndex]>=0);
                return pFields[RefIndex];
    }
}

template<class PixType, class CoeffsType>
EncoderRefPicListStruct<PixType>* H264CoreEncoder<PixType, CoeffsType>::GetRefPicList(H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice, Ipp32u List,Ipp32s mb_cod_type,Ipp32s is_bottom_mb)
{
    EncoderRefPicListStruct<PixType> *pList;
    if (List == LIST_0)
        pList = &curr_slice->m_TempRefPicList[mb_cod_type][is_bottom_mb].m_RefPicListL0;
    else
        pList = &curr_slice->m_TempRefPicList[mb_cod_type][is_bottom_mb].m_RefPicListL1;
    return pList;
}    // RefPicLists
#endif

template <class PixType, class CoeffsType>
void H264CoreEncoder<PixType,CoeffsType>::Intra16x16SelectAndPredict(H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice, Ipp32u uMB, Ipp32u *puAIMBSAD, PixType *pPredBuf)
{
    T_AIMode BestMode;
    H264CurrentMacroblockDescriptor<PixType, CoeffsType>& cur_mb = curr_slice->m_cur_mb;

    if( m_Analyse & ANALYSE_RD_OPT ){
        *puAIMBSAD = Intra16x16SelectRD(curr_slice, cur_mb.mbPtr, m_pReconstructFrame->m_pYPlane + m_pMBOffsets[uMB].uLumaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field], cur_mb.mbPitchPixels, &BestMode, pPredBuf);
    }else{
        *puAIMBSAD = AIModeSelectOneMB_16x16(curr_slice, cur_mb.mbPtr, m_pReconstructFrame->m_pYPlane + m_pMBOffsets[uMB].uLumaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field], cur_mb.mbPitchPixels, &BestMode, pPredBuf);
    }
    curr_slice->m_cur_mb.LocalMacroblockInfo->intra_16x16_mode = BestMode;   // Selected mode is stored in block 0
    if (((m_Analyse & ANALYSE_RD_OPT) && (curr_slice->m_slice_type != INTRASLICE)) || (!(m_Analyse & ANALYSE_RD_OPT) && (m_Analyse & ANALYSE_RD_MODE))) {
        // for ANALYSE_RD_OPT it is need to calc Chroma for non INTRA slices
        CH264pBs<PixType,CoeffsType> *pBitstream = curr_slice->m_pbitstream;
        curr_slice->fakeBitstream->Reset();
        curr_slice->fakeBitstream->CopyContext_CABAC(*pBitstream);
        Ipp32s ob = curr_slice->fakeBitstream->m_nOutstandingBits;
        curr_slice->m_pbitstream = curr_slice->fakeBitstream;
        H264MacroblockLocalInfo sLocalMBinfo = *cur_mb.LocalMacroblockInfo;
        H264MacroblockGlobalInfo sGlobalMBinfo = *cur_mb.GlobalMacroblockInfo;
        pSetMB8x8TSPackFlag(cur_mb.GlobalMacroblockInfo, false);
        cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_INTRA_16x16;
        CEncAndRec16x16IntraMB(curr_slice);
        if (m_PicParamSet.chroma_format_idc)
            EncodeChroma(curr_slice);
        Put_MB(curr_slice);
        Ipp32s bs = curr_slice->fakeBitstream->GetBsOffset() + curr_slice->fakeBitstream->m_nOutstandingBits - ob;
        Ipp32s d = SSD16x16(cur_mb.mbPtr, cur_mb.mbPitchPixels, m_pReconstructFrame->m_pYPlane + m_pMBOffsets[uMB].uLumaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field], cur_mb.mbPitchPixels);
        Ipp32s uOffset = m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field];
        if (m_PicParamSet.chroma_format_idc != 0) {
            //TODO 420 only !!
            d += SSD8x8(m_pCurrentFrame->m_pUPlane + uOffset, cur_mb.mbPitchPixels, m_pReconstructFrame->m_pUPlane + uOffset, cur_mb.mbPitchPixels);
            d += SSD8x8(m_pCurrentFrame->m_pVPlane + uOffset, cur_mb.mbPitchPixels, m_pReconstructFrame->m_pVPlane + uOffset, cur_mb.mbPitchPixels);
        }
        *puAIMBSAD = d + cur_mb.lambda * bs;
        curr_slice->m_pbitstream = pBitstream;
        *cur_mb.LocalMacroblockInfo = sLocalMBinfo;
        *cur_mb.GlobalMacroblockInfo = sGlobalMBinfo;
    }
}   // Intra16x16SelectAndPredict

template <class PixType, class CoeffsType>
Ipp32u H264CoreEncoder<PixType,CoeffsType>::MB_Decision(H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice, Ipp32s uMB)
{
    Ipp32u best_sad, uAIMBSAD_16x16, uAIMBSAD_4x4, uAIMBSAD_8x8, uBestIntraSAD;
    MB_Type uBestIntraMBType;
    bool bIntra8x8 = false;
    T_AIMode intra_types_save[16];
    H264CurrentMacroblockDescriptor<PixType, CoeffsType> &cur_mb = curr_slice->m_cur_mb;
    Ipp8u  uMBQP = getLumaQP51(cur_mb.LocalMacroblockInfo->QP, m_PicParamSet.bit_depth_luma);
    Ipp32s MBHasEdges;

    best_sad = uAIMBSAD_4x4 = uAIMBSAD_8x8 = uBestIntraSAD = MAX_SAD>>1;
    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;
    cur_mb.LocalMacroblockInfo->cbp_luma = 0xffff;
    cur_mb.LocalMacroblockInfo->cbp_chroma = 0xffffffff;
    cur_mb.LocalMacroblockInfo->best_distortion = MAX_SAD;
    curr_slice->m_uIntraCBP4x4 = 0xffff;
    curr_slice->m_uIntraCBP8x8 = 0xffff;
    curr_slice->m_uMBInterSAD = MAX_SAD;

    if (curr_slice->m_slice_type != INTRASLICE)  {
#ifdef H264_NEW_ME
        curr_slice->m_uMBInterSAD = (BPREDSLICE == curr_slice->m_slice_type) ? ME_B(curr_slice) : ME_P(curr_slice);
#else
        CMEOneMB(curr_slice, uMB, &curr_slice->m_uMBInterSAD);
#endif
        // 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
        MBTypeValue MBTypeInter = cur_mb.GlobalMacroblockInfo->mbtype;
        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);
        cur_mb.mb[MBTYPE_INTER].sad = curr_slice->m_uMBInterSAD;

        Ipp32s mb_type = cur_mb.GlobalMacroblockInfo->mbtype;
        if (((m_Analyse & ANALYSE_RD_OPT) || (m_Analyse & ANALYSE_RD_MODE)) || (!((mb_type == MBTYPE_DIRECT) || (mb_type == MBTYPE_SKIPPED) || (curr_slice->m_uMBInterSAD < EmptyThreshold[uMBQP])))) {
            Intra16x16SelectAndPredict(curr_slice, uMB, &uAIMBSAD_16x16, cur_mb.mb16x16.prediction);
            cur_mb.mb[MBTYPE_INTRA_16x16].sad = uBestIntraSAD = uAIMBSAD_16x16;
            uBestIntraMBType = MBTYPE_INTRA_16x16;
            // FAST intra decision
            if (uAIMBSAD_16x16 <= 2 * curr_slice->m_uMBInterSAD && ((m_Analyse & ANALYSE_RD_OPT) || (m_Analyse & ANALYSE_RD_MODE) || (curr_slice->m_uMBInterSAD >= rd_quant_intra_min[uMBQP]))) {
                if ((m_Analyse & ANALYSE_I_4x4) || (m_info.transform_8x8_mode_flag && (m_Analyse & ANALYSE_I_8x8))) {
#ifndef  H264_RD_OPT
                    // Use edge detection to determine if the MB is a flat region
                    ippiEdgesDetect16x16(cur_mb.mbPtr, cur_mb.mbPitchPixels, EdgePelDiffTable[uMBQP], EdgePelCountTable[uMBQP], &MBHasEdges);
                    if (MBHasEdges) {
#endif
                        if (m_info.transform_8x8_mode_flag && (m_Analyse & ANALYSE_I_8x8)) {
                            pSetMB8x8TSFlag(curr_slice->m_cur_mb.GlobalMacroblockInfo, true);
                            AdvancedIntraModeSelectOneMacroblock8x8(curr_slice, uMB, uBestIntraSAD, &uAIMBSAD_8x8);
                            //Save intra_types
                            memcpy(intra_types_save, curr_slice->m_cur_mb.intra_types, 16*sizeof(T_AIMode));
                            if (uAIMBSAD_8x8 < uBestIntraSAD) {
                                uBestIntraSAD = 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, uBestIntraSAD, &uAIMBSAD_4x4);
                            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 < uBestIntraSAD) {
                                uBestIntraSAD = uAIMBSAD_4x4;
                                uBestIntraMBType = MBTYPE_INTRA;
                                bIntra8x8 = false;
                            }
                        }
#ifndef  H264_RD_OPT
                    }
#endif
                }
            }
            curr_slice->m_uMBIntraSAD = uBestIntraSAD;
            if (!((m_Analyse & ANALYSE_RD_OPT) || (m_Analyse & ANALYSE_RD_MODE)) && (m_Analyse & ANALYSE_ME_CHROMA) && m_PicParamSet.chroma_format_idc != 0) {
                Ipp8u mode;
                Ipp32s  uOffset = m_pMBOffsets[uMB].uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field];
                PixType* pPredBuf = cur_mb.mbChromaIntra.prediction;
                //Get intra chroma prediction
                uBestIntraSAD += AIModeSelectChromaMBs_8x8(curr_slice, m_pCurrentFrame->m_pUPlane + uOffset, m_pReconstructFrame->m_pUPlane + uOffset,
                    m_pCurrentFrame->m_pVPlane + uOffset, m_pReconstructFrame->m_pVPlane + uOffset, cur_mb.mbPitchPixels, &mode, pPredBuf, pPredBuf+8);
            }
            if (!((m_Analyse & ANALYSE_RD_OPT) || (m_Analyse & ANALYSE_RD_MODE)) && (curr_slice->m_slice_type == BPREDSLICE))
                uBestIntraSAD += BITS_COST(9, glob_RDQM[uMBQP]);
            if (uBestIntraSAD < curr_slice->m_uMBInterSAD) {
                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_Intra_MB_Counter++;
                best_sad = uBestIntraSAD;
            } else {
                cur_mb.GlobalMacroblockInfo->mbtype = MBTypeInter;
                cur_mb.LocalMacroblockInfo->cbp_luma = curr_slice->m_uInterCBP4x4;
                best_sad = curr_slice->m_uMBInterSAD;
                pSetMB8x8TSPackFlag(cur_mb.GlobalMacroblockInfo, curr_slice->m_InterMB8x8PackFlag);
            }
        } else {
            best_sad = curr_slice->m_uMBInterSAD;
        }
    } else { // intra slice
        Intra16x16SelectAndPredict(curr_slice, uMB, &uAIMBSAD_16x16, cur_mb.mb16x16.prediction);
        uBestIntraMBType = MBTYPE_INTRA_16x16;
        cur_mb.mb[MBTYPE_INTRA_16x16].sad = best_sad = uAIMBSAD_16x16;
        if ((m_Analyse & ANALYSE_I_4x4) || (m_info.transform_8x8_mode_flag && (m_Analyse & ANALYSE_I_8x8))) {
#ifndef  H264_RD_OPT
            // Use edge detection to determine if the MB is a flat region
            ippiEdgesDetect16x16(cur_mb.mbPtr, cur_mb.mbPitchPixels, EdgePelDiffTable[uMBQP], EdgePelCountTable[uMBQP], &MBHasEdges);
            if (MBHasEdges) {
#else
            // cur_mb.mb[MBTYPE_INTRA_16x16].ssd = SSD16x16(cur_mb.mbPtr, cur_mb.mbPitchPixels, cur_mb.mb16x16.reconstruct, 16 );
#endif

⌨️ 快捷键说明

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