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

📄 umc_me_m2.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
字号:
/* /////////////////////////////////////////////////////////////////////////////
//
//                  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) 2007 Intel Corporation. All Rights Reserved.
//
//
//          MPEG2 encoder motion estimation
//
*/
#if 0
#include "umc_me_m2.h"


//*******************************************************************************************************
namespace UMC
{


MeMPEG2::MeMPEG2()
{
}

MeMPEG2::~MeMPEG2()
{
}

bool MeMPEG2::Init(MeInitParams *par)
{
  return MeBase::Init(par);
}

#define VARMEAN_INTRA(pblock, step, vardiff, meandiff, _vardiff)                 \
  ippiVarSum8x8_8u32s_C1R(pblock             , step, &vardiff[0], &meandiff[0]); \
  ippiVarSum8x8_8u32s_C1R(pblock + 8         , step, &vardiff[1], &meandiff[1]); \
  ippiVarSum8x8_8u32s_C1R(pblock + 8*step    , step, &vardiff[2], &meandiff[2]); \
  ippiVarSum8x8_8u32s_C1R(pblock + 8*step + 8, step, &vardiff[3], &meandiff[3]); \
  _vardiff = vardiff[0] + vardiff[1] + vardiff[2] + vardiff[3]

#define VARMEAN_INTER(pDiff, step, vardiff, meandiff, _vardiff)              \
  ippiVarSum8x8_16s32s_C1R(pDiff         , step, &vardiff[0], &meandiff[0]); \
  ippiVarSum8x8_16s32s_C1R(pDiff+8       , step, &vardiff[1], &meandiff[1]); \
  ippiVarSum8x8_16s32s_C1R(pDiff+4*step  , step, &vardiff[2], &meandiff[2]); \
  ippiVarSum8x8_16s32s_C1R(pDiff+4*step+8, step, &vardiff[3], &meandiff[3]); \
  _vardiff = vardiff[0] + vardiff[1] + vardiff[2] + vardiff[3]

#define TRY_MV(_bestmv, _bestcost, mvx, mvy) { \
  Ipp32s bcost; \
  ippiSAD16x16_8u32s(src, sstep, ref+((mvx)>>1)+((mvy)>>1)*rstep, rstep, \
    &bcost, (((mvx) & 1) << 3) | (((mvy) & 1) << 2)); \
  if(bcost < _bestcost) { \
    _bestcost = bcost; \
    _bestmv.x = mvx; _bestmv.y = mvy; \
    changed = 1; \
  } \
}

#define MV_IN_RANGE(mvx, mvy) \
  (bx*bw*2+((mvx)>>0)>=ll && (bx+1)*bw*2+((mvx+0)>>0) <= lr && \
   by*bh*2+((mvy)>>0)>=lt && (by+1)*bh*2+((mvy+0)>>0) <= lb )

void MeMPEG2::me_block(const Ipp8u* src, Ipp32s sstep, const Ipp8u* ref, Ipp32s rstep,
                       Ipp32s bh, Ipp32s bx, Ipp32s by,
                       Ipp32s ll, Ipp32s lt, Ipp32s lr, Ipp32s lb,
                       MeMV* mv, Ipp32s* cost, MeMV* mvleft, MeMV* mvtop)
{
  const Ipp32s bw = 16; // can be a param
  MeMV bestmv;
  Ipp32s bestcost = IPP_MAX_32S;
  Ipp32s changed = 0;
  Ipp32s step = (((bx - by) & 7) != 1) ? 2 :
    (IPP_MAX(m_MePar->SearchRange.x, m_MePar->SearchRange.y)>>3<<1);

  TRY_MV(bestmv, bestcost, 0, 0);
  mv->x &= ~1; // to full pixel
  mv->y &= ~1;
  if(MV_IN_RANGE(mv->x, mv->y)) {
    TRY_MV(bestmv, bestcost, mv->x, mv->y);
  }
  // try left and top
  if(mvleft) {
    if(MV_IN_RANGE(mvleft->x & ~1, mvleft->y & ~1)) {
      TRY_MV(bestmv, bestcost, mvleft->x & ~1, mvleft->y & ~1);
    }
  }
  if(mvtop) {
    if(MV_IN_RANGE(mvtop->x & ~1, mvtop->y & ~1)) {
      TRY_MV(bestmv, bestcost, mvtop->x & ~1, mvtop->y & ~1);
    }
  }

  while(step>=1) {
    changed = 1;
    while(changed) {
      MeMV localmv = bestmv;
      changed = 0;
      if(MV_IN_RANGE(bestmv.x+step, bestmv.y)) {
        TRY_MV(localmv, bestcost, bestmv.x+step, bestmv.y);
      }
      if(MV_IN_RANGE(bestmv.x-step, bestmv.y)) {
        TRY_MV(localmv, bestcost, bestmv.x-step, bestmv.y);
      }
      if(MV_IN_RANGE(bestmv.x, bestmv.y+step)) {
        TRY_MV(localmv, bestcost, bestmv.x, bestmv.y+step);
      }
      if(MV_IN_RANGE(bestmv.x, bestmv.y-step)) {
        TRY_MV(localmv, bestcost, bestmv.x, bestmv.y-step);
      }
      if(changed)
        bestmv = localmv;
    }
    step = (step==2) ? 1 : ((step+1)>>2<<1); // keep even till the end
  }

  *mv = bestmv;
  *cost = bestcost;

}

bool MeMPEG2::EstimateFrame(MeParams *par, ME_Frame *res)
{
    Ipp32s x, y;
    Ipp8u *src, *ref[2];
    Ipp16s bufDiff[3][256];
    Ipp32s varintra, varinter, var[4], mean[4];

    //check and save input
    m_MePar = par;

    if(!CheckParams(false))
        return false;

    //estimate

    for( y=0; y<m_HeightMB; y++){
        for( x=0; x<m_WidthMB; x++){
            Ipp32s bestcost;
            src = par->pSrcY + par->srcStep * y * 16 + x*16;
            ref[0] = par->pRefFY[0] + par->refStep * y * 16 + x*16;
            if(par->SearchDirection == bidir_search)
              ref[1] = par->pRefBY[0] + par->refStep * y * 16 + x*16;
            else
              ref[1] = 0;
            m_adr = m_WidthMB*y + x;
            m_ResMB[m_adr].skipped = 0;

            if(x>0 && x+1 < m_WidthMB) { // try to skip (MPEG only)
              if(par->SearchDirection == forward_search) { //P-picture
                ippiGetDiff16x16_8u16s_C1(src, par->srcStep,
                  ref[0], par->refStep,
                  bufDiff[0], 32, 0, 0, 0, ippRndZero);
                VARMEAN_INTER(bufDiff[0], 32, var, mean, varinter);
                //if(varinter <= par->BlockVarThresh) {
                if (var[0] <= par->BlockVarThresh && abs(mean[0])<par->BlockVarThresh*8 &&
                    var[1] <= par->BlockVarThresh && abs(mean[1])<par->BlockVarThresh*8 &&
                    var[2] <= par->BlockVarThresh && abs(mean[2])<par->BlockVarThresh*8 &&
                    var[3] <= par->BlockVarThresh && abs(mean[3])<par->BlockVarThresh*8 ) {
                  m_ResMB[m_adr].skipped = 1;
                  m_ResMB[m_adr].MbType = MbFrw;
                  m_ResMB[m_adr].MbCosts[0] = varinter;
                  m_ResMB[m_adr].MVs[0].x = 0;
                  m_ResMB[m_adr].MVs[0].y = 0;
                  continue;
                }
              } else if (par->SearchDirection == bidir_search) { // B picture
                if ( (m_ResMB[m_adr-1].MbType != MbIntra)
                  && (!(m_ResMB[m_adr-1].MbType == MbFrw || m_ResMB[m_adr-1].MbType == MbBidir)
                      || x*16+(m_ResMB[m_adr-1].MVs[0].x>>1)+16 < m_WidthMB*16)
                  && (!(m_ResMB[m_adr-1].MbType == MbBkw || m_ResMB[m_adr-1].MbType == MbBidir)
                      || x*16+(m_ResMB[m_adr-1].MVs[1].x>>1)+16 < m_WidthMB*16) )
                {
                  if (m_ResMB[m_adr-1].MbType == MbFrw) {
                    ippiGetDiff16x16_8u16s_C1(src, par->srcStep,
                      ref[0]+(m_ResMB[m_adr-1].MVs[0].x>>1)+(m_ResMB[m_adr-1].MVs[0].y>>1)*par->refStep, par->refStep,
                      bufDiff[0], 32, 0, 0,
                      ((m_ResMB[m_adr-1].MVs[0].x & 1) << 3) | ((m_ResMB[m_adr-1].MVs[0].y & 1) << 2), ippRndZero);
                  } else if (m_ResMB[m_adr-1].MbType == MbBkw) {
                    ippiGetDiff16x16_8u16s_C1(src, par->srcStep,
                      ref[0]+(m_ResMB[m_adr-1].MVs[1].x>>1)+(m_ResMB[m_adr-1].MVs[1].y>>1)*par->refStep, par->refStep,
                      bufDiff[0], 32, 0, 0,
                      ((m_ResMB[m_adr-1].MVs[1].x & 1) << 3) | ((m_ResMB[m_adr-1].MVs[1].y & 1) << 2), ippRndZero);
                  } else if (m_ResMB[m_adr-1].MbType == MbBidir) {
                    ippiGetDiff16x16B_8u16s_C1(src, par->srcStep,
                      ref[0]+(m_ResMB[m_adr-1].MVs[0].x>>1)+(m_ResMB[m_adr-1].MVs[0].y>>1)*par->refStep, par->refStep,
                      ((m_ResMB[m_adr-1].MVs[0].x & 1) << 3) | ((m_ResMB[m_adr-1].MVs[0].y & 1) << 2),
                      ref[1]+(m_ResMB[m_adr-1].MVs[1].x>>1)+(m_ResMB[m_adr-1].MVs[1].y>>1)*par->refStep, par->refStep,
                      ((m_ResMB[m_adr-1].MVs[1].x & 1) << 3) | ((m_ResMB[m_adr-1].MVs[1].y & 1) << 2),
                      bufDiff[0], 32, ippRndZero);
                  } else {
                    VM_ASSERT(0);
                  }
                  VARMEAN_INTER(bufDiff[0], 32, var, mean, varinter);
                  //if(varinter <= par->BlockVarThresh) {
                  if (var[0] <= par->BlockVarThresh && abs(mean[0])<par->BlockVarThresh*8 &&
                      var[1] <= par->BlockVarThresh && abs(mean[1])<par->BlockVarThresh*8 &&
                      var[2] <= par->BlockVarThresh && abs(mean[2])<par->BlockVarThresh*8 &&
                      var[3] <= par->BlockVarThresh && abs(mean[3])<par->BlockVarThresh*8 ) {
                    m_ResMB[m_adr].skipped = 1;
                    m_ResMB[m_adr].MbType = m_ResMB[m_adr-1].MbType;
                    m_ResMB[m_adr].MbCosts[0] = varinter;
                    m_ResMB[m_adr].MVs[0] = m_ResMB[m_adr-1].MVs[0];
                    m_ResMB[m_adr].MVs[1] = m_ResMB[m_adr-1].MVs[1];
                    continue;
                  }
                }
              }
            }
            m_BestMV[0].x = m_BestMV[0].y = 0;
            me_block(src, par->srcStep, ref[0], par->refStep,
              16, x, y,
              IPP_MAX(par->PicRange.top_left.x*2, x*16*2 - par->SearchRange.x*2),
              IPP_MAX(par->PicRange.top_left.y*2, y*16*2 - par->SearchRange.y*2),
              IPP_MIN(par->PicRange.bottom_right.x*2, (x+1)*16*2 + par->SearchRange.x*2 -1),
              IPP_MIN(par->PicRange.bottom_right.y*2, (y+1)*16*2 + par->SearchRange.y*2 -1),
              &(m_BestMV[0]), &(m_BestCost[0]),
              x>0 ? &(m_ResMB[m_adr-1].MVs[0]) : 0,
              y>0 ? &(m_ResMB[m_adr-m_HeightMB].MVs[0]) : 0);
            m_ResMB[m_adr].MVs[0] = m_BestMV[0];

            VARMEAN_INTRA(src, par->srcStep, var, mean, varintra);

            ippiGetDiff16x16_8u16s_C1(src, par->srcStep,
              ref[0]+(m_BestMV[0].x>>1)+(m_BestMV[0].y>>1)*par->refStep, par->refStep,
              bufDiff[0], 32, 0, 0,
              ((m_BestMV[0].x & 1) << 3) | ((m_BestMV[0].y & 1) << 2), ippRndZero);
            VARMEAN_INTER(bufDiff[0], 32, var, mean, varinter);

            if(varinter <= varintra) {
              m_ResMB[m_adr].MbType = MbFrw;
              bestcost = varinter;
            } else {
              m_ResMB[m_adr].MbType = MbIntra;
              bestcost = varintra;
            }
            m_ResMB[m_adr].MbCosts[0] = bestcost;
            if(m_ResMB[m_adr].MbType == MbFrw) {
              if (var[0] <= par->BlockVarThresh && abs(mean[0])<par->BlockVarThresh &&
                  var[1] <= par->BlockVarThresh && abs(mean[1])<par->BlockVarThresh &&
                  var[2] <= par->BlockVarThresh && abs(mean[2])<par->BlockVarThresh &&
                  var[3] <= par->BlockVarThresh && abs(mean[3])<par->BlockVarThresh ) {
                continue;
              }
            }
            if(par->SearchDirection != bidir_search) {
              continue;
            }

            m_BestMV[1].x = -m_BestMV[0].x; // need to be scaled
            m_BestMV[1].y = -m_BestMV[0].y; // need to be scaled

            me_block(src, par->srcStep, ref[1], par->refStep,
              16, x, y,
              IPP_MAX(par->PicRange.top_left.x*2, x*16*2 - par->SearchRange.x*2),
              IPP_MAX(par->PicRange.top_left.y*2, y*16*2 - par->SearchRange.y*2),
              IPP_MIN(par->PicRange.bottom_right.x*2, (x+1)*16*2 + par->SearchRange.x*2 -1),
              IPP_MIN(par->PicRange.bottom_right.y*2, (y+1)*16*2 + par->SearchRange.y*2 -1),
              &(m_BestMV[1]), &(m_BestCost[1]),
              x>0 ? &(m_ResMB[m_adr-1].MVs[1]) : 0,
              y>0 ? &(m_ResMB[m_adr-m_HeightMB].MVs[1]) : 0);
            m_ResMB[m_adr].MVs[1] = m_BestMV[1];

            ippiGetDiff16x16_8u16s_C1(src, par->srcStep,
              ref[1]+(m_BestMV[1].x>>1)+(m_BestMV[1].y>>1)*par->refStep, par->refStep,
              bufDiff[1], 32, 0, 0,
              ((m_BestMV[1].x & 1) << 3) | ((m_BestMV[1].y & 1) << 2), ippRndZero);
            VARMEAN_INTER(bufDiff[1], 32, var, mean, varinter);
// both MVs are stored in their positions!!!

            m_ResMB[m_adr].MVs[1] = m_BestMV[1];
            if(varinter < bestcost) {
              m_ResMB[m_adr].MbType = MbBkw;
              bestcost = varinter;
            }

            // try bidir now
            ippiGetDiff16x16B_8u16s_C1(src, par->srcStep,
              ref[0]+(m_BestMV[0].x>>1)+(m_BestMV[0].y>>1)*par->refStep, par->refStep,
              ((m_BestMV[0].x & 1) << 3) | ((m_BestMV[0].y & 1) << 2),
              ref[1]+(m_BestMV[1].x>>1)+(m_BestMV[1].y>>1)*par->refStep, par->refStep,
              ((m_BestMV[1].x & 1) << 3) | ((m_BestMV[1].y & 1) << 2),
              bufDiff[2], 32, ippRndZero);
            VARMEAN_INTER(bufDiff[2], 32, var, mean, varinter);
            m_BestCost[2] = varinter;

            if(varinter*17 < bestcost*16) {
              m_ResMB[m_adr].MbType = MbBidir;
              bestcost = varinter;
            }
            m_ResMB[m_adr].MbCosts[0] = bestcost;
         }
    }

    //save results
    res->NumOfMVs = m_NumOfMVs;
    res->MBs = m_ResMB;

    return true;
}

void MeMPEG2::Close()
{
  return MeBase::Close();
}

}
#endif

⌨️ 快捷键说明

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