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

📄 umc_h264_me.cpp

📁 这是在PCA下的基于IPP库示例代码例子,在网上下了IPP的库之后,设置相关参数就可以编译该代码.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                MVPrev.iMVx, MVPrev.iMVy, SADPrev,                MVFuture.iMVx, MVFuture.iMVy, SADFuture);#endif  // BFRAME_PRINT_MVS#if defined BFRAME_FORCE_FUTURE_REFERENCE            SADPrev = ME_MAX_SAD;#endif#if defined BFRAME_FORCE_PREVIOUS_REFERENCE            SADFuture = ME_MAX_SAD;#endif        } while (0);    *puMBSAD = SADTemp;    } else {    // P Slice        // Start Integer Search        // Initial MB_type        m_pCurrentFrame->pMBData[uMB].uMBType = MBTYPE_INTER;#ifdef P_EARLY_EXIT        {            Ipp32s iXType, iYType;            Ipp8u *const pInterpBuf = m_pCurrentFrame->pMBEncodeBuffer + 256;            Ipp8u *pRef = pRefPicList0[0]->m_pYPlane + m_pCurrentFrame->pMBOffsets[uMB].uLumaOffset + m_pCurrentFrame->y_line_shift;            // Get the MV that could lead to a skip block            Skip_MV_Predicted(uMB, &BestMVs[SB_16x16]);            // MC it...            pRef += SubpelMVAdjust(&BestMVs[SB_16x16], m_pCurrentFrame->uPitch, iXType, iYType);            // interpolate copy the 16x16 block            (*m_pCurrentFrame->InterpFunc)[iYType][iXType](pRef, pInterpBuf, m_pCurrentFrame->uPitch, 16, 16, 16);            // if it's "good enough", just use it.            Ipp32u tmpSAD = SAD16_P16(m_pCurrentFrame->m_pYPlane + m_pCurrentFrame->pMBOffsets[uMB].uLumaOffset + m_pCurrentFrame->y_line_shift,                               pInterpBuf, m_pCurrentFrame->uPitch);            if (tmpSAD < PSkipMEThres[uQP])            {                for (int row = 0; row < 4; ++row)                {                    for (int col = 0; col < 4; ++col)                    {                        pRefIdxL0[row*uWidthIn4x4Blocks + col] = 0;                        pRefIdxL1[row*uWidthIn4x4Blocks + col] = -1;                        pMVL0[row*uWidthIn4x4Blocks + col] = BestMVs[SB_16x16];                        pMVL1[row*uWidthIn4x4Blocks + col] = NullMV;                    }                }                *puMBSAD = tmpSAD;                m_pCurrentFrame->pMBData[uMB].uCBP4x4 = 0xffffff;            } else {#endif        VM_ASSERT(m_NumRefsInL0List);        for (int k = 0; k < m_NumRefsInL0List; k++)        {             CMEOneMB_worker(uMB, k, pRefPicList0[k],                        iSearchHor, iSearchVer, false, bestRefIdxs, BestMVs,                        BestSADs, PredictedMV);        }        // Start Subpel Search        CMESplitOneMB_P_Slice(uMB, puMBSAD, bestRefIdxs, BestMVs, BestSADs, PredictedMV);#ifdef P_EARLY_EXIT            }        }#endif    }} // CMEOneMB////////////////////////////////////////////////////////////////////////////////// CMEOneMB_worker//////////////////////////////////////////////////////////////////////////////////// Perform MB Motion Estimation//// The MB ME steps are://// TBD - VSI - Describe new approach here....//// Possible uMBType values are (from enum MB_Type):// MBTYPE_INTRA,        not used in this function// MBTYPE_INTER,        1 16x16 block// MBTYPE_INTER_8x8,    4 8x8 blocks (or subdivisions)// MBTYPE_INTER_8x8_REF0, 4 8x8 blocks (or subdivisions)// MBTYPE_FORWARD,      B frame, forward (16x16 implied)// MBTYPE_BACKWARD,     B frame, backward (16x16 implied)// MBTYPE_DIRECTvoid  H264VideoEncoder::CMEOneMB_worker(    Ipp32u uMB,    T_RefIdx ref_idx,    const H264EncoderFrame *pRefFrame,    Ipp32s iSearchHor,    Ipp32s iSearchVer,    bool bBSlice,    T_RefIdx bestRefIdxs[41],    T_ECORE_MV BestMVs[41],    Ipp32u  BestSADs[41],    T_ECORE_MV PredictedMV[41]){    T_EncodeMBOffsets *pMBOffset = &m_pCurrentFrame->pMBOffsets[uMB];    const Ipp8u *pCurrent   = m_pCurrentFrame->m_pYPlane + pMBOffset->uLumaOffset + m_pCurrentFrame->y_line_shift;    const Ipp8u *pPrev      = pRefFrame->m_pYPlane + pMBOffset->uLumaOffset + m_pCurrentFrame->y_line_shift;    const Ipp8u *pCur, *pRef; // Working pointers    Ipp32s uPitch           = m_pCurrentFrame->uPitch;    Ipp32s uQP              = m_pCurrentFrame->pMBData[uMB].uMBQP;    Ipp16s *pRDQM           = RDQM[uQP];    T_ECORE_MV BestMV16x16;    Ipp32s uBestSAD16x16e, uBestSAD16x16NoRD;    T_ECORE_MV tempPredictedMV[41];    bool bDone = false;    Ipp32s xFactor, yFactor;    Ipp32s xvec, yvec;    Ipp32s block;    Ipp32s StartX, StartY;    Ipp32s maxleft, maxright, maxup, maxdown;    Ipp32s left, right, up, down;    const Ipp32s ME_MAX_SAD = INT_MAX >> 5; // Scaled down to allow sums of MAX without overflow.    // FindBestOfInitial16x16    Ipp16u ThisSAD[41];    T_ECORE_BIGMV tmpMVDelta;    Ipp32u tempSAD = 0;    Ipp32u uRefFrame;    unsigned int ref_constraint = RefConstraint(ref_idx, m_NumRefsInL0List, pRDQM);    // max<dir> is the maximum number of pels that can be searched    // in direction <dir>. These are signed value, ie, maxleft and    // maxup will be negative or 0.    maxleft     = -(Ipp32s)((pMBOffset->uMVLimits & 0xff)   >> 0);  // pels    maxright    =  (Ipp32s)((pMBOffset->uMVLimits & 0xff00) >> 8);  // pels    maxup       = -(Ipp32s)((pMBOffset->uMVLimits & 0xff0000)>> 16);// pels    maxdown     =  (Ipp32s)(pMBOffset->uMVLimits >> 24);    // pels    // Do the "Best of 4" analysis to find the best 16x16 integer search    // starting point (and it's RD-Optimized distortion).  Also returns    // the predicted vectors for the 16x16 block.    bDone = FindBestInitialMV(                pCurrent, pPrev,                uMB,                bBSlice,                BestMV16x16, // passed as ref and get initialized                uBestSAD16x16e, // passed as ref and get initialized                uBestSAD16x16NoRD, // resulting Distortion                tempPredictedMV[SB_16x16],  // passed as ref and get initialized                maxleft, maxright, maxup, maxdown);    if (!bDone)    {        // Starting with the "best of 5" results...        StartX = (Ipp32s)BestMV16x16.iMVx;        StartY = (Ipp32s)BestMV16x16.iMVy;        left    = MAX(maxleft,  StartX - iSearchHor);        left    = MAX(left, -MAXINTVEC-1);  // clip to Ipp8s range        right   = MIN(maxright, StartX + iSearchHor);        right   = MIN(right, MAXINTVEC);        up      = MAX(maxup,    StartY - iSearchVer);        up      = MAX(up, -MAXINTVEC-1);        down    = MIN(maxdown,  StartY + iSearchVer);        down    = MIN(down, MAXINTVEC);        uRefFrame = (m_pCurrentFrame->pMBData[uMB].uMBType == MBTYPE_BACKWARD) ? 1 : 0;        // Calc the predicted MV for the 8x8 blocks 0        Estimate_One_MV_Predictor(uMB, 0, uRefFrame, NULL, 2, 1, &tempPredictedMV[SB_8x8_TL], &tmpMVDelta);        // Calc the predicted MV for the 8x16 block 0        Estimate_One_MV_Predictor(uMB, 0, uRefFrame, NULL, 2, 4, &tempPredictedMV[SB_8x16_L], &tmpMVDelta);        // Calc the predicted MV for the 16x8 block 0        Estimate_One_MV_Predictor(uMB, 0, uRefFrame, NULL, 4, 2, &tempPredictedMV[SB_16x8_T], &tmpMVDelta);        // Calc the predicted MV for the 8x16 block 1        Estimate_One_MV_Predictor(uMB, 2, uRefFrame, NULL, 2, 4, &tempPredictedMV[SB_8x16_R], &tmpMVDelta);        // Calc the predicted MV for the 16x8 block 1        Estimate_One_MV_Predictor(uMB, 8, uRefFrame, NULL, 4, 2, &tempPredictedMV[SB_16x8_B], &tmpMVDelta);        if (m_info.me_split_8x8s)    // Split 8x8s        {            T_ECORE_MV temp_BestMVs[41];            Ipp32u  temp_BestSADs[41];            T_RefIdx temp_bestRefIdxs[41];            T_ECORE_MV NullMV = {0, 0};            int block;            for (block = 0; block < 41; block++)            {                temp_BestSADs[block] = ME_MAX_SAD;                temp_BestMVs[block] = NullMV;                temp_bestRefIdxs[block] = -1;            }            // Calc the predicted MV for the 4x4 & 4x8 & 8x4 blocks 0            Estimate_One_MV_Predictor(uMB, 0, uRefFrame, NULL, 1, 1, &tempPredictedMV[SB_4x4_TL], &tmpMVDelta);            tempPredictedMV[SB_4x8_TL] = tempPredictedMV[SB_4x4_TL];            tempPredictedMV[SB_8x4_TL] = tempPredictedMV[SB_8x8_TL];    // 8x4 same as 8x8            yFactor = SubPelFactor*up;            for (yvec = up; yvec <= down; ++yvec, yFactor += SubPelFactor)            {                xFactor = SubPelFactor*left;                for (xvec = left; xvec <= right; ++xvec, xFactor += SubPelFactor)                {                    pCur = pCurrent;                    pRef = MVADJUST(pPrev, uPitch, xvec, yvec);                    SAD16SB16 (pCur, pRef, ThisSAD, uPitch);                    ThisSAD[SB_4x4_TL] += ref_constraint/4 +                        (Ipp16u)MVConstraint(xFactor - tempPredictedMV[SB_4x4_TL].iMVx, yFactor - tempPredictedMV[SB_4x4_TL].iMVy, pRDQM);                    ThisSAD[SB_4x8_TL] += ref_constraint/2 +                        (Ipp16u)MVConstraint(xFactor - tempPredictedMV[SB_4x8_TL].iMVx, yFactor - tempPredictedMV[SB_4x8_TL].iMVy, pRDQM);                    ThisSAD[SB_8x4_TL] += ref_constraint/2 +                        (Ipp16u)MVConstraint(xFactor - tempPredictedMV[SB_8x4_TL].iMVx, yFactor - tempPredictedMV[SB_8x4_TL].iMVy, pRDQM);                    ThisSAD[SB_8x8_TL] += ref_constraint +                        (Ipp16u)MVConstraint(xFactor - tempPredictedMV[SB_8x8_TL].iMVx, yFactor - tempPredictedMV[SB_8x8_TL].iMVy, pRDQM);                    ThisSAD[SB_8x16_L] += ref_constraint +                        (Ipp16u)MVConstraint(xFactor - tempPredictedMV[SB_8x16_L].iMVx, yFactor - tempPredictedMV[SB_8x16_L].iMVy, pRDQM);                    ThisSAD[SB_16x8_T] += ref_constraint +                        (Ipp16u)MVConstraint(xFactor - tempPredictedMV[SB_16x8_T].iMVx, yFactor - tempPredictedMV[SB_16x8_T].iMVy, pRDQM);                    ThisSAD[SB_16x16] += ref_constraint +                        (Ipp16u)MVConstraint(xFactor - tempPredictedMV[SB_16x16].iMVx, yFactor - tempPredictedMV[SB_16x16].iMVy, pRDQM);                    ThisSAD[SB_8x16_R] += ref_constraint +                        (Ipp16u)MVConstraint(xFactor - tempPredictedMV[SB_8x16_R].iMVx, yFactor - tempPredictedMV[SB_8x16_R].iMVy, pRDQM);                    ThisSAD[SB_16x8_B] += ref_constraint +                        (Ipp16u)MVConstraint(xFactor - tempPredictedMV[SB_16x8_B].iMVx, yFactor - tempPredictedMV[SB_16x8_B].iMVy, pRDQM);                    // if 8x8 is better then                    SADComp41(ThisSAD, temp_BestSADs, temp_BestMVs, ref_idx, temp_bestRefIdxs,                        tempPredictedMV, tempPredictedMV, xvec, yvec,  0, 32);                    SADComp41(ThisSAD, BestSADs, BestMVs, ref_idx, bestRefIdxs,                        tempPredictedMV, PredictedMV, xvec, yvec,  32, 41);                }   // for xvec            }   // for yvec            for (block = 0; block < 4; block++)            {                if (ThisSAD[SB_8x8_TL + block] < BestSADs[SB_8x8_TL + block])                {                    Move_ME_Info(temp_BestSADs, BestSADs, BestMVs, temp_BestMVs, ref_idx, bestRefIdxs,                        tempPredictedMV, PredictedMV, SB_4x4_TL+block*4, SB_4x4_TL+block*4 + 4);                    Move_ME_Info(temp_BestSADs, BestSADs, BestMVs, temp_BestMVs, ref_idx, bestRefIdxs,                        tempPredictedMV, PredictedMV, SB_8x4_TL+block*2, SB_8x4_TL+block*2 + 2);                    Move_ME_Info(temp_BestSADs, BestSADs, BestMVs, temp_BestMVs, ref_idx, bestRefIdxs,                        tempPredictedMV, PredictedMV, SB_4x8_TL+block*2, SB_4x8_TL+block*2 + 2);                }            }        } else {            // Don't split 8x8s            yFactor = SubPelFactor*up;            for (yvec = up; yvec <= down; ++yvec, yFactor += SubPelFactor) {                xFactor = SubPelFactor*left;                for (xvec = left; xvec <= right; ++xvec, xFactor += SubPelFactor) {                    // Add in the approx RD cost of the MV diff for block zero                    tempSAD = MVConstraint(xFactor - PredictedMV[SB_8x8_TL].iMVx, yFactor - PredictedMV[SB_8x8_TL].iMVy, pRDQM)                            + ref_constraint;                    pCur = pCurrent;                    pRef = MVADJUST(pPrev, uPitch, xvec, yvec);                    SAD16SB4 (pCur, pRef, ThisSAD, uPitch);                    for (block = 32; block < 36; ++block) { // 4 - 8x8 blocks                        tempSAD += (Ipp32u)ThisSAD[block-32];                        // Accumulate SAD and MVs for 8x8 blocks                        if (tempSAD < BestSADs[block]) {                            BestSADs[block] = tempSAD;                            BestMVs[block].iMVx = (Ipp8s)xvec*SubPelFactor;                            BestMVs[block].iMVy = (Ipp8s)yvec*SubPelFactor;                            bestRefIdxs[block] = ref_idx;                            PredictedMV[block] = tempPredictedMV[block];                        }                        tempSAD = 0;                    }   // block// Unroll the loop; removes table lookups                    tempSAD = MVConstraint(xFactor - PredictedMV[SB_8x16_L].iMVx, yFactor - PredictedMV[SB_8x16_L].iMVy, pRDQM)                        + ref_constraint;                    tempSAD += ((Ipp32u)ThisSAD[0]+(Ipp32u)ThisSAD[2]);                    if (tempSAD < BestSADs[SB_8x16_L]) {                        BestSADs[SB_8x16_L] = tempSAD;                        BestMVs[SB_8x16_L].iMVx = (Ipp8s)xvec*SubPelFactor;                        BestMVs[SB_8x16_L].iMVy = (Ipp8s)yvec*SubPelFactor;                        bestRefIdxs[SB_8x16_L] = ref_idx;                        PredictedMV[SB_8x16_L] = tempPredictedMV[SB_8x16_L];                    }                    tempSAD = MVConstraint(xFactor - PredictedMV[SB_8x16_R].iMVx, yFactor - PredictedMV[SB_8x16_R].iMVy, pRDQM)                        + ref_constraint;                    tempSAD += ((Ipp32u)ThisSAD[1]+(Ipp32u)ThisSAD[3]);                    if (tempSAD < BestSADs[SB_8x16_R]) {                        BestSADs[SB_8x16_R] = tempSAD;                        BestMVs[SB_8x16_R].iMVx = (Ipp8s)xvec*SubPelFactor;                        BestMVs[SB_8x16_R].iMVy = (Ipp8s)yvec*SubPelFactor;

⌨️ 快捷键说明

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