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

📄 umc_h264_me.cpp

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

    if (mvy + padded_y + MBYoffset + sbheight >= height)
    {
        return PREDICTION_FROM_BOTTOM;
    }

    return ALLOK;
}

template <class PixType, class CoeffsType>
void H264CoreEncoder<PixType,CoeffsType>::Interpolate(const Ipp32s mb_decoding_flag,
                                                      const PixType* src,
                                                            Ipp32s   src_pitch,
                                                            PixType* dst,
                                                            Ipp32s   dst_pitch,
                                                            Ipp32s   xh,
                                                            Ipp32s   yh,
                                                            IppiSize sz,
                                                            Ipp32s   mvy,
                                                            Ipp32s   mb_y_pos,
                                                            Ipp32s   sb_y_pos)
{
    Ipp32s mbYOffset = (mb_y_pos >> mb_decoding_flag) + sb_y_pos; //m_CurMB_Y * 16 + sb_pos;
    Ipp32s yint = mvy >> 2;
    Ipp32s height = (m_HeightInMBs << 4)  >> mb_decoding_flag;

    Ipp8u pred_method = SelectPredictionMethod(
        mbYOffset,
        mvy,
        sz.height,
        height);

    switch(pred_method)
    {
        case ALLOK:
            ippiInterpolateLuma_H264(src, src_pitch*sizeof(PixType),
                dst, dst_pitch*sizeof(PixType),
                xh, yh, sz, m_PicParamSet.bit_depth_luma);
            break;

        case PREDICTION_FROM_TOP:
            ippiInterpolateLumaTop_H264(src, src_pitch*sizeof(PixType),
                dst, dst_pitch*sizeof(PixType),
                xh, yh, - ((Ipp32s)mbYOffset + yint), sz, m_PicParamSet.bit_depth_luma);
            break;

        case PREDICTION_FROM_BOTTOM:
            ippiInterpolateLumaBottom_H264(src, src_pitch*sizeof(PixType),
                dst, dst_pitch*sizeof(PixType),
                xh, yh, ((Ipp32s)mbYOffset + yint + sz.height) - (height), sz, m_PicParamSet.bit_depth_luma);
            break;

        default:
            VM_ASSERT(false);
            break;
    }
}

template <class PixType, class CoeffsType>
void H264CoreEncoder<PixType,CoeffsType>::Interpolate_Cr(const Ipp32s  mb_decoding_flag,
                                                         const PixType* src,
                                                               Ipp32s   src_pitch,
                                                               PixType* dst,
                                                               Ipp32s dst_pitch,
                                                               Ipp32s xh,
                                                               Ipp32s yh,
                                                               IppiSize sz,
                                                               Ipp32s mvy,
                                                               Ipp32s mb_y_pos,
                                                               Ipp32s sb_y_pos)
{
    Ipp32s mbYOffset = (mb_y_pos >> mb_decoding_flag) + sb_y_pos; //m_CurMB_Y * 16 + sb_pos;
    Ipp32s yint = mvy >> 3;
    Ipp32s height = (m_HeightInMBs << 4) >> mb_decoding_flag;

    Ipp8u pred_method = SelectPredictionMethod(
        mbYOffset,
        mvy,
        sz.height*2,
        height);

    switch(pred_method)
    {
        case ALLOK:
            ippiInterpolateChroma_H264(src, src_pitch*sizeof(PixType),
                dst, dst_pitch*sizeof(PixType),
                xh, yh, sz, m_SeqParamSet.bit_depth_chroma);
            break;

        case PREDICTION_FROM_TOP:
            ippiInterpolateChromaTop_H264(src, src_pitch*sizeof(PixType),
                dst, dst_pitch*sizeof(PixType),
                xh, yh, - ((Ipp32s)mbYOffset/2 + yint), sz, m_SeqParamSet.bit_depth_chroma);
            break;

        case PREDICTION_FROM_BOTTOM:
            ippiInterpolateChromaBottom_H264(src, src_pitch*sizeof(PixType),
                dst, dst_pitch*sizeof(PixType),
                xh, yh, ((Ipp32s)mbYOffset/2 + yint + sz.height) - (height)/2, sz, m_SeqParamSet.bit_depth_chroma);
            break;

        default:
            VM_ASSERT(false);
            break;
    }
}


////////////////////////////////////////////////////////////////////////////////
// FindBestInitialMV
// Return the best Initial 16x16 MV from the possible candidates:
////////////////////////////////////////////////////////////////////////////////
template <class PixType, class CoeffsType>
bool  H264CoreEncoder<PixType,CoeffsType>::FindBestInitialMV(
    H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice,
    const PixType*        pCurrent,
    const PixType*        pPrev,
    const Ipp32u        uMB,        // MB number
    bool                bBSlice,
    H264MotionVector&   BestMV16x16,    // resulting Best MV
    Ipp32s&             uBestSAD16x16e, // resulting Best RD-Opt Distortion
    Ipp32s&             uBestSAD16x16NoRD, // resulting Distortion
    H264MotionVector&   PredictedMV,    // return the 16x16 predicted vector
    const Ipp32s        xMin,
    const Ipp32s        xMax,
    const Ipp32s        yMin,
    const Ipp32s        yMax)
{
    Ipp32s sad_16x16_full, sad_16x16;
    bool is_done = true;
    H264MotionVector    mvs_pred[16];
    H264MotionVector    mv_delta;
    H264EncoderFrame<PixType> *pPrevFrm = GetRefPicList(curr_slice, LIST_0,curr_slice->m_is_cur_mb_field,uMB&1)->m_RefPicList[0];
    bool is_bwd_pred = (curr_slice->m_cur_mb.GlobalMacroblockInfo->mbtype == MBTYPE_BACKWARD);
    Ipp32s list_num = is_bwd_pred ? LIST_1 : LIST_0;
    Ipp32s  iQP  = getLumaQP51(curr_slice->m_cur_mb.LocalMacroblockInfo->QP, m_PicParamSet.bit_depth_luma);
    Ipp16s* pRDQM = glob_RDQM[iQP];
    Ipp32s mv_num = 1;

    // TODO !!! Will improve Best of 5 for sliced images, by allowing Top/Left MVs to contend across slice boundaries, which is OK, since there is no
    // dependency implied here.  Particularly important since the Predictor will not be as good in these cases.

    // zero vector
    mvs_pred[0] = null_mv;

    // predicted
    //f     Estimate_One_MV_Predictor(curr_slice, uMB, 0, is_bwd_pred, NULL, 4, 4, &PredictedMV, &mv_delta);
    Calc_One_MV_Predictor(curr_slice, uMB, 0, is_bwd_pred, 4, 4, &PredictedMV, &mv_delta);
    mvs_pred[1].mvx = (Ipp16s) (PredictedMV.mvx >> SUB_PEL_SHIFT);
    mvs_pred[1].mvy = (Ipp16s) (PredictedMV.mvy >> SUB_PEL_SHIFT);
    if (mvs_pred[1].mvx >= xMin && mvs_pred[1].mvx <= xMax && mvs_pred[1].mvy >= yMin && mvs_pred[1].mvy <= yMax) {
        if (mvs_pred[1] != mvs_pred[0])
            mv_num = 2;
    }

    // above MV
    Ipp32s above_addr = curr_slice->m_cur_mb.CurrentMacroblockNeighbours.mb_B;
    if (above_addr >= 0) {
        const H264MotionVector &above = m_pCurrentFrame->m_mbinfo.MV[list_num][above_addr].MotionVectors[12];
        mvs_pred[mv_num].mvx = above.mvx >> SUB_PEL_SHIFT;
        mvs_pred[mv_num].mvy = above.mvy >> SUB_PEL_SHIFT;
        if (mvs_pred[mv_num].mvx >= xMin && mvs_pred[mv_num].mvx <= xMax && mvs_pred[mv_num].mvy >= yMin && mvs_pred[mv_num].mvy <= yMax) {
            for (Ipp32s i = 0; i < mv_num; i++) {
                if (mvs_pred[mv_num] == mvs_pred[i]) {
                    mv_num --;
                    break;
                }
            }
            mv_num++;
        }
    }

    // left MV
    Ipp32s left_addr = curr_slice->m_cur_mb.CurrentMacroblockNeighbours.mb_A;
    if (left_addr >= 0) {
        const H264MotionVector &left = m_pCurrentFrame->m_mbinfo.MV[list_num][left_addr].MotionVectors[3];
        mvs_pred[mv_num].mvx = left.mvx >> SUB_PEL_SHIFT;
        mvs_pred[mv_num].mvy = left.mvy >> SUB_PEL_SHIFT;
        if (mvs_pred[mv_num].mvx >= xMin && mvs_pred[mv_num].mvx <= xMax && mvs_pred[mv_num].mvy >= yMin && mvs_pred[mv_num].mvy <= yMax) {
            for (Ipp32s i = 0; i < mv_num; i++) {
                if (mvs_pred[mv_num] == mvs_pred[i]) {
                    mv_num --;
                    break;
                }
            }
            mv_num++;
        }
    }

    // topleft MV
    Ipp32s topleft_addr = curr_slice->m_cur_mb.CurrentMacroblockNeighbours.mb_D;
    if (topleft_addr >= 0) {
        const H264MotionVector &topleft = m_pCurrentFrame->m_mbinfo.MV[list_num][topleft_addr].MotionVectors[15];
        mvs_pred[mv_num].mvx = topleft.mvx >> SUB_PEL_SHIFT;
        mvs_pred[mv_num].mvy = topleft.mvy >> SUB_PEL_SHIFT;
        if (mvs_pred[mv_num].mvx >= xMin && mvs_pred[mv_num].mvx <= xMax && mvs_pred[mv_num].mvy >= yMin && mvs_pred[mv_num].mvy <= yMax) {
            for (Ipp32s i = 0; i < mv_num; i++) {
                if (mvs_pred[mv_num] == mvs_pred[i]) {
                    mv_num --;
                    break;
                }
            }
            mv_num++;
        }
    }
//f
    // topright MV
    if (curr_slice->m_CurMB_Y > 0 && curr_slice->m_CurMB_X < m_WidthInMBs - 1) {
        Ipp32s topright_addr = uMB - m_WidthInMBs + 1;
        const H264MotionVector &topright = m_pCurrentFrame->m_mbinfo.MV[list_num][topright_addr].MotionVectors[12];
        mvs_pred[mv_num].mvx = topright.mvx >> SUB_PEL_SHIFT;
        mvs_pred[mv_num].mvy = topright.mvy >> SUB_PEL_SHIFT;
        if (mvs_pred[mv_num].mvx >= xMin && mvs_pred[mv_num].mvx <= xMax && mvs_pred[mv_num].mvy >= yMin && mvs_pred[mv_num].mvy <= yMax) {
            for (Ipp32s i = 0; i < mv_num; i++) {
                if (mvs_pred[mv_num] == mvs_pred[i]) {
                    mv_num --;
                    break;
                }
            }
            mv_num++;
        }
    }
    // ref bottom
    if (curr_slice->m_CurMB_Y < m_HeightInMBs - 1) {
        Ipp32s bottom_addr = uMB + m_WidthInMBs;
        const H264MotionVector &bottom = pPrevFrm->m_mbinfo.MV[LIST_0][bottom_addr].MotionVectors[0];
        if (!bBSlice) {
            mvs_pred[mv_num] = bottom;
        } else {
            // Forward vector, needs to be scaled, but direction is correct
            const Ipp32s uFwdRatio = curr_slice->DistScaleFactorMV[0];
            const Ipp32s TR_RND = (1 << (TR_SHIFT - 1));
            mvs_pred[mv_num].mvx = (Ipp16s) ((uFwdRatio * bottom.mvx + TR_RND) >> TR_SHIFT);
            mvs_pred[mv_num].mvy = (Ipp16s) ((uFwdRatio * bottom.mvy + TR_RND) >> TR_SHIFT);
            if (is_bwd_pred) {
                // Backward vector, needs both scaling and direction changed derived the backward MV from the reference MV: MVb = MVf-MV = -(1-r1)*MV
                mvs_pred[mv_num].mvx = (Ipp16s)(mvs_pred[mv_num].mvx - bottom.mvx);
                mvs_pred[mv_num].mvy = (Ipp16s)(mvs_pred[mv_num].mvy - bottom.mvy);
            }
        }
        mvs_pred[mv_num].mvx = bottom.mvx >> SUB_PEL_SHIFT;
        mvs_pred[mv_num].mvy = bottom.mvy >> SUB_PEL_SHIFT;
        if (mvs_pred[mv_num].mvx >= xMin && mvs_pred[mv_num].mvx <= xMax && mvs_pred[mv_num].mvy >= yMin && mvs_pred[mv_num].mvy <= yMax) {
            for (Ipp32s i = 0; i < mv_num; i++) {
                if (mvs_pred[mv_num] == mvs_pred[i]) {
                    mv_num --;
                    break;
                }
            }
            mv_num++;
        }
    }

    // This code properly selects and scales a MV from the reference frame(s)
    H264MotionVector fwd_mv = pPrevFrm->m_mbinfo.MV[LIST_0][uMB].MotionVectors[0];
    if (!bBSlice) {
        mvs_pred[mv_num] = fwd_mv;
    } else {
        // Forward vector, needs to be scaled, but direction is correct
        const Ipp32s uFwdRatio = curr_slice->DistScaleFactorMV[0];
        const Ipp32s TR_RND = (1 << (TR_SHIFT - 1));
        mvs_pred[mv_num].mvx = (Ipp16s) ((uFwdRatio * fwd_mv.mvx + TR_RND) >> TR_SHIFT);
        mvs_pred[mv_num].mvy = (Ipp16s) ((uFwdRatio * fwd_mv.mvy + TR_RND) >> TR_SHIFT);
        if (is_bwd_pred) {
            // Backward vector, needs both scaling and direction changed derived the backward MV from the reference MV: MVb = MVf-MV = -(1-r1)*MV
            mvs_pred[mv_num].mvx = (Ipp16s)(mvs_pred[mv_num].mvx - fwd_mv.mvx);
            mvs_pred[mv_num].mvy = (Ipp16s)(mvs_pred[mv_num].mvy - fwd_mv.mvy);
        }
    }
    // truncate motion vector
    Ipp32s frm_width = m_WidthInMBs << 4;
    Ipp32s frm_height = m_HeightInMBs << 4;
    Ipp32s posx = curr_slice->m_CurMB_X*16;
    Ipp32s posy = curr_slice->m_CurMB_Y*16;
    TRUNCATE_LO(mvs_pred[mv_num].mvx, (frm_width - posx + 1) << SUB_PEL_SHIFT);
    TRUNCATE_HI(mvs_pred[mv_num].mvx, (-16 - posx - 1) << SUB_PEL_SHIFT);
    TRUNCATE_LO(mvs_pred[mv_num].mvy, (frm_height - posy + 1) << SUB_PEL_SHIFT);
    TRUNCATE_HI(mvs_pred[mv_num].mvy, (-16 - posy - 1) << SUB_PEL_SHIFT);
    // Scale to Integer Pel
    mvs_pred[mv_num].mvx >>= SUB_PEL_SHIFT;
    mvs_pred[mv_num].mvy >>= SUB_PEL_SHIFT;
    if (mvs_pred[mv_num].mvx >= xMin && mvs_pred[mv_num].mvx <= xMax && mvs_pred[mv_num].mvy >= yMin && mvs_pred[mv_num].mvy <= yMax) {
        for (Ipp32s i = 0; i < mv_num; i++) {
            if (mvs_pred[mv_num] == mvs_pred[i]) {
                mv_num --;
                break;
            }
        }
        mv_num++;
    }

    do {
        // Begin tests to determine which of the 5 MVs is the best starting point...
        Ipp32s pitchPixels = m_pCurrentFrame->pitchPixels()<<curr_slice->m_is_cur_mb_field;
        // start with zero vector
        BestMV16x16 = null_mv;
        // do not need expand interpolation
        uBestSAD16x16NoRD = SAD16x16(pCurrent, pitchPixels*sizeof(PixType), pPrev, pitchPixels*sizeof(PixType));
        uBestSAD16x16e = uBestSAD16x16NoRD + MVConstraint(0 - PredictedMV.mvx, 0 - PredictedMV.mvy, pRDQM);
        //  If the zero vector is the predicted vector, then give it preference to encourage skip blocks in P slices.
//f        if (PredictedMV.is_zero() && !bBSlice)
//f            uBestSAD16x16e -= BITS_COST(6, glob_RDQM[iQP]);

#if defined BESTOF5_EARLY_EXIT
        // Consider the best of five mv is good enough if the effective SAD is less than the given threshold.
        if (uBestSAD16x16e <= m_BestOf5EarlyExitThres[iQP]) {
            if (uBestSAD16x16e < 0)
                uBestSAD16x16e = 0;
            break;
        }
#else
        // Skip if sad < 0

⌨️ 快捷键说明

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