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

📄 umc_h264_me_new.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
{
    Ipp32s uMB = curr_slice->m_CurMBAddr;
    bool bBSlice = BPREDSLICE == curr_slice->m_slice_type;
    bool is_bwd_pred = (list_id == LIST_1);
    Ipp32s i;
    H264EncoderFrame<PixType> *pPrevFrm = GetRefPicList(curr_slice, list_id, curr_slice->m_is_cur_mb_field, uMB & 1)->m_RefPicList[0];

    // set of candidates
    Ipp32s mv_num = 1;
    // predicted, calculated already
    meInfo->candMV[0].mvx = (Ipp16s)(meInfo->predictedMV.mvx >> SUB_PEL_SHIFT);
    meInfo->candMV[0].mvy = (Ipp16s)(meInfo->predictedMV.mvy >> SUB_PEL_SHIFT);
    // zero vector
    meInfo->candMV[1] = null_mv;
    if (meInfo->candMV[1] != meInfo->candMV[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_id][above_addr].MotionVectors[12];
        meInfo->candMV[mv_num].mvx = above.mvx >> SUB_PEL_SHIFT;
        meInfo->candMV[mv_num].mvy = above.mvy >> SUB_PEL_SHIFT;
        for (i = 0; i < mv_num; i++) {
            if (meInfo->candMV[mv_num] == meInfo->candMV[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_id][left_addr].MotionVectors[3];
        meInfo->candMV[mv_num].mvx = left.mvx >> SUB_PEL_SHIFT;
        meInfo->candMV[mv_num].mvy = left.mvy >> SUB_PEL_SHIFT;
        for (i = 0; i < mv_num; i++) {
            if (meInfo->candMV[mv_num] == meInfo->candMV[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_id][topleft_addr].MotionVectors[15];
        meInfo->candMV[mv_num].mvx = topleft.mvx >> SUB_PEL_SHIFT;
        meInfo->candMV[mv_num].mvy = topleft.mvy >> SUB_PEL_SHIFT;
        for (i = 0; i < mv_num; i++) {
            if (meInfo->candMV[mv_num] == meInfo->candMV[i]) {
                mv_num --;
                break;
            }
        }
        mv_num++;
    }
    // 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_id][topright_addr].MotionVectors[12];
        meInfo->candMV[mv_num].mvx = topright.mvx >> SUB_PEL_SHIFT;
        meInfo->candMV[mv_num].mvy = topright.mvy >> SUB_PEL_SHIFT;
        for (i = 0; i < mv_num; i++) {
            if (meInfo->candMV[mv_num] == meInfo->candMV[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_id][bottom_addr].MotionVectors[0];
        if (!bBSlice) {
            meInfo->candMV[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));
            meInfo->candMV[mv_num].mvx = (Ipp16s) ((uFwdRatio * bottom.mvx + TR_RND) >> TR_SHIFT);
            meInfo->candMV[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
                meInfo->candMV[mv_num].mvx = (Ipp16s)(meInfo->candMV[mv_num].mvx - bottom.mvx);
                meInfo->candMV[mv_num].mvy = (Ipp16s)(meInfo->candMV[mv_num].mvy - bottom.mvy);
            }
        }
        meInfo->candMV[mv_num].mvx = bottom.mvx >> SUB_PEL_SHIFT;
        meInfo->candMV[mv_num].mvy = bottom.mvy >> SUB_PEL_SHIFT;
        for (i = 0; i < mv_num; i++) {
            if (meInfo->candMV[mv_num] == meInfo->candMV[i]) {
                mv_num --;
                break;
            }
        }
        mv_num++;
    }
    // ref right
    if (curr_slice->m_CurMB_X < m_WidthInMBs - 1) {
        Ipp32s right_addr = uMB + 1;
        const H264MotionVector &right = pPrevFrm->m_mbinfo.MV[list_id][right_addr].MotionVectors[0];
        if (!bBSlice) {
            meInfo->candMV[mv_num] = right;
        } 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));
            meInfo->candMV[mv_num].mvx = (Ipp16s) ((uFwdRatio * right.mvx + TR_RND) >> TR_SHIFT);
            meInfo->candMV[mv_num].mvy = (Ipp16s) ((uFwdRatio * right.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
                meInfo->candMV[mv_num].mvx = (Ipp16s)(meInfo->candMV[mv_num].mvx - right.mvx);
                meInfo->candMV[mv_num].mvy = (Ipp16s)(meInfo->candMV[mv_num].mvy - right.mvy);
            }
        }
        meInfo->candMV[mv_num].mvx = right.mvx >> SUB_PEL_SHIFT;
        meInfo->candMV[mv_num].mvy = right.mvy >> SUB_PEL_SHIFT;
        for (i = 0; i < mv_num; i++) {
            if (meInfo->candMV[mv_num] == meInfo->candMV[i]) {
                mv_num --;
                break;
            }
        }
        mv_num++;
    }
    // ref current
    H264MotionVector fwd_mv = pPrevFrm->m_mbinfo.MV[list_id][uMB].MotionVectors[0];
    if (!bBSlice) {
        meInfo->candMV[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));
        meInfo->candMV[mv_num].mvx = (Ipp16s) ((uFwdRatio * fwd_mv.mvx + TR_RND) >> TR_SHIFT);
        meInfo->candMV[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
            meInfo->candMV[mv_num].mvx = (Ipp16s)(meInfo->candMV[mv_num].mvx - fwd_mv.mvx);
            meInfo->candMV[mv_num].mvy = (Ipp16s)(meInfo->candMV[mv_num].mvy - fwd_mv.mvy);
        }
    }
    meInfo->candMV[mv_num].mvx >>= SUB_PEL_SHIFT;
    meInfo->candMV[mv_num].mvy >>= SUB_PEL_SHIFT;
    for (i = 0; i < mv_num; i++) {
        if (meInfo->candMV[mv_num] == meInfo->candMV[i]) {
            mv_num --;
            break;
        }
    }
    mv_num++;
    meInfo->candNum = mv_num;
}

template <class PixType, class CoeffsType> bool H264CoreEncoder<PixType,CoeffsType>::CheckSkip(H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice, H264MotionVector &cmpMV)
{
    H264MotionVector skip_vec;
    Skip_MV_Predicted(curr_slice, curr_slice->m_CurMBAddr, &skip_vec);
    if ((abs(cmpMV.mvx - skip_vec.mvx) > 1) || (abs(cmpMV.mvy - skip_vec.mvy) > 1))
        return false;

    H264CurrentMacroblockDescriptor<PixType, CoeffsType> &cur_mb = curr_slice->m_cur_mb;
    H264EncoderFrame<PixType> **pRefPicList0 = GetRefPicList(curr_slice, LIST_0, curr_slice->m_is_cur_mb_field, curr_slice->m_CurMBAddr&1)->m_RefPicList;
    Ipp8s *pFields0 = GetRefPicList(curr_slice, LIST_0, curr_slice->m_is_cur_mb_field, curr_slice->m_CurMBAddr&1)->m_Prediction;
    PixType *const pInterpBuf = curr_slice->m_pMBEncodeBuffer;
    Ipp16s* pDiffBuf    = (Ipp16s*) (curr_slice->m_pMBEncodeBuffer + 512);
    CoeffsType *pTransformResult = (CoeffsType*)(pDiffBuf + 16);
    T_EncodeMBOffsets *pMBOffset = &m_pMBOffsets[curr_slice->m_CurMBAddr];
    Ipp32s pitchPixels = m_pCurrentFrame->pitchPixels()<<curr_slice->m_is_cur_mb_field;
    PixType* pSrcPlane = m_pCurrentFrame->m_pYPlane;
    Ipp32u offset = m_pMBOffsets[curr_slice->m_CurMBAddr].uLumaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field];
    Ipp32s   iNumCoeffs, iLastCoeff, iXType, iYType;

    PixType *pRef = pRefPicList0[0]->m_pYPlane + offset + curr_slice->m_InitialOffset[pFields0[0]];
    pRef += SubpelMVAdjust(&skip_vec, pitchPixels, iXType, iYType);
#ifdef NEW_INTERPOLATE
    Interpolate(pRef, pitchPixels, pInterpBuf, 16, iXType, iYType, size16x16, skip_vec.mvy, m_CurMB_Y*16);
#else
    ippiInterpolateLuma_H264(pRef, pitchPixels*sizeof(PixType), pInterpBuf, 16*sizeof(PixType), iXType, iYType, size16x16, m_PicParamSet.bit_depth_luma);
#endif
    Ipp32s coeffs_cost = 0;
    Ipp32u uMBQP  = getLumaQP(cur_mb.LocalMacroblockInfo->QP, m_PicParamSet.bit_depth_luma);
    Ipp32s  chromaQP = getChromaQP(cur_mb.LocalMacroblockInfo->QP, m_PicParamSet.chroma_qp_index_offset, m_SeqParamSet.bit_depth_chroma);
    // code block
    for (Ipp32s uBlock = 0; uBlock < 16; uBlock ++) {
        PixType* pPredBuf = pInterpBuf + xoff[uBlock] + yoff[uBlock]*16;
        Diff4x4(pPredBuf, pSrcPlane + offset, pitchPixels*sizeof(PixType), pDiffBuf);
        ippiTransformQuantResidual_H264(pDiffBuf, pTransformResult,(Ipp32s)uMBQP,&iNumCoeffs,0, enc_single_scan[curr_slice->m_is_cur_mb_field], &iLastCoeff);
        coeffs_cost += CalculateCoeffsCost(pTransformResult, 16, dec_single_scan[curr_slice->m_is_cur_mb_field]);
        if (coeffs_cost >= 6) return false;
        offset += m_EncBlockOffsetInc[curr_slice->m_is_cur_mb_field][uBlock];
    }
    if (m_PicParamSet.chroma_format_idc != 0) {
        offset = pMBOffset->uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field];
        H264MotionVector chroma_skip_vec = skip_vec;
        if( m_PicParamSet.chroma_format_idc == 1 ){
            if (!curr_slice->m_is_cur_mb_bottom_field && pFields0[0])  chroma_skip_vec.mvy += - 2;
            else if (curr_slice->m_is_cur_mb_bottom_field && !pFields0[0]) chroma_skip_vec.mvy += 2;
        }
        IppiSize chroma_size;
        if( m_PicParamSet.chroma_format_idc == 1){ //420
            chroma_size =  size8x8;
        }else if( m_PicParamSet.chroma_format_idc == 2){ //422
            chroma_size =  size8x16;
        }
        CoeffsType* pQBuf    = (CoeffsType*) (pTransformResult + 16);
        CoeffsType* pDCBuf   = (CoeffsType*) (pQBuf + 16);   // Used for both luma and chroma DC blocks
        Ipp16s* pMassDiffBuf = (Ipp16s*) (pDCBuf + 16);
        Ipp32s start_block = 16, last_block = 20;
        if(m_PicParamSet.chroma_format_idc == 2) start_block = 16, last_block = 24;
        pSrcPlane = m_pCurrentFrame->m_pUPlane;
        pRef = pRefPicList0[0]->m_pUPlane + offset + curr_slice->m_InitialOffset[pFields0[0]];
        Ipp32s mv_offset = SubpelChromaMVAdjust(&chroma_skip_vec, pitchPixels, iXType, iYType, m_PicParamSet.chroma_format_idc);
        for (Ipp32s i = 0; i < 2 ; i++) {
            pRef += mv_offset;
#ifdef NEW_INTERPOLATE
            Interpolate_Cr(pRef, pitchPixels, pInterpBuf, 16, iXType, iYType, size16x16, chroma_skip_vec.mvy, m_CurMB_Y*16);
#else
            ippiInterpolateChroma_H264(pRef, pitchPixels*sizeof(PixType), pInterpBuf, 16*sizeof(PixType), iXType, iYType, chroma_size, m_SeqParamSet.bit_depth_chroma);
#endif
            ippiSumsDiff8x8Blocks4x4(pSrcPlane + offset, pitchPixels, pInterpBuf, 16, pDCBuf, pMassDiffBuf);
            if( m_PicParamSet.chroma_format_idc == 2 ){
                // Process second part of 2x4 block for DC coeffs
                 ippiSumsDiff8x8Blocks4x4(pSrcPlane + offset+8*pitchPixels,    // source pels
                                          pitchPixels,                 // source pitch
                                          pInterpBuf+8*16,               // predictor pels
                                          16,
                                          pDCBuf+4,                 // result buffer
                                          pMassDiffBuf+64);   //+Offset for second path
            }
            // 2x2 forward transform
            switch( m_PicParamSet.chroma_format_idc ){
                case 1:
                    ippiTransformQuantChromaDC_H264(pDCBuf, pQBuf, chromaQP,&iNumCoeffs,(curr_slice->m_slice_type == INTRASLICE),1);
                    break;
                case 2:
                    ippiTransformQuantChroma422DC_H264(pDCBuf, pQBuf,chromaQP,&iNumCoeffs,(curr_slice->m_slice_type == INTRASLICE),1);
                    break;
            }
            if (pDCBuf[0] || pDCBuf[1] || pDCBuf[2] || pDCBuf[3]) return false;
            if( m_PicParamSet.chroma_format_idc == 2 && (pDCBuf[4] || pDCBuf[5] || pDCBuf[6] || pDCBuf[7]) ) return false;
            coeffs_cost = 0;
            for (Ipp32s uBlock = start_block; uBlock < last_block; uBlock ++) {
                Ipp16s* pTempDiffBuf = pMassDiffBuf+(uBlock - start_block)*16;
                ippiTransformQuantResidual_H264(pTempDiffBuf, pTransformResult, chromaQP, &iNumCoeffs, 0, enc_single_scan[curr_slice->m_is_cur_mb_field], &iLastCoeff);
                coeffs_cost += CalculateCoeffsCost(pTransformResult, 15, &dec_single_scan[curr_slice->m_is_cur_mb_field][1]);
                if (coeffs_cost >= 7) return false;
                offset += m_EncBlockOffsetInc[curr_slice->m_is_cur_mb_field][uBlock];
            }
            if( m_PicParamSet.chroma_format_idc == 1 ){
                start_block = 20;
                last_block = 24;
            }else if( m_PicParamSet.chroma_format_idc == 2 ){
                start_block = 24;
                last_block = 32;
            }
            pSrcPlane = m_pCurrentFrame->m_pVPlane;
            offset = pMBOffset->uChromaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field];
            pRef = pRefPicList0[0]->m_pVPlane + offset + curr_slice->m_InitialOffset[pFields0[0]];
        }
    }
    for (Ipp32s i = 0; i < 16; i ++) {
        cur_mb.MVs[LIST_0]->MotionVectors[i] = skip_vec;
        cur_mb.MVs[LIST_1]->MotionVectors[i] = null_mv;
        cur_mb.RefIdxs[LIST_0]->RefIdxs[i] = (T_RefIdx)0;
        cur_mb.RefIdxs[LIST_1]->RefIdxs[i] = (T_RefIdx)-1;
    }
    curr_slice->m_cur_mb.LocalMacroblockInfo->cbp_luma = 0x000000;
    curr_slice->m_cur_mb.LocalMacroblockInfo->cbp_chroma = 0;//0xffffffff;
    curr_slice->m_cur_mb.LocalMacroblockInfo->cbp = 0;
    curr_slice->m_cur_mb.GlobalMacroblockInfo->mbtype = MBTYPE_SKIPPED;
    // cur_mb.GlobalMacroblockInfo->sbtype[0] = MBTYPE_SKIPPED;
    return true;
}


template <class PixType, class CoeffsType> bool H264CoreEncoder<PixType,CoeffsType>::CheckSkipB(H264EncoderThreadPrivateSlice<PixType,CoeffsType>* curr_slice)
{
    PixType* pInterpBuf = curr_slice->m_pPred4DirectB;
    Ipp16s* pDiffBuf    = (Ipp16s*) (curr_slice->m_pMBEncodeBuffer + 5

⌨️ 快捷键说明

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