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

📄 intraprediction.cpp

📁 JVT-Z203_jsvm.rar
💻 CPP
📖 第 1 页 / 共 4 页
字号:


Void IntraPrediction::xSet8x8AvailableMask( B8x8Idx cIdx )
{
  B4x4Idx c4x4Idx( cIdx );
  UInt uiM1 = xGetAvailableMask( c4x4Idx );
  c4x4Idx++;
  UInt uiM2 = xGetAvailableMask( c4x4Idx );

  m_uiAvailable  = 0;
  m_uiAvailable |= uiM2&8;
  m_uiAvailable |= uiM1&7;

  m_bSpecial = ( cIdx.b8x8Index() == 1 );
}


ErrVal IntraPrediction::predictLuma8x8Block( XPel* puc, Int iStride, UInt uiPredMode, B8x8Idx cIdx )
{
  xSet8x8AvailableMask( cIdx );

  switch( uiPredMode )
  {
  case 0:
    {
      xPredLum8x8Mode0Vert( puc, iStride );
      ROFRS( xIsAboveRef(), Err::m_nDataNotAvailable );
      break;
    }
  case 1:
    {
      xPredLum8x8Mode1Horiz( puc, iStride );
      ROFRS( xIsLeftRef(), Err::m_nDataNotAvailable );
      break;
    }
  case 2:
    {
      xPredLum8x8Mode2Dc( puc, iStride );
      break;
    }
  case 3:
    {
      xPredLum8x8Mode3DiagDownLeft( puc, iStride );
      ROFRS( xIsAboveRef(), Err::m_nDataNotAvailable );
      break;
    }
  case 4:
    {
      xPredLum8x8Mode4DiagDownRight( puc, iStride );
      ROFRS( xIsAllLeftAboveRef(), Err::m_nDataNotAvailable );
      break;
    }
  case 5:
    {
      xPredLum8x8Mode5VertRight( puc, iStride );
      ROFRS( xIsAllLeftAboveRef(), Err::m_nDataNotAvailable );
      break;
    }
  case 6:
    {
      xPredLum8x8Mode6HorizDown( puc, iStride );
      ROFRS( xIsAllLeftAboveRef(), Err::m_nDataNotAvailable );
      break;
    }
  case 7:
    {
      xPredLum8x8Mode7VertLeft( puc, iStride );
      ROFRS( xIsAboveRef(), Err::m_nDataNotAvailable );
      break;
    }
  case 8:
    {
      xPredLum8x8Mode8HorizUp( puc, iStride );
      ROFRS( xIsLeftRef(), Err::m_nDataNotAvailable );
      break;
    }
  default:
    {
      assert( 0 );
      return Err::m_nInvalidParameter;
    }
  }

  return Err::m_nOK;
}



Void IntraPrediction::xLoadHorPred8x8( XPel* puc, Int iStride ) 
{
  if( xIsAboveLeftRef() )
  {
    m_pucHor[0] = (puc[-iStride-1] + 2*puc[-iStride] + puc[-iStride+1] + 2) >> 2;
  }
  else
  {
    m_pucHor[0] = (3*puc[-iStride] + puc[-iStride+1] + 2) >> 2;
  }

  for( Int x = 1; x < 7; x++ )
  {
    const Int iOffset = x-iStride;
    m_pucHor[x] = (puc[iOffset-1] + 2*puc[iOffset] + puc[iOffset+1] + 2) >> 2;
  }

  if( ! xIsAboveRightRef() )
  {
    m_pucHor[7] = (puc[6-iStride] + 3*puc[7-iStride] + 2) >> 2;

    for( Int x = 8; x < 16; x++ )
    {
      m_pucHor[x] = puc[7-iStride];
    }
  }
  else
  {
    m_pucHor[7] = (puc[6-iStride] + 2*puc[7-iStride] + puc[8-iStride] + 2) >> 2;

    AOT( ! xIsAboveRef() )

    if( ! m_bSpecial)
    {
      m_pucHor[ 8] = (puc[ 7-iStride] + 2*puc[ 8-iStride] + puc[ 9-iStride] + 2) >> 2;
      m_pucHor[ 9] = (puc[ 8-iStride] + 2*puc[ 9-iStride] + puc[10-iStride] + 2) >> 2;
      m_pucHor[10] = (puc[ 9-iStride] + 2*puc[10-iStride] + puc[11-iStride] + 2) >> 2;
      m_pucHor[11] = (puc[10-iStride] + 2*puc[11-iStride] + puc[12-iStride] + 2) >> 2;
      m_pucHor[12] = (puc[11-iStride] + 2*puc[12-iStride] + puc[13-iStride] + 2) >> 2;
      m_pucHor[13] = (puc[12-iStride] + 2*puc[13-iStride] + puc[14-iStride] + 2) >> 2;
      m_pucHor[14] = (puc[13-iStride] + 2*puc[14-iStride] + puc[15-iStride] + 2) >> 2;

      m_pucHor[15] = (puc[14-iStride] + 3*puc[15-iStride] + 2) >> 2;
    }
    else
    {
      m_pucHor[ 8] = (puc[ 7-iStride] + 2*puc[ 8-iStride] + puc[ 9-iStride] + 2) >> 2;
      m_pucHor[ 9] = (puc[ 8-iStride] + 2*puc[ 9-iStride] + puc[10-iStride] + 2) >> 2;
      m_pucHor[10] = (puc[ 9-iStride] + 2*puc[10-iStride] + puc[11-iStride] + 2) >> 2;
      m_pucHor[11] = (puc[10-iStride] + 2*puc[11-iStride] + puc[8         ] + 2) >> 2;
      m_pucHor[12] = (puc[11-iStride] + 2*puc[8         ] + puc[9         ] + 2) >> 2;
      m_pucHor[13] = (puc[8         ] + 2*puc[9         ] + puc[10        ] + 2) >> 2;
      m_pucHor[14] = (puc[9         ] + 2*puc[10        ] + puc[11        ] + 2) >> 2;

      m_pucHor[15] = (puc[10] + 3*puc[11] + 2) >> 2;
    }
  }
}


Void IntraPrediction::xLoadXPred8x8( XPel* puc, Int iStride ) 
{
  if( xIsAboveLeftRef() )
  {
    if( xIsAboveRef() )
    {
      if( xIsLeftRef() )
      {
        m_pucHor[-1] = m_pucVer[-1] = (puc[-1] + 2 * puc[-iStride-1] + puc[-iStride] + 2 )>>2;
      }
      else
      {
        m_pucHor[-1] = m_pucVer[-1] = (3 * puc[-iStride-1] + puc[-iStride] + 2 )>>2;
      }
    }
    else
    {
      if( xIsLeftRef() )
      {
        m_pucHor[-1] = m_pucVer[-1] = (puc[-1] + 3 * puc[-iStride-1] )>>2;
      }
      else
      {
        m_pucHor[-1] = m_pucVer[-1] = puc[-iStride-1];
      }
    }
  }
}


Void IntraPrediction::xLoadVerPred8x8( XPel* puc, Int iStride ) 
{
  if( xIsLeftRef() )
  {
    if( xIsAboveLeftRef() )
    {
      m_pucVer[0] = (puc[-iStride-1] + 2 * puc[-1] + puc[iStride-1] + 2 )>>2;
    }
    else
    {
      m_pucVer[0] = ( 3 * puc[-1] + puc[iStride-1] + 2 )>>2;
    }

    for( Int y = 1; y < 7; y++ )
    {
      const Int iOffset = y*iStride-1;
      m_pucVer[y] = (puc[iOffset-iStride] + 2*puc[iOffset] + puc[iOffset+iStride] + 2) >> 2;
    }

    m_pucVer[7] = ( puc[6*iStride-1] + 3*puc[7*iStride-1] + 2 )>>2;
  }
}


Void IntraPrediction::xPredLum8x8Mode0Vert( XPel* puc, Int iStride )
{
  AOF_DBG( xIsAboveRef() );

  xLoadHorPred8x8( puc, iStride );

  for( Int n = 0; n < 8; n++ )
  {
    ::memcpy( puc, m_pucHor, 8*sizeof(XPel) );
    puc += iStride;
  }
}


Void IntraPrediction::xPredLum8x8Mode1Horiz( XPel* puc, Int iStride )
{
  AOF_DBG( xIsLeftRef() );

  xLoadVerPred8x8( puc, iStride );

  for( Int n = 0; n < 8; n++ )
  {
    for( Int m = 0; m < 8; m++ )
    {
      puc[m] = m_pucVer[n];
    }
    puc += iStride;
  }
}



Void IntraPrediction::xPredLum8x8Mode2Dc( XPel* puc, Int iStride ) 
{
  UInt uiDcValue = 4;

  if( ! xIsLeftRef() )
  {
    if( ! xIsAboveRef() )
    {
      uiDcValue = 0x80;
    }
    else
    {
      xLoadHorPred8x8( puc, iStride );
      for( Int x = 0; x < 8; x++ )
      {
        uiDcValue  += m_pucHor[x];
      }
      uiDcValue >>= 3;
    }
  }
  else
  {
    xLoadVerPred8x8( puc, iStride );
  
    if( ! xIsAboveRef() )
    {
      for( Int y = 0; y < 8; y++ )
      {
        uiDcValue  += m_pucVer[y];
      }
      uiDcValue >>= 3;
    }
    else
    {
      xLoadHorPred8x8( puc, iStride );
    
      uiDcValue = 8;
      for( Int x = 0; x < 8; x++ )
      {
        uiDcValue  += m_pucHor[x];
      }

      for( Int y = 0; y < 8; y++ )
      {
        uiDcValue  += m_pucVer[y];
      }
      uiDcValue >>= 4;

    }
  }

  for( Int n = 0; n < 8; n++ )
  {
    for( Int m = 0; m < 8; m++ )
    {
      puc[m] = uiDcValue;
    }
    puc += iStride;
  }
}


Void IntraPrediction::xPredLum8x8Mode3DiagDownLeft( XPel* puc, Int iStride ) // Diagonal Down Left Pred
{
  AOF_DBG( xIsAboveRef() );

  xLoadHorPred8x8( puc, iStride );

  for( Int y = 0; y < 8; y++ )
  {
    for( Int x = 0; x < 8; x++ )
    {
      puc[x] = (m_pucHor[x+y] + 2*m_pucHor[x+y+1] + m_pucHor[x+y+2] + 2 ) >> 2;
    }
    puc += iStride;
  }
  puc[7-iStride] = (m_pucHor[14] + 3*m_pucHor[15] + 2)>>2;
}


Void IntraPrediction::xPredLum8x8Mode4DiagDownRight( XPel* puc, Int iStride ) // Diagonal Down Right Pred
{
  AOF_DBG( xIsAllLeftAboveRef() );

  xLoadHorPred8x8( puc, iStride );
  xLoadVerPred8x8( puc, iStride );
  xLoadXPred8x8  ( puc, iStride );

  for( Int y = 0; y < 8; y++ )
  {
    for( Int x = 0; x < 8; x++ )
    {
      if(x > y)
      {
        const Int iOffset = x-y;
        puc[x] = (m_pucHor[iOffset-2] + 2*m_pucHor[iOffset-1] + m_pucHor[iOffset] + 2)>>2;
      }
      else if(x < y)
      {
        const Int iOffset = y-x;
        puc[x] = (m_pucVer[iOffset-2] + 2*m_pucVer[iOffset-1] + m_pucVer[iOffset] + 2)>>2;
      }
      else
      {
        puc[x] = (m_pucHor[0] + 2*m_pucVer[-1] + m_pucVer[0] + 2)>>2;
      }
    }
    puc += iStride;
  }
}



Void IntraPrediction::xPredLum8x8Mode5VertRight( XPel* puc, Int iStride )  // Vertical Right Pred
{
  AOF_DBG( xIsAllLeftAboveRef() );

  xLoadHorPred8x8( puc, iStride );
  xLoadVerPred8x8( puc, iStride );
  xLoadXPred8x8  ( puc, iStride );

  for( Int y = 0; y < 8; y++ )
  {
    for( Int x = 0; x < 8; x++ )
    {
      Int iZVR = 2 * x - y;
      if( iZVR >= 0 )
      {
        Int iOffset = x-(y>>1);
        if( iZVR & 1)
        {
          puc[x] = ( m_pucHor[iOffset-2] + 2*m_pucHor[iOffset-1] + m_pucHor[iOffset] + 2 ) >> 2;
        }
        else
        {
          puc[x] = ( m_pucHor[iOffset-1] + m_pucHor[iOffset] + 1 ) >> 1;
        }
      }
      else
      {
        if( iZVR == -1)
        {
          puc[x] = (m_pucHor[0] + 2*m_pucVer[-1] + m_pucVer[0] + 2)>>2;
        }
        else
        {
          Int iOffset = y-2*x;
          puc[x] = (m_pucVer[iOffset-1] + 2*m_pucVer[iOffset-2] + m_pucVer[iOffset-3] + 2)>>2;
        }
      }
    }
    puc += iStride;
  }
}



Void IntraPrediction::xPredLum8x8Mode6HorizDown( XPel* puc, Int iStride ) // Horizontal DownPred
{
  AOF_DBG( xIsAllLeftAboveRef() );

  xLoadXPred8x8( puc, iStride );
  xLoadHorPred8x8( puc, iStride );
  xLoadVerPred8x8( puc, iStride );

  for( Int y = 0; y < 8; y++ )
  {
    for( Int x = 0; x < 8; x++ )
    {
      Int iZHD = 2 * y - x;
      if( iZHD >= 0 )
      {
        Int iOffset = y-(x>>1);
        if( iZHD & 1)
        {
          puc[x] = ( m_pucVer[iOffset-2] + 2*m_pucVer[iOffset-1] + m_pucVer[iOffset] + 2 ) >> 2;
        }
        else
        {
          puc[x] = ( m_pucVer[iOffset-1] + m_pucVer[iOffset] + 1 ) >> 1;
        }
      }
      else
      {
        if( iZHD == -1)
        {
          puc[x] = (m_pucHor[0] + 2*m_pucVer[-1] + m_pucVer[0] + 2)>>2;
        }
        else
        {
          Int iOffset = x - 2*y;
          puc[x] = ( m_pucHor[iOffset-1] + 2*m_pucHor[iOffset-2] + m_pucHor[iOffset-3] + 2 ) >> 2;
        }
      }
    }
    puc += iStride;
  }
}


Void IntraPrediction::xPredLum8x8Mode7VertLeft( XPel* puc, Int iStride ) // Vertical Left Pred
{
  AOF_DBG( xIsAboveRef() ); //!!!

  xLoadHorPred8x8( puc, iStride );

  for( Int y = 0; y < 8; y+=2 )
  {
    for( Int x1 = 0; x1 < 8; x1++ )
    {
      Int iOffset = x1 + ( y >> 1 );
      puc[x1] = ( m_pucHor[iOffset] + m_pucHor[iOffset+1] + 1 ) >> 1;
    }
    puc += iStride;

    for( Int x2 = 0; x2 < 8; x2++ )
    {
      Int iOffset = x2 + ( y >> 1 );
      puc[x2] = ( m_pucHor[iOffset] + 2*m_pucHor[iOffset+1] + m_pucHor[iOffset+2] + 2 ) >> 2;
    }
    puc += iStride;
  }
}



Void IntraPrediction::xPredLum8x8Mode8HorizUp( XPel* puc, Int iStride ) // Horizontal Up Pred
{
  AOF_DBG( xIsLeftRef() ); //!!!

  xLoadVerPred8x8( puc, iStride );

  UInt uiEqual13 = (m_pucVer[6]+ 3*m_pucVer[7] + 2) >> 2;
  UInt uiGreater13 = m_pucVer[7];
  
  for( Int y = 0; y < 8; y++ )
  {
    for( Int x = 0; x < 8; x++ )
    {
      Int iZHU = x + 2 * y;
      if( iZHU < 13 )
      {
        Int iOffset = y+(x>>1);
        if( iZHU & 1)
        {
          puc[x] = ( m_pucVer[iOffset] + 2*m_pucVer[iOffset+1] + m_pucVer[iOffset+2] + 2 ) >> 2;
        }
        else
        {
          puc[x] = ( m_pucVer[iOffset] + m_pucVer[iOffset+1] + 1 ) >> 1;
        }
      }
      else
      {
        if( iZHU == 13 )
        {
          puc[x] = uiEqual13;
        }
        else
        {
          puc[x] = uiGreater13;
        }
      }
    }
    puc += iStride;
  }
}




H264AVC_NAMESPACE_END

⌨️ 快捷键说明

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