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

📄 motionestimation.cpp

📁 jsvm开发代码包括抽样,编码,抽取,解码等一系列功能,可以做工具或研究用
💻 CPP
📖 第 1 页 / 共 4 页
字号:

  if( ! bQPelRefinementOnly )
  {
    if( uiSearchRange )
    {
      xPelBlockSearch     ( pcRefPelData[0], cMv, uiMinSAD, uiSearchRange );
    }
    else
    {
      switch( m_cParams.getSearchMode() )
      {
      case 0:
        {
          xPelBlockSearch ( pcRefPelData[0], cMv, uiMinSAD );
        }
        break;
      case 1:
        {
          xPelSpiralSearch( pcRefPelData[0], cMv, uiMinSAD );
        }
        break;
      case 2:
        {
          xPelLogSearch   ( pcRefPelData[0], cMv, uiMinSAD, false, m_iMaxLogStep << ((NULL == pcBSP) ? 1 : 0) );
        }
        break;
      case 3:
        {
          rcMbDataAccess.getMvPredictors( m_acMvPredictors );
          xPelLogSearch   ( pcRefPelData[0], cMv, uiMinSAD, true, (NULL == pcBSP) ? 2 : 1 );
        }
        break;
      case 4:
        {
          rcMbDataAccess.getMvPredictors( m_acMvPredictors );
          xTZSearch( pcRefPelData[0], cMv, uiMinSAD );
        }
        break;
      default:
        RERR();
        break;
      }
    }
    cMv <<= 2;
  }
  else
  {
    Mv cMvBase = cMv;
    cMv.limitComponents( m_cMin, m_cMax );
    if( ! ( cMvBase == cMv ) )
    {
      // don't refine in that case
      rcMv     = cMvBase;
      ruiBits += 2;
      ruiCost  = MSYS_UINT_MAX / 2;
      // >>>> bug fix by H.Schwarz 19/9/05
      if( bOriginalSearchModeIsYUVSAD )
      {
        m_cParams.setFullPelDFunc( DF_YUV_SAD );
      }
      // <<<< bug fix by H.Schwarz 19/9/05
      return Err::m_nOK;
    }
  }
  // heiko.schwarz@hhi.fhg.de (fix for uninitialized memory with YUV_SAD and bi-directional search) >>>>
  if( bOriginalSearchModeIsYUVSAD )
  {
    m_cParams.setFullPelDFunc( DF_YUV_SAD );
  }
  // <<< heiko.schwarz@hhi.fhg.de (fix for uninitialized memory with YUV_SAD and bi-directional search)


  //===== SUB-PEL ESTIMATION =====
  xGetMotionCost( 1 != ( 1 & m_cParams.getSubPelDFunc() ), 0 );
  m_pcXDistortion->getDistStruct( uiMode, m_cParams.getSubPelDFunc(), false, m_cXDSS );
  m_cXDSS.pYOrg = pcWeightedYuvBuffer->getLumBlk();
  xSetCostScale( 0 );

  xSubPelSearch( pcRefPelData[1], cMv, uiMinSAD, uiBlk, uiMode, bQPelRefinementOnly );

  Short sHor      = cMv.getHor();
  Short sVer      = cMv.getVer();
  UInt  uiMvBits  = xGetBits( sHor, sVer );
  ruiBits        += uiMvBits;
  ruiCost         = (UInt)floor( fWeight * (Double)( uiMinSAD - xGetCost( uiMvBits ) ) ) + xGetCost( ruiBits );
  rcMv            = cMv;

  return Err::m_nOK;
}








ErrVal MotionEstimation::initMb( UInt uiMbPosY, UInt uiMbPosX, MbDataAccess& rcMbDataAccess )
{
  RNOK( MotionCompensation::initMb( uiMbPosY, uiMbPosX, rcMbDataAccess) );// TMM_INTERLACE

  return Err::m_nOK;
}





Void MotionEstimation::xPelBlockSearch( IntYuvPicBuffer *pcPelData, Mv& rcMv, UInt& ruiSAD, UInt uiSearchRange )
{
  if( ! uiSearchRange )
  {
    uiSearchRange = m_cParams.getSearchRange();
  }

  Int     iYStride   = pcPelData->getLStride();
  XPel*   pucYRef    = pcPelData->getLumBlk ();
  XPel*   pucYSearch;
  Int     iCStride   = pcPelData->getCStride();
  XPel*   pucURef    = pcPelData->getCbBlk  ();
  XPel*   pucVRef    = pcPelData->getCrBlk  ();
  UInt    uiSad;

  Int y = 0;
  Int x = 0;

  m_cXDSS.iYStride = iYStride;
  m_cXDSS.iCStride = iCStride;

  ruiSAD = MSYS_UINT_MAX;
  rcMv.limitComponents( m_cMin, m_cMax );
  rcMv >>= 2;

  SearchRect cSearchRect;
  cSearchRect.init( uiSearchRange, rcMv, m_cMin, m_cMax );

  pucYSearch  = pucYRef - iYStride * (cSearchRect.iNegVerLimit);

  for(  y = -cSearchRect.iNegVerLimit; y <= cSearchRect.iPosVerLimit; y++ )
  {
    for( x = -cSearchRect.iNegHorLimit; x <= cSearchRect.iPosHorLimit; x++ )
    {
      m_cXDSS.pYSearch  = pucYSearch + x;
      m_cXDSS.pUSearch  = pucURef + (y>>1)*iCStride + (x>>1);
      m_cXDSS.pVSearch  = pucVRef + (y>>1)*iCStride + (x>>1);

      uiSad  = m_cXDSS.Func( &m_cXDSS );
      uiSad += xGetCost( x, y);

      if( ruiSAD > uiSad )
      {
        ruiSAD = uiSad;
        rcMv.setVer( y );
        rcMv.setHor( x );
      }
    }
    pucYSearch += iYStride;
  }


  y = rcMv.getVer();
  x = rcMv.getHor();

  ruiSAD -= xGetCost( x, y);

  DO_DBG( m_cXDSS.pYSearch = pucYRef +  y     * iYStride +  x     );
  DO_DBG( m_cXDSS.pUSearch = pucURef + (y>>1) * iCStride + (x>>1) );
  DO_DBG( m_cXDSS.pVSearch = pucVRef + (y>>1) * iCStride + (x>>1) );
  uiSad  = m_cXDSS.Func( &m_cXDSS );
  AOF_DBG( ruiSAD == ( uiSad  = m_cXDSS.Func( &m_cXDSS ) ) );
}




Void MotionEstimation::xPelSpiralSearch( IntYuvPicBuffer *pcPelData, Mv& rcMv, UInt& ruiSAD, UInt uiSearchRange )
{
  if( ! uiSearchRange )
  {
    uiSearchRange = m_cParams.getSearchRange();
  }

  m_cXDSS.iYStride  = pcPelData->getLStride();
  m_cXDSS.iCStride  = pcPelData->getCStride();
  XPel* pucYRef     = pcPelData->getLumBlk();
  XPel* pucURef     = pcPelData->getCbBlk ();
  XPel* pucVRef     = pcPelData->getCrBlk ();
  UInt  uiSad;
  UInt  uiBestPos = 0;

  Mv cLimitMv( 4*uiSearchRange, 4*uiSearchRange );
  Mv cMin = m_cMin + cLimitMv;
  Mv cMax = m_cMax - cLimitMv;

  rcMv.limitComponents( cMin, cMax );
  rcMv >>= 2;

  ruiSAD = MSYS_UINT_MAX;
  for( UInt n = 0; n < m_uiSpiralSearchEntries; n++ )
  {
    Int x = rcMv.getHor() + m_pcMvSpiralSearch[n].getHor();
    Int y = rcMv.getVer() + m_pcMvSpiralSearch[n].getVer();
    
    m_cXDSS.pYSearch = pucYRef + y * m_cXDSS.iYStride + x;
    m_cXDSS.pUSearch = pucURef + (y>>1) * m_cXDSS.iCStride + (x>>1);
    m_cXDSS.pVSearch = pucVRef + (y>>1) * m_cXDSS.iCStride + (x>>1);
    
    uiSad  = m_cXDSS.Func( &m_cXDSS );
    uiSad += xGetCost( x, y );

    if( ruiSAD > uiSad )
    {
      ruiSAD = uiSad;
      uiBestPos = n;
    }

  }
  rcMv += m_pcMvSpiralSearch[uiBestPos];

  Int y = rcMv.getVer();
  Int x = rcMv.getHor();

  ruiSAD -= xGetCost( x, y);

  DO_DBG( m_cXDSS.pYSearch = pucYRef +  y     * m_cXDSS.iYStride +  x );
  DO_DBG( m_cXDSS.pUSearch = pucURef + (y>>1) * m_cXDSS.iCStride + (x>>1) );
  DO_DBG( m_cXDSS.pVSearch = pucVRef + (y>>1) * m_cXDSS.iCStride + (x>>1) );
  AOF_DBG( ruiSAD == ( uiSad  = m_cXDSS.Func( &m_cXDSS ) ) );
}



Void MotionEstimation::xPelLogSearch( IntYuvPicBuffer *pcPelData, Mv& rcMv, UInt& ruiSAD, Bool bFme, UInt uiStep, UInt uiSearchRange )
{
  if( ! uiSearchRange )
  {
    uiSearchRange = m_cParams.getSearchRange();
  }

  XPel* pucRef  = pcPelData->getLumBlk();
  XPel* pucSearch;
  Int   iStride = pcPelData->getLStride();
  UInt  uiSad;
  UInt  uiBestSad;

  Int   iStepSizeStart = uiStep;

  Mv cMvPred = rcMv;
  cMvPred.limitComponents( m_cMin, m_cMax );
  cMvPred >>= 2;

  SearchRect cSearchRect;
  cSearchRect.init( uiSearchRange, cMvPred, m_cMin, m_cMax );

  rcMv.limitComponents( m_cMin, m_cMax );
  rcMv >>= 2;


  m_cXDSS.iYStride = iStride;
  m_cXDSS.pYSearch = pucRef + rcMv.getHor() + rcMv.getVer() * iStride;
  uiBestSad = m_cXDSS.Func( &m_cXDSS );
  uiBestSad += xGetCost( rcMv.getHor(), rcMv.getVer() );

  if( bFme )
  {
    for( UInt n = 0; n < 3; n++ )
    {
      Mv cMv = m_acMvPredictors[n];
      {
        cMv.limitComponents( m_cMin, m_cMax );
        cMv >>= 2;
        XPel* pStart = pucRef + cMv.getHor() + cMv.getVer() * iStride;
        m_cXDSS.pYSearch = pStart;
        uiSad  = m_cXDSS.Func( &m_cXDSS );
        uiSad += xGetCost( cMv.getHor(), cMv.getVer());
        if( uiBestSad > uiSad )
        {
          uiBestSad = uiSad;
          rcMv = cMv;
        }
      }
    }
  }


  Int x = rcMv.getHor();
  Int y = rcMv.getVer();
  pucSearch = pucRef + x + y * iStride;

  Int dxOld = 0;
  Int dyOld = 0;
  Bool  bContinue;
  Int   iStepStride;
  Int iStep;


  for( iStep = iStepSizeStart; iStep != 0; iStep >>= 1 )
  {
    bContinue   = true;
    iStepStride = iStep * iStride;
    dxOld = 0;
    dyOld = 0;

    while( ruiSAD && bContinue )
    {
      Int   dx = 0;
      Int   dy = 0;

      if( dxOld <= 0 && -x <= cSearchRect.iNegHorLimit - iStep )
      {
        m_cXDSS.pYSearch = pucSearch - iStep;
        uiSad = m_cXDSS.Func( &m_cXDSS );
        uiSad += xGetCost( x - iStep, y);

        if( uiBestSad > uiSad )
        {
          uiBestSad = uiSad;
          dx = -iStep;
        }
      }


      if( dxOld >= 0 && x < cSearchRect.iPosHorLimit - iStep)
      {
        m_cXDSS.pYSearch = pucSearch + iStep;
        uiSad = m_cXDSS.Func( &m_cXDSS );
        uiSad += xGetCost( x + iStep, y);

        if( uiBestSad > uiSad )
        {
          uiBestSad = uiSad;
          dx = iStep;
        }
      }


      if( dyOld <= 0 && -y <= cSearchRect.iNegVerLimit - iStep)
      {
        m_cXDSS.pYSearch = pucSearch - iStepStride;
        uiSad = m_cXDSS.Func( &m_cXDSS );
        uiSad += xGetCost( x, y - iStep );

        if( uiBestSad > uiSad )
        {
          uiBestSad = uiSad;
          dx =  0;
          dy = -iStep;
        }
      }


      if( dyOld >= 0 && y < cSearchRect.iPosVerLimit - iStep)
      {
        m_cXDSS.pYSearch = pucSearch + iStepStride;
        uiSad = m_cXDSS.Func( &m_cXDSS );
        uiSad += xGetCost( x, y + iStep );

        if( uiBestSad > uiSad )

⌨️ 快捷键说明

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