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

📄 motionestimationquarterpel.cpp

📁 JMVM MPEG MVC/3DAV 测试平台 国际通用标准
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#if JMVM_ONLY  // JVT-U052
Void MotionEstimationQuarterPel::xSubPelSearch( Icp&              rcIcp,
                                                IntYuvPicBuffer*  pcPelData,
                                                Mv&               rcMv,
                                                UInt&             ruiSAD,
                                                UInt              uiBlk,
                                                UInt              uiMode,
                                                Bool              bQPelOnly )
{
  // TMM_ESS {
  Mv    cIniMv = rcMv;
  if( bQPelOnly && (rcMv.getHor() % 2 || rcMv.getVer() % 2) )
  {
    rcMv >>= 1;
    rcMv <<= 1;
  }
// TMM_ESS }

  Icp   cIcpBestMatch = rcIcp;
  Mv    cMvBestMatch  = rcMv;
  UInt  uiBestSad     = MSYS_UINT_MAX;
  UInt  uiNumHPelPos  = 9;
  UInt  uiNumQPelPos  = 9;
  UInt  uiBestHPelPos = MSYS_UINT_MAX;

  Int   n;
  UInt  uiYSize;
  UInt  uiXSize;

  // KJH: set m_cXDSS scale/offset as found Icp : NO NEED
  xResetIcpInMs( m_cXDSS.sIcpInMs );
  m_cXDSS.sIcpInMs.sIcAct  = rcIcp.getIcAct();

  if( bQPelOnly )
  {
    AOT( (rcMv.getHor() % 2) || (rcMv.getVer() % 2) );
    cMvBestMatch >>= 2;
    cMvBestMatch <<= 2;

    //--- get best h-pel search position ---
    Mv cMvDiff = rcMv - cMvBestMatch;
    for( Int iHIndex = 0; iHIndex < 9; iHIndex++ )
    { 
      if( cMvDiff == g_acHPSearchMv[iHIndex] )
      {
        uiBestHPelPos = iHIndex;
        break;
      }
    }
    AOT( uiBestHPelPos == 5 || uiBestHPelPos == 1 || uiBestHPelPos == 6 ||
         uiBestHPelPos == 3 || uiBestHPelPos == 7 || uiBestHPelPos == MSYS_UINT_MAX );
    
    rcMv = cMvBestMatch;
  }

  xGetSizeFromMode      ( uiXSize, uiYSize, uiMode);
  xCompensateBlocksHalf ( m_aXHPelSearch, pcPelData, cMvBestMatch, uiMode, uiYSize, uiXSize ) ;
  m_cXDSS.iYStride = X1;

  if( ! bQPelOnly || 0 == uiBestHPelPos )
  {
    n = 0;
    Mv cMvTest = g_acHPSearchMv[n];
    m_cXDSS.pYSearch = m_apXHPelSearch[n];
    UInt uiSad = m_cXDSS.Func( &m_cXDSS );

    cMvTest += rcMv;
    uiSad += xGetCost( cMvTest );

    if( uiSad < uiBestSad )
    {
      m_uiBestMode = n;
      uiBestSad = uiSad;
      cMvBestMatch = cMvTest;

      if (cIcpBestMatch.getIcAct())
	  {
        cIcpBestMatch.setOffset( m_cXDSS.sIcpInMs.sOffset );
      }
    }
  }

  //compute SAD for initial 1/2 pel MV
  for( n = 1; n < (Int)uiNumHPelPos; n++ )
  {
    if( bQPelOnly && n != uiBestHPelPos )
    {
      continue;
    }

    Mv cMvTest = g_acHPSearchMv[n];
    m_cXDSS.pYSearch = m_apXHPelSearch[n];
    UInt uiSad = m_cXDSS.Func( &m_cXDSS );

    cMvTest += rcMv;
    UInt uiCost = xGetCost( cMvTest );
    uiSad += uiCost;

    if( uiSad < uiBestSad )
    {
      m_uiBestMode = n;
      uiBestSad = uiSad;
      cMvBestMatch = cMvTest;
	  
      if (cIcpBestMatch.getIcAct())
	  {
        cIcpBestMatch.setOffset( m_cXDSS.sIcpInMs.sOffset );
      }
    }
  }

  rcMv = cMvBestMatch;
  rcIcp = cIcpBestMatch;

  XPel* pPel = pcPelData->getLumBlk();
  Int iStride = pcPelData->getLStride();
  pPel += (cMvBestMatch.getHor()>>1) + (cMvBestMatch.getVer()>>1) * iStride;

  m_pcQuarterPelFilter->filterBlock( m_aXQPelSearch, pPel, iStride, uiXSize, uiYSize, g_aucFilter[m_uiBestMode]);
  m_cXDSS.iYStride = 16;

  //1/4 pel refinement around initial 1/2 pel MV
  for( n = 1; n < (Int)uiNumQPelPos; n++ )
  {
    Mv cMvTest = g_acQPSearchMv[n];
    m_cXDSS.pYSearch = m_apXQPelSearch[n];
    UInt uiSad = m_cXDSS.Func( &m_cXDSS );

    cMvTest += rcMv;
    uiSad += xGetCost( cMvTest );

    // TMM_ESS {
    if( bQPelOnly && (abs(cIniMv.getHor()-cMvTest.getHor()) > 1 || abs(cIniMv.getVer()-cMvTest.getVer()) > 1) )
      uiSad = MSYS_UINT_MAX;
    // TMM_ESS }
	
    if( uiSad < uiBestSad )
    {
      m_uiBestMode = n<<4;
      uiBestSad = uiSad;
      cMvBestMatch = cMvTest;

      if (cIcpBestMatch.getIcAct())
	  {
        cIcpBestMatch.setOffset( m_cXDSS.sIcpInMs.sOffset);
      }
    }
  }

  rcMv = cMvBestMatch;
  ruiSAD = uiBestSad;
  rcIcp = cIcpBestMatch;

// TMM_ESS {
//---
  if( bQPelOnly && (cIniMv.getHor() % 2 || cIniMv.getVer() % 2) )
  {
    int   dx0 = ((cIniMv.getHor()>>1)<<1);
    int   dy0 = ((cIniMv.getVer()>>1)<<1);
    int   dx1 = (cIniMv.getHor() % 2) ? (dx0+2) : dx0;
    int   dy1 = (cIniMv.getVer() % 2) ? (dy0+2) : dy0;

    for (int dx=dx0; dx<=dx1; dx+=2)
    {
      for (int dy=dy0; dy<=dy1; dy+=2)
      {
        if (dx!=dx0 || dy!=dy0)
        {
          rcMv.setHor(dx);
          rcMv.setVer(dy);

          UInt  uiBestSad1     = MSYS_UINT_MAX;
          Mv    cMvBestMatch1 = rcMv;
          cMvBestMatch1 >>= 2;
          cMvBestMatch1 <<= 2;

          //--- get best h-pel search position ---
          Mv cMvDiff = rcMv - cMvBestMatch1;
          for( Int iHIndex = 0; iHIndex < 9; iHIndex++ )
          { 
            if( cMvDiff == g_acHPSearchMv[iHIndex] )
            {
              uiBestHPelPos = iHIndex;
              break;
            }
          }
          AOT( uiBestHPelPos == 5 || uiBestHPelPos == 1 || uiBestHPelPos == 6 ||
               uiBestHPelPos == 3 || uiBestHPelPos == 7 || uiBestHPelPos == MSYS_UINT_MAX );
    
          rcMv = cMvBestMatch1;


          xGetSizeFromMode      ( uiXSize, uiYSize, uiMode);
          xCompensateBlocksHalf ( m_aXHPelSearch, pcPelData, cMvBestMatch1, uiMode, uiYSize, uiXSize ) ;
          m_cXDSS.iYStride = X1;

          if( 0 == uiBestHPelPos )
          {
            n = 0;
            Mv cMvTest = g_acHPSearchMv[n];
            m_cXDSS.pYSearch = m_apXHPelSearch[n];
            UInt uiSad = m_cXDSS.Func( &m_cXDSS );

            cMvTest += rcMv;
            uiSad += xGetCost( cMvTest );

            if( uiSad < uiBestSad1 )
            {
              m_uiBestMode = n;
              uiBestSad1 = uiSad;
              cMvBestMatch1 = cMvTest;
            }
          }

          //compute SAD for initial 1/2 pel MV
          for( n = 1; n < (Int)uiNumHPelPos; n++ )
          {
            if( n != uiBestHPelPos )
            {
              continue;
            }

            Mv cMvTest = g_acHPSearchMv[n];
            m_cXDSS.pYSearch = m_apXHPelSearch[n];
            UInt uiSad = m_cXDSS.Func( &m_cXDSS );

            cMvTest += rcMv;
            UInt uiCost = xGetCost( cMvTest );
            uiSad += uiCost;

            if( uiSad < uiBestSad1 )
            {
              m_uiBestMode = n;
              uiBestSad1 = uiSad;
              cMvBestMatch1 = cMvTest;
            }
          }

          rcMv = cMvBestMatch1;

          XPel* pPel = pcPelData->getLumBlk();
          Int iStride = pcPelData->getLStride();
          pPel += (cMvBestMatch1.getHor()>>1) + (cMvBestMatch1.getVer()>>1) * iStride;

          m_pcQuarterPelFilter->filterBlock( m_aXQPelSearch, pPel, iStride, uiXSize, uiYSize, g_aucFilter[m_uiBestMode]); //1/4 pel interp
          m_cXDSS.iYStride = 16;

          //1/4 pel refinement around initial 1/2 pel MV
          for( n = 1; n < (Int)uiNumQPelPos; n++ )
          {
            Mv cMvTest = g_acQPSearchMv[n];
            m_cXDSS.pYSearch = m_apXQPelSearch[n];
            UInt uiSad = m_cXDSS.Func( &m_cXDSS );

            cMvTest += rcMv;
            uiSad += xGetCost( cMvTest );

            if( bQPelOnly && (abs(cIniMv.getHor()-cMvTest.getHor()) > 1 || abs(cIniMv.getVer()-cMvTest.getVer()) > 1) )
              uiSad = MSYS_UINT_MAX;

            if( uiSad < uiBestSad1 )
            {
              m_uiBestMode = n<<4;
              uiBestSad1 = uiSad;
              cMvBestMatch1 = cMvTest;
            }
          }

          if (uiBestSad1 < uiBestSad)
          {
            uiBestSad = uiBestSad1;
            rcMv = cMvBestMatch1;
            ruiSAD = uiBestSad;
          }
        } // if (dx!=dx0 || dy!=dy0)
      } // for (int dy=dy0; dy<=dy1; dy+=2)
    } // for (int dx=dx0; dx<=dx1; dx+=2)
  }
//---
// TMM_ESS }
  return;
}

#endif



Void MotionEstimationQuarterPel::xGetSizeFromMode( UInt& ruiXSize, UInt& ruiYSize, UInt uiMode )
{
  switch( uiMode )
  {
  case MODE_16x16:
    {
      ruiYSize = 16;
      ruiXSize = 16;
      break;
    }
  case MODE_8x16:
    {
      ruiYSize = 16;
      ruiXSize = 8;
      break;
    }
  case MODE_16x8:
    {
      ruiYSize = 8;
      ruiXSize = 16;
      break;
    }
  case BLK_8x8:
    {
      ruiYSize = 8;
      ruiXSize = 8;
      break;
    }

  case BLK_4x8:
    {
      ruiYSize = 8;
      ruiXSize = 4;
      break;
    }

  case BLK_8x4:
    {
      ruiYSize = 4;
      ruiXSize = 8;
      break;
    }

  case BLK_4x4:
    {
      ruiYSize = 4;
      ruiXSize = 4;
      break;
    }
  default:
    assert( 0 );
    return;
  }
}

Void MotionEstimationQuarterPel::xCompensateBlocksHalf( XPel *pPelDes, IntYuvPicBuffer *pcRefPelData, Mv cMv, UInt uiMode, UInt uiYSize, UInt uiXSize )
{
  XPel* pPelSrc = pcRefPelData->getLumBlk();
  Int iSrcStride = pcRefPelData->getLStride();
  pPelSrc += (cMv.getHor()>>1) + (cMv.getVer()>>1) * iSrcStride;

  uiXSize++;
  UInt x, y;
  for( y = 0; y < uiYSize; y++)
  {
    for( x = 0; x < uiXSize; x++)
    {
      Int x4 = x<<1;
      pPelDes[3*X1*17] = pPelSrc[x4-iSrcStride-1],
      pPelDes[1*X1*17] = pPelSrc[x4-iSrcStride],
      pPelDes++;
    }
    pPelDes -= uiXSize;
    for( x = 0; x < uiXSize; x++)
    {
      Int x4 = x<<1;
      pPelDes[2*X1*17] = pPelSrc[x4-1];
      pPelDes[0*X1*17] = pPelSrc[x4],
      pPelDes++;
    }
    pPelDes += X1-uiXSize;
    pPelSrc += 2*iSrcStride;
  }

  for( x = 0; x < uiXSize; x++)
  {
    Int x4 = x<<1;
    pPelDes[3*X1*17] = pPelSrc[x4-iSrcStride-1],
    pPelDes[1*X1*17] = pPelSrc[x4-iSrcStride],
    pPelDes++;
  }
  return;
}


ErrVal MotionEstimationQuarterPel::compensateBlock( IntYuvMbBuffer* pcRecPelData,
                                                    UInt            uiBlk,
                                                    UInt            uiMode,
                                                    IntYuvMbBuffer* pcRefPelData2 )
{
  pcRecPelData->set4x4Block( B4x4Idx(uiBlk) );
  XPel iStride = pcRecPelData->getLStride();
  XPel* pDes = pcRecPelData->getLumBlk();
  XPel* pSrc;
  Int iAdd;

  if( 0x10 > m_uiBestMode )
  {
    pSrc = m_apXHPelSearch[m_uiBestMode];
    iAdd = X1;
  }
  else
  {
    pSrc = m_apXQPelSearch[m_uiBestMode>>4];
    iAdd = 16;
  }

  UInt uiXSize = 0;
  UInt uiYSize = 0;
  xGetSizeFromMode( uiXSize, uiYSize, uiMode);

  if( pcRefPelData2 == NULL )
  {
    for( UInt y = 0; y < uiYSize; y++)
    {
      for( UInt x = 0; x < uiXSize; x+=4 )
      {
        pDes[x+0] = pSrc[x+0];
        pDes[x+1] = pSrc[x+1];
        pDes[x+2] = pSrc[x+2];
        pDes[x+3] = pSrc[x+3];
      }
      pDes += iStride;
      pSrc += iAdd;
    }
  }
  else
  {
    pcRefPelData2->set4x4Block( B4x4Idx(uiBlk) );
    XPel iStride2 = pcRefPelData2->getLStride();
    XPel* pSrc2 = pcRefPelData2->getLumBlk();
    for( UInt y = 0; y < uiYSize; y++)
    {
      for( UInt x = 0; x < uiXSize; x+=4 )
      {
        pDes[x+0] = (pSrc[x+0] + pSrc2[x+0] + 1)>>1;
        pDes[x+1] = (pSrc[x+1] + pSrc2[x+1] + 1)>>1;
        pDes[x+2] = (pSrc[x+2] + pSrc2[x+2] + 1)>>1;
        pDes[x+3] = (pSrc[x+3] + pSrc2[x+3] + 1)>>1;
      }
      pDes  += iStride;
      pSrc  += iAdd;
      pSrc2 += iStride2;
    }

  }
  return Err::m_nOK;
}


H264AVC_NAMESPACE_END

⌨️ 快捷键说明

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