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

📄 umc_h264_me.cpp

📁 这是在PCA下的基于IPP库示例代码例子,在网上下了IPP的库之后,设置相关参数就可以编译该代码.
💻 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 - 2005 Intel Corporation. All Rights Reserved.//#include <string.h>#include <limits.h>#include "umc_h264_tables.h"    // for const Ipp8u rd_quant[];#include "umc_h264_bme.h"#include "umc_h264_video_encoder.h"//#define TRACE_MV_PRED//#define PREV_PRED // Uncommenting this substitutes a MV from a previously                    // encoded reference frame for the LeftMV in RD Calculations                    // that use predicted MV values//#define UL_PRED       // Uncommenting this substitutes a MV from the (when avail) UL MB                    // for the LeftMV in RD Calculations that use predicted MV values//#define NULL_PRED   // Uncommenting this substitutes a Null MV (0,0)                    // for the LeftMV in RD Calculations that use predicted MV values#if (defined(PREV_PRED) || defined(UL_PRED) || defined(NULL_PRED))#define NO_LEFT_DEP#endif // PREV_PRED || UL_PRED || NULL_PRED//#define NO_EMPTY_THRESH#define B_EARLY_EXIT//#define P_EARLY_EXIT#define BESTOF5_EARLY_EXIT      // skip rest of search if current best is good enough//#define FORCE_INTER//#define NO_SUBPEL_SEARCH//#define PRINT_MVS//#define BFRAME_FORCE_FUTURE_REFERENCE     // for B frames//#define BFRAME_FORCE_PREVIOUS_REFERENCE   // for B frames//#define BFRAME_NO_DIRECT_MODE             // for B frames//#define BFRAME_NO_BIPRED_MODE             // for B frames//#define BFRAME_NO_BIPRED_MODE_SUBDIV//#define BFRAME_PRINT_MVS//#define FULL_SUBPEL_SEARCH    // Otherwise, conjugate...// Macro definitions used to make things a little easier to read...#define SAD16   SAD16x16Block#define SAD8    SAD8x8Block#define SAD4    SAD4x4Block#define SAD16SB4    SAD16x16Block_Sb4#define SAD16SB16   SAD16x16Block_Sb16// SAD functions using fixed pitch for second source#define SAD16_P16   SAD16x16Block_P16#define SAD8_P16    SAD8x8Block_P16#define SAD4_P16    SAD4x4Block_P16// Subpel interpolation function//#define SP_INTERP(x,y)        ((*m_pCurrentFrame->InterpFunc)[(y)][(x)])#define RANGECHECK(x, low, high) (((x) >= (low)) && ((x) <= (high)))#define MAXINTVEC   (31)    // ((max Ipp8s) - (subpel search range)) / subpel factor                            // (127 - 3) / 4// Macro to verify that vectors will not exceed the size of an Ipp8s after// conversion from integer to subpel. Theoretically this is possible even though// the signature search only searches +/- 32 around 0 (thus a max vector of// +/- 96 plus the subpel search of =/- 2), because the initial integer search// positions include predictor vectors, which could already be at a +/- 32 point.// Then the integer search goes a little further, the new larger vector is a// future predictor, so the future search go could even a little further, ...// The code currently converts the vectors to Ipp8s from Ipp32s without clipping on// the assumption that the above scenario in practice will not occur. The// macros are used in HiveAsserts to verify this assumption. Clipping may need// to be added if the assumption proves false.// 01/28/00 update: The asserts have been hit a few times, indicating vectors// are sometimes exceeding Ipp8s size, so clipping has been added when calculating// the search ranges (left, right, up, down).#define VINTRANGE(v)    RANGECHECK((v), -MAXINTVEC-1, MAXINTVEC)// LUT for MV bit usage.// FIXME: This table is way bigger than need be. It should be no larger than 256 entries.// FIXE RJR: 256 is too small because the index into the table is the sum of two// vectors (predictor, current position). The range of predictor is theoretically// -128 to +127 and current position range is currently -32*3 to +32*3. I'm// temporarily restoring the table to it's original larger size, which is too// big, but actually should do no harm.//#define BITSFORMV_OFFSET 128 // (1+2+4+8+16+11*32)#define BITSFORMV_OFFSET (1+2+4+8+16+11*32)#define MVBITS(v) (BitsForMV[(v)+BITSFORMV_OFFSET])using namespace UMC_H264_ENCODER;namespace UMC{const Ipp8s BitsForMV [BITSFORMV_OFFSET + 1 + BITSFORMV_OFFSET] = {    19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,    19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,    19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,    19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,    // -256    17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,    17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,    17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,    17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,    // -128    15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,    15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,    // -64    13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,    // -32    11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,    // -16     9, 9, 9, 9, 9, 9, 9, 9,    // -8     7, 7, 7, 7,    // -4     5, 5,  // -2     3, // -1     1, // 0     3, // 1     5, 5,  // 2     7, 7, 7, 7,    // 4     9, 9, 9, 9, 9, 9, 9, 9,    // 8    11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,    // 16    13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,    // 32    15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,    // 64    15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,    17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,    // 128    17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,    17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,    17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,    19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,    // 256    19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,    19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,    19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19};Ipp16s RDQM[52][39];bool bRDQMInitialized = false;enum BlockBestMode_8x8{    MODE_8x8,    MODE_8x4,    MODE_4x8,    MODE_4x4,#ifndef BFRAME_NO_DIRECT_MODE    MODE_DIRECT_8x8,#endif};////////////////////////////////////////////////////////////////////////////////// MVConstraint////////////////////////////////////////////////////////////////////////////////#if defined _DEBUGIpp32u MVConstraint(Ipp32s x, Ipp32s y, Ipp16s *pRDQM){    return (pRDQM[MVBITS(x) + MVBITS(y)]*1);}#else#define MVConstraint(x, y, pRDQM)   (pRDQM[MVBITS(x) + MVBITS(y)])#endif  // _DEBUGinline int RefConstraint(int ref_idx, int active_refs, Ipp16s *pRDQM){    if (active_refs == 1)        return 0;    if (active_refs > 2)    {        return pRDQM[MVBITS(ref_idx)];    }else{        return 0;//pRDQM[ref_idx ?  2 : 1];    }}#define MVADJUST(ptr, pitch, x, y)  ((ptr) + Ipp32s((pitch)*(y) + (x)))////////////////////////////////////////////////////////////////////////////////// FindBestInitialMV// Return the best Initial 16x16 MV from the four possible candidates:// 1) Zero MV// 2) Predicted MV// 3) Above MV// 4) Left MV////////////////////////////////////////////////////////////////////////////////bool  H264VideoEncoder::FindBestInitialMV(    const Ipp8u*        pCurrent,    const Ipp8u*        pPrev,    const Ipp32u        uMB,        // MB number    bool                bBSlice,    T_ECORE_MV&         BestMV16x16,    // resulting Best MV    Ipp32s&             uBestSAD16x16e, // resulting Best RD-Opt Distortion    Ipp32s&             uBestSAD16x16NoRD, // resulting Distortion    T_ECORE_MV&         PredictedMV,    // return the 16x16 predicted vector    const Ipp32s        xMin,    const Ipp32s        xMax,    const Ipp32s        yMin,    const Ipp32s        yMax){    Ipp32u i;    Ipp32s uSAD16x16e, uSAD16x16NoRD;    Ipp32s uPitch = m_pCurrentFrame->uPitch;    bool bDone = true;    T_ECORE_MV NullMV = {0, 0};    T_ECORE_MV MVPred[7];    T_ECORE_BIGMV mvDelta[1];    T_ECORE_MV *pMVRef;    bool bBackwardFlag = (m_pCurrentFrame->pMBData[uMB].uMBType == MBTYPE_BACKWARD);    const Ipp32s uFwdRatio = m_SliceHeader.DistScaleFactorMV[0];//todo switch to ref_idx    const Ipp32s TR_RND = (1 << (TR_SHIFT - 1));    Ipp32u uQP  = m_pCurrentFrame->pMBData[uMB].uMBQP;    Ipp16s* pRDQM = RDQM[uQP];    // zero vector    MVPred[0] = NullMV;    Ipp32u uMVnum = 1;    // For now, assume Inter 16x16 MB Type    // Note, if MB_Type is changed to anything else,    // review that the values for xPred and yPred below are    // appropriate...    Estimate_One_MV_Predictor(uMB, 0, bBackwardFlag, NULL, 4, 4, &PredictedMV, mvDelta);    // VSI - TODO -- Change the 3 lines below to reflect actual _frame_ edges.    // 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.    Ipp32u uMBEdgeType = m_pCurrentFrame->pMBData[uMB].uEdgeType;    Ipp8u bMBIsNotOnTopEdge = uMBEdgeType & MBEdgeTypeIsNotTopEdge;    Ipp8u bMBIsNotOnLeftEdge = uMBEdgeType & MBEdgeTypeIsNotLeftEdge;    // vector for block 0 of the MB    T_ECORE_MV *pMV, *pMVAbove;#ifndef NO_LEFT_DEP    T_ECORE_MV *pMVLeft;#endif    if (bBackwardFlag) {        pMV = &m_pCurrentFrame->pMVL1[m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex];    } else {        pMV = &m_pCurrentFrame->pMVL0[m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex];    }    // predictors    // note: at this point, uMVnum >= 1    MVPred[uMVnum].iMVx = (Ipp8s) (PredictedMV.iMVx / SubPelFactor);    MVPred[uMVnum].iMVy = (Ipp8s) (PredictedMV.iMVy / SubPelFactor);    for (i = 0; i < uMVnum; i ++)    {        if (MVPred[uMVnum].iMVx == MVPred[i].iMVx &&            MVPred[uMVnum].iMVy == MVPred[i].iMVy)            break;        if (i == uMVnum - 1 &&            MVPred[uMVnum].iMVx >= xMin && MVPred[uMVnum].iMVx <= xMax &&            MVPred[uMVnum].iMVy >= yMin && MVPred[uMVnum].iMVy <= yMax)        {            uMVnum ++;            break;        }    }    // above predictor    if (bMBIsNotOnTopEdge) {        pMVAbove = pMV - uWidthIn4x4Blocks;        MVPred[uMVnum].iMVx = pMVAbove->iMVx / SubPelFactor;        MVPred[uMVnum].iMVy = pMVAbove->iMVy / SubPelFactor;        for (i = 0; i < uMVnum; i ++)        {            if (MVPred[uMVnum].iMVx == MVPred[i].iMVx &&                MVPred[uMVnum].iMVy == MVPred[i].iMVy)                break;            if (i == uMVnum - 1 &&                MVPred[uMVnum].iMVx >= xMin && MVPred[uMVnum].iMVx <= xMax &&                MVPred[uMVnum].iMVy >= yMin && MVPred[uMVnum].iMVy <= yMax)            {                uMVnum ++;                break;            }        }    }    // This code properly selects and scales a MV from the reference frame(s)    H264EncoderFrame *pPrevFrm = m_pCurrentFrame->GetRefPicList(0, LIST_0)->m_RefPicList[0];    // TO DO may be we should consider future MV if exist and B-slice    //H264EncoderFrame *pFutFrm = m_pCurrentFrame->GetRefPicList(0, LIST_1)->m_RefPicList[0];    pMVRef = &pPrevFrm->pMVL0[m_pCurrentFrame->pMBOffsets[uMB].uFirstBlockIndex];    if (!bBSlice) {        // Not B Slice, Magnitude is correct, simply copy vector        MVPred[uMVnum].iMVx = pMVRef->iMVx;        MVPred[uMVnum].iMVy = pMVRef->iMVy;    } else {        // B Slice        // Forward vector, needs to be scaled, but direction is correct        Ipp32s iSign;        //iSign = pMVRef->iMVx < 0 ? -1 : 1;        iSign = 1;        MVPred[uMVnum].iMVx = (Ipp8s) ((uFwdRatio * pMVRef->iMVx + TR_RND * iSign) >> TR_SHIFT);        iSign = pMVRef->iMVy < 0 ? -1 : 1;        iSign = 1;        MVPred[uMVnum].iMVy = (Ipp8s) ((uFwdRatio * pMVRef->iMVy + TR_RND * iSign) >> TR_SHIFT);        if (bBackwardFlag) {            // Backward vector, needs both scaling and direction changed

⌨️ 快捷键说明

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