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

📄 umc_h264_aic.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 "vm_debug.h"
#include "umc_h264_video_encoder.h"
#include "umc_h264_tables.h"
#include "umc_h264_bme.h"

////////////////////////////////////////////////////////////////////////////////
// Intra4x4InitBlockParams
//
// Sets up the parameters for the 4x4 block level mode select function. Must
// be called once per MB prior to calling the mode select function.
//
////////////////////////////////////////////////////////////////////////////////
// Uncomment the following #define to remove the left MB dependency in the
// code to select the 4x4 Intra mode for a given block.
//#define NOINTRALEFTDEP

// 4x4 Prediction Details
//  The predictors for the 16 pels of a 4x4 block are obtained using pels
//  above and to the left of the block, used dependent upon prediction mode.
//
// Notation for comments regarding prediction and predictors.

// The pels of the 4x4 block are labelled a..p. The predictor pels above
// are labelled A..H, from the left I..L, and from above left M, as follows:
//
//  M A B C D E F G H
//  I a b c d
//  J e f g h
//  K i j k l
//  L m n o p

// Predictor array index definitions
#define P_Z PredPel[0]
#define P_A PredPel[1]
#define P_B PredPel[2]
#define P_C PredPel[3]
#define P_D PredPel[4]
#define P_E PredPel[5]
#define P_F PredPel[6]
#define P_G PredPel[7]
#define P_H PredPel[8]
#define P_I PredPel[9]
#define P_J PredPel[10]
#define P_K PredPel[11]
#define P_L PredPel[12]
#define P_M (PredPel[13])
#define P_N (PredPel[14])
#define P_O (PredPel[15])
#define P_P (PredPel[16])
#define P_Q (PredPel[17])
#define P_R (PredPel[18])
#define P_S (PredPel[19])
#define P_T (PredPel[20])
#define P_U (PredPel[21])
#define P_V (PredPel[22])
#define P_W (PredPel[23])
#define P_X (PredPel[24])

// Predicted pixel array offset macros
#define P_a pPredBuf[0]
#define P_b pPredBuf[1]
#define P_c pPredBuf[2]
#define P_d pPredBuf[3]
#define P_e pPredBuf[0+1*16]
#define P_f pPredBuf[1+1*16]
#define P_g pPredBuf[2+1*16]
#define P_h pPredBuf[3+1*16]
#define P_i pPredBuf[0+2*16]
#define P_j pPredBuf[1+2*16]
#define P_k pPredBuf[2+2*16]
#define P_l pPredBuf[3+2*16]
#define P_m pPredBuf[0+3*16]
#define P_n pPredBuf[1+3*16]
#define P_o pPredBuf[2+3*16]
#define P_p pPredBuf[3+3*16]

namespace UMC_H264_ENCODER
{

#define NUM_AI_MODES 9

Ipp32s intra_modes[4][8] = {
    {0,1,3,7,8,-1,-1,-1},
    {0,1,3,4,5, 6, 7, 8},
    {0,3,7,-1,-1,-1,-1,-1},
    {1,8,-1,-1,-1,-1,-1,-1}
};

////////////////////////////////////////////////////////////////////////////////
// AdvancedIntraModeSelectOneMacroblock
//
// Main function to drive advanced intra mode select for one macroblock.
////////////////////////////////////////////////////////////////////////////////
template <class PixType, class CoeffsType>
void H264CoreEncoder<PixType,CoeffsType>::AdvancedIntraModeSelectOneMacroblock(
    H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice,
    Ipp32u uMB,         // which MB
    Ipp32u uBestSAD,
    Ipp32u *puAIMBSAD       // return total MB SAD here
)
{
    H264CurrentMacroblockDescriptor<PixType, CoeffsType> &cur_mb = curr_slice->m_cur_mb;
    // All 9 intra modes are checked.  Since we treat all 4x4 blocks before
    // coding/decoding the prediction may not be based on decoded pixels (except
    // for some of the blocks).  Therefore original pixel data are used for
    // prediction in this assessment of intra coding.  This will result in
    // too good prediction.
    // To compensate for this the SAD for intra is given a 'handicap'
    // depending on QP.  Notice:  Original data is used for prediction only
    // in mode selection.  When real coding is performed, prediction is made
    // from decoded  data
    //Ipp32u uMBQP = curr_slice->m_cur_mb.LocalMacroblockInfo->QP;
    *puAIMBSAD = 0;//rd_quant_intra[uMBQP]; //TODO ADB

    // pointer to upper left pel of first block
    PixType *pBlock = cur_mb.mbPtr;
    PixType *rBlock = m_pReconstructFrame->m_pYPlane + m_pMBOffsets[uMB].uLumaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field];
    Ipp32s uBlock;

    if( m_Analyse & ANALYSE_RD_OPT ){
        curr_slice->fakeBitstream->CopyContext_CABAC(*(curr_slice->m_pbitstream));
        curr_slice->fakeBitstream->SaveContext_CABAC();
    }
    // loop over all 16 4x4 blocks in the MB
    for (uBlock = 0; uBlock < 16; uBlock++){
        PixType *pPredBuf = 0;

        if (curr_slice->m_use_transform_for_intra_decision)
            pPredBuf = cur_mb.mb4x4.prediction + xoff[uBlock] + yoff[uBlock]*16;

        if( m_Analyse & ANALYSE_RD_OPT && pPredBuf ){
        *puAIMBSAD += Intra4x4SelectRD(curr_slice,
                                           pBlock,         // source block
                                           rBlock,         // no reference block yet, use source for ref.
                                           uBlock,
                                           curr_slice->m_cur_mb.intra_types,
                                           pPredBuf);
        }else{
        // CPU-dependent call to block level mode select
        *puAIMBSAD += AIModeSelectOneBlock(curr_slice,
                                           pBlock,         // source block
                                           rBlock,         // no reference block yet, use source for ref.
                                           uBlock,
                                           curr_slice->m_cur_mb.intra_types,
                                           pPredBuf);      // no return of predictor pels
        }

#ifndef H264_RD_OPT
        if( *puAIMBSAD > uBestSAD ){
            return;  //Don't count anymore because previous SAD is better.
        }
#endif
        // next block
        pBlock += m_EncBlockOffsetInc[curr_slice->m_is_cur_mb_field][uBlock];
        rBlock += m_EncBlockOffsetInc[curr_slice->m_is_cur_mb_field][uBlock];
    }
    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;
        cur_mb.LocalMacroblockInfo->cbp_luma = curr_slice->m_uIntraCBP4x4;
        CEncAndRec4x4IntraMB(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;
    } else {
        Ipp32s iQP = getLumaQP51(curr_slice->m_cur_mb.LocalMacroblockInfo->QP, m_PicParamSet.bit_depth_luma);
        *puAIMBSAD += BITS_COST(24, glob_RDQM[iQP]);
    }
}   // AdvancedIntraModeSelectOneMacroblock


static const Ipp8u uBlockURPredOK[] = {
    // luma
    0xff, 0xff, 0xff, 0,
    0xff, 0xff, 0xff, 0,
    0xff, 0xff, 0xff, 0,
    0xff, 0,    0xff, 0
};

////////////////////////////////////////////////////////////////////////////////
//
// GetBlockPredPels
//
//  Obtains the above and left prediction pels for the 4x4 block,
//  following edge rules.
//
//  The prediction pel buffer is ordered as follows:
//
//  [0]:    M
//  [1..8]: A..H
//  [9..12] I..L
//
//  Predictors M and E..H are used only for the diagonal modes
//  (modes 3 and greater).
//
////////////////////////////////////////////////////////////////////////////////

template <class PixType, class CoeffsType>
void H264CoreEncoder<PixType,CoeffsType>::GetBlockPredPels(
    H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice,
    PixType* pLeftRefBlock,          // pointer to block in reference picture
    Ipp32u   uLeftPitch,             // of source data
    PixType* pAboveRefBlock,         // pointer to block in reference picture
    Ipp32u   uAbovePitch,            // of source data
    PixType* pAboveLeftRefBlock,     // pointer to block in reference picture
    Ipp32u   uAboveLeftPitch,        // of source data
    Ipp32u   uBlock,                 // 0..15 for luma blocks only
    PixType* PredPel)                // result here
{
    Ipp32s raster_block = block_subblock_mapping[uBlock];

    bool bLeft = false;
    if (BLOCK_IS_ON_LEFT_EDGE(raster_block)){
        bLeft = curr_slice->m_cur_mb.CurrentBlockNeighbours.mbs_left[raster_block / 4].mb_num < 0;
    }

    bool bTop = false;
    if (BLOCK_IS_ON_TOP_EDGE(raster_block)){
        bTop = curr_slice->m_cur_mb.CurrentBlockNeighbours.mb_above.mb_num < 0;
    }

    // get predictor pels from above and left blocks, following edge rules
    if (bTop && bLeft) {
        P_A = P_B = P_C = P_D =
        P_I = P_J = P_K = P_L = 1<<(m_PicParamSet.bit_depth_luma - 1);
    }else if (bTop && !bLeft) {
        for (Ipp32s i = 0; i < 4; i++) {
            PredPel[i+1] = PredPel[i+9] = (pLeftRefBlock + i*uLeftPitch)[-1];
        }
    }else if (!bTop && bLeft) {
        for (Ipp32s i = 0; i < 4; i++) {
            PredPel[i+1] = PredPel[i+9] =(pAboveRefBlock - uAbovePitch)[i];
        }
    }else {
        for (Ipp32s i = 0; i < 4; i++) {
            PredPel[i+1] = (pAboveRefBlock - uAbovePitch)[i];
            PredPel[i+9] = (pLeftRefBlock + i*uLeftPitch)[-1];
        }

        // for diagonal modes
        P_Z = (pAboveLeftRefBlock - uAboveLeftPitch)[-1];
    }

    if (!bTop) {
        // Get EFGH, predictors pels above and to the right of the block.
        // Use D when EFGH are not valid, which is when the block is on
        // the right edge of the MB and the MB is at the right edge of
        // the picture; or when the block is on the right edge of the MB
        // but not in the top row.
        bool bRight = raster_block == 3 ?
            curr_slice->m_cur_mb.CurrentBlockNeighbours.mb_above_right.mb_num < 0 : false;

        if (uBlockURPredOK[uBlock] == 0 || bRight)
        {
            P_E = P_F = P_G = P_H = P_D;
        } else {
            P_E = (pAboveRefBlock - uAbovePitch)[4];
            P_F = (pAboveRefBlock - uAbovePitch)[5];
            P_G = (pAboveRefBlock - uAbovePitch)[6];
            P_H = (pAboveRefBlock - uAbovePitch)[7];
        }
    }
}   // GetBlockPredPels

////////////////////////////////////////////////////////////////////////////////
//
// GetPredBlock
//
// Find advanced intra prediction block, store in PredBuf, which has a pitch

⌨️ 快捷键说明

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