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

📄 umc_h264_aic.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// of sizeof(PixSize)*16.
//
////////////////////////////////////////////////////////////////////////////////

template <class PixType, class CoeffsType>
void H264CoreEncoder<PixType,CoeffsType>::GetPredBlock(Ipp32u uMode, PixType *pPredBuf, PixType *PredPel)
{
    Ipp32u sum;
    Ipp32s i, j;
    PixType PredVal;

    // for the specified mode create the prediction block from the predictor
    // pels
    switch (uMode)
    {
    case 0:
        // mode 0: vertical prediction (from above)
        for (j = 0; j < 4; j++) {
            for (i = 0; i < 4; i++) {
                pPredBuf[i] = PredPel[i+1]; // ABCD
            }
            pPredBuf += 16;
        }
        break;

    case 1:
        // mode 1: horizontal prediction (from left)
        for (j = 0; j < 4; j++) {
            for (i = 0; i < 4; i++) {
                pPredBuf[i] = PredPel[j+9]; // IJKL
            }
            pPredBuf += 16;
        }
        break;

    case 2:
        // mode 2: DC prediction
        sum = 0;
        for (i = 0; i < 4; i++) {
            sum += PredPel[i+9];    // IJKL
            sum += PredPel[i+1];    // ABCD
        }
        PredVal = (PixType)((sum + 4) / 8);

        for (j = 0; j < 4; j++) {
            for (i = 0; i < 4; i++) {
                // Warning: The WinCE compiler generated incorrect code (storing
                // predictor in the first byte only) when the following line of
                // code was:
                // pPredBuf[i] = (PixType)sum;
                pPredBuf[i] = PredVal;
            }
            pPredBuf += 16;
        }
        break;

    case 3:
        // mode 3: diagonal down/left prediction
        P_a =                   (P_A + ((P_B) << 1) + P_C + 2) >> 2;
        P_b = P_e =             (P_B + ((P_C) << 1) + P_D + 2) >> 2;
        P_c = P_f = P_i =       (P_C + ((P_D) << 1) + P_E + 2) >> 2;
        P_d = P_g = P_j = P_m = (P_D + ((P_E) << 1) + P_F + 2) >> 2;
        P_h = P_k = P_n =       (P_E + ((P_F) << 1) + P_G + 2) >> 2;
        P_l = P_o =             (P_F + ((P_G) << 1) + P_H + 2) >> 2;
        P_p =                   (P_G + ((P_H) << 1) + P_H + 2) >> 2;
        break;

    case 4:
        // mode 4: diagonal down/right prediction
        P_m =                   (P_J + ((P_K) << 1) + P_L + 2) >> 2;
        P_i = P_n =             (P_I + ((P_J) << 1) + P_K + 2) >> 2;
        P_e = P_j = P_o =       (P_Z + ((P_I) << 1) + P_J + 2) >> 2;
        P_a = P_f = P_k = P_p = (P_A + ((P_Z) << 1) + P_I + 2) >> 2;
        P_b = P_g = P_l =       (P_Z + ((P_A) << 1) + P_B + 2) >> 2;
        P_c = P_h =             (P_A + ((P_B) << 1) + P_C + 2) >> 2;
        P_d =                   (P_B + ((P_C) << 1) + P_D + 2) >> 2;
        break;

    case 5 :
        // mode 5: vertical-right prediction
        P_a = P_j = (P_Z + P_A + 1) >> 1;
        P_b = P_k = (P_A + P_B + 1) >> 1;
        P_c = P_l = (P_B + P_C + 1) >> 1;
        P_d =       (P_C + P_D + 1) >> 1;
        P_e = P_n = (P_I + ((P_Z) << 1) + P_A + 2) >> 2;
        P_f = P_o = (P_Z + ((P_A) << 1) + P_B + 2) >> 2;
        P_g = P_p = (P_A + ((P_B) << 1) + P_C + 2) >> 2;
        P_h =       (P_B + ((P_C) << 1) + P_D + 2) >> 2;
        P_i =       (P_Z + ((P_I) << 1) + P_J + 2) >> 2;
        P_m =       (P_I + ((P_J) << 1) + P_K + 2) >> 2;
        break;

    case 6 :
        // mode 6: horizontal-down prediction
        P_a = P_g = (P_Z + P_I + 1) >> 1;
        P_b = P_h = (P_I + ((P_Z) << 1) + P_A + 2) >> 2;
        P_c =       (P_Z + ((P_A) << 1) + P_B + 2) >> 2;
        P_d =       (P_A + ((P_B) << 1) + P_C + 2) >> 2;
        P_e = P_k = (P_I + P_J + 1) >> 1;
        P_f = P_l = (P_Z + ((P_I) << 1) + P_J + 2) >> 2;
        P_i = P_o = (P_J + P_K + 1) >> 1;
        P_j = P_p = (P_I + ((P_J) << 1) + P_K + 2) >> 2;
        P_m =       (P_K + P_L + 1) >> 1;
        P_n =       (P_J + ((P_K) << 1) + P_L + 2) >> 2;
        break;

    case 7 :
        // mode 7: vertical-left prediction
        P_a =       (P_A + P_B + 1) >> 1;
        P_b = P_i = (P_B + P_C + 1) >> 1;
        P_c = P_j = (P_C + P_D + 1) >> 1;
        P_d = P_k = (P_D + P_E + 1) >> 1;
        P_l =       (P_E + P_F + 1) >> 1;
        P_e =       (P_A + ((P_B) << 1) + P_C + 2) >> 2;
        P_f = P_m = (P_B + ((P_C) << 1) + P_D + 2) >> 2;
        P_g = P_n = (P_C + ((P_D) << 1) + P_E + 2) >> 2;
        P_h = P_o = (P_D + ((P_E) << 1) + P_F + 2) >> 2;
        P_p =       (P_E + ((P_F) << 1) + P_G + 2) >> 2;
        break;

    case 8 :
        // mode 8: horizontal-up prediction
        P_a =       (P_I + P_J + 1) >> 1;
        P_b =       (P_I + ((P_J) << 1) + P_K + 2) >> 2;
        P_c = P_e = (P_J + P_K + 1) >> 1;
        P_d = P_f = (P_J + ((P_K) << 1) + P_L + 2) >> 2;
        P_g = P_i = (P_K + P_L + 1) >> 1;
        P_h = P_j = (P_K + ((P_L) << 1) + P_L + 2) >> 2;
        P_k = P_l = P_m = P_n = P_o = P_p = (P_L);
        break;

    default:
        break;
    }   // switch
}   // GetPredBlock

////////////////////////////////////////////////////////////////////////////////
//
// AIModeSelectOneBlock
//
// Choose the best advanced intra mode for coding one block, store at
// *pMode. Also return the RD-adjusted SAD for the chosen mode. Also
// save predictor pels in provided buffer when the buffer pointer is
// not NULL.
//
// Used both in ME phase, for INTRA/INTER decision using original source
// pels for predictors, and later in block encoding using reconstructed
// pels for predictors.
//
//
// In the ME phase (signaled by pPred==NULL) only modes 0,1,2 are checked
// in the interest of CPU performance. The resulting best SAD is good enough
// for MB mode selection.
//
////////////////////////////////////////////////////////////////////////////////

template <class PixType, class CoeffsType>
Ipp32u H264CoreEncoder<PixType,CoeffsType>::AIModeSelectOneBlock(
                             H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice,
                             PixType*  pSrcBlock,         // pointer to upper left pel of source block
                             PixType*  pReconBlock,         // pointer to same block in reconstructed picture
                             Ipp32u    uBlock,            // which 4x4 of the MB (0..15)
                             T_AIMode* intra_types,       // selected mode goes here
                             PixType*  pPred)             // predictor pels for selected mode goes here
                             // if not NULL
{
    Ipp32u uMinSAD;
    T_AIMode Mode, ModeAbove, ModeLeft, ProbMode;
    __ALIGN16 PixType uPred[16*NUM_AI_MODES*4]; // predictor pels, all modes, each 4 rows, pitch=16
    PixType PredPel[13];

    T_AIMode *pMode = &intra_types[uBlock];

    // get AI mode of block above and block to left to use to add bit cost
    // of signaling each mode for this block to SAD. Take care not to go
    // beyond the AIMode array, at top and left picture edges.
    ModeLeft = -1;
#ifdef NOINTRALEFTDEP
    // If this block is on the left MB edge, assume we don't know anything about the block to the left.
    if (BLOCK_IS_ON_LEFT_EDGE(block_subblock_mapping[uBlock]))
    {
        if (curr_slice->m_cur_mb.CurrentBlockNeighbours.mbs_left[block_subblock_mapping[uBlock] / 4].mb_num >= 0)
            ModeLeft = 2;
    } else {
        Ipp32s block_num = block_subblock_mapping[uBlock] - 1; // neighbour in non-raster order
        block_num = block_subblock_mapping[block_num];
        ModeLeft = intra_types[block_num];
    }
#else
    if (BLOCK_IS_ON_LEFT_EDGE(block_subblock_mapping[uBlock]))
    {
        H264BlockLocation block = curr_slice->m_cur_mb.CurrentBlockNeighbours.mbs_left[block_subblock_mapping[uBlock] >> 2];
        if (block.mb_num >= 0)
        {
            ModeLeft = m_mbinfo.intra_types[block.mb_num].intra_types[block_subblock_mapping[block.block_num]];
        }
    } else {
        Ipp32s block_num = block_subblock_mapping[uBlock] - 1; // neighbour in non-raster order
        block_num = block_subblock_mapping[block_num];
        ModeLeft = intra_types[block_num];
    }
#endif // NOINTRALEFTDEP

    ModeAbove = -1;
    if (BLOCK_IS_ON_TOP_EDGE(block_subblock_mapping[uBlock]))
    {
        H264BlockLocation block = curr_slice->m_cur_mb.CurrentBlockNeighbours.mb_above;
        if (block.mb_num >= 0)
        {
            block.block_num += block_subblock_mapping[uBlock];
            ModeAbove = m_mbinfo.intra_types[block.mb_num].intra_types[block_subblock_mapping[block.block_num]];
        }
    }else {
        Ipp32s block_num = block_subblock_mapping[uBlock] - 4; // neighbour in non-raster order
        block_num = block_subblock_mapping[block_num];
        ModeAbove = intra_types[block_num];
    }

    Ipp32s pitchPixels = m_pCurrentFrame->pitchPixels()<<curr_slice->m_is_cur_mb_field;

    PixType* pLeftRefBlock;
    Ipp32u uLeftPitch;
    PixType* pAboveRefBlock;
    Ipp32u uAbovePitch;
    PixType* pAboveLeftRefBlock;
    Ipp32u uAboveLeftPitch;

    if (curr_slice->m_use_transform_for_intra_decision){
        uLeftPitch = uAbovePitch = uAboveLeftPitch = 16;
#ifdef H264_RD_OPT
        pLeftRefBlock = pAboveRefBlock = pAboveLeftRefBlock = curr_slice->m_cur_mb.mb4x4.reconstruct + xoff[uBlock] + yoff[uBlock]*16;
#else
        pLeftRefBlock = pAboveRefBlock = pAboveLeftRefBlock = pPred + 256;
#endif
        if (ModeAbove == -1 || BLOCK_IS_ON_TOP_EDGE(block_subblock_mapping[uBlock])){
            pAboveRefBlock = pReconBlock;
            uAbovePitch = pitchPixels;
            pAboveLeftRefBlock = pReconBlock;
            uAboveLeftPitch = pitchPixels;
        }

        if (BLOCK_IS_ON_LEFT_EDGE(block_subblock_mapping[uBlock])){
            pLeftRefBlock = pReconBlock;
            uLeftPitch = pitchPixels;
            pAboveLeftRefBlock = pReconBlock;
            uAboveLeftPitch = pitchPixels;
        }
    } else {
        pLeftRefBlock = pReconBlock;
        uLeftPitch = pitchPixels;
        pAboveRefBlock = pReconBlock;
        uAbovePitch = pitchPixels;
        pAboveLeftRefBlock = pReconBlock;
        uAboveLeftPitch = pitchPixels;
    }

    // Get the above and left predictor pels to PredPel
    GetBlockPredPels(curr_slice, pLeftRefBlock, uLeftPitch, pAboveRefBlock, uAbovePitch, pAboveLeftRefBlock, uAboveLeftPitch, uBlock, PredPel);

    // If all the predictor pels are equal, all modes will give the same results.
    Ipp32s iQP = getLumaQP51(curr_slice->m_cur_mb.LocalMacroblockInfo->QP, m_PicParamSet.bit_depth_luma);
    ProbMode = MIN(ModeAbove, ModeLeft);
    if (ProbMode == -1) ProbMode = 2;

    GetPredBlock(2, &uPred[2*64], PredPel);
    if (m_Analyse & ANALYSE_SAD)
        uMinSAD = BITS_COST((ProbMode == 2)? 1:4, glob_RDQM[iQP]) + SAD4x4(pSrcBlock, pitchPixels*sizeof(PixType), &uPred[2*64], 16*sizeof(PixType));
    else
        uMinSAD = BITS_COST((ProbMode == 2)? 1:4, glob_RDQM[iQP]) + SATD4x4(pSrcBlock, pitchPixels*sizeof(PixType), &uPred[2*64], 16*sizeof(PixType));
    *pMode = 2;

    Ipp32s* modes;
    Ipp32s nmodes=0;

    if( ( ModeAbove >= 0 ) && ( ModeLeft >= 0 ) ){
        if (!uBlock && (curr_slice->m_cur_mb.CurrentBlockNeighbours.mb_above_left.mb_num < 0)){
            modes = &intra_modes[0][0];
            nmodes=5;
        }else{
            modes = &intra_modes[1][0];
            nmodes=8;
        }
    }else if( ModeAbove >= 0){
        modes = &intra_modes[2][0];
        nmodes=3;
    }else if( ModeLeft >= 0 ){
        modes = &intra_modes[3][0];
        nmodes=2;
    }

    if( nmodes ){
        Ipp32u ModeSAD[9];
        Ipp32s i;

        if (m_Analyse & ANALYSE_SAD){
            for (i=0; i < nmodes; i++){
                Mode = modes[i];
                GetPredBlock(Mode, &uPred[Mode*64], PredPel);

⌨️ 快捷键说明

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