intraprediction.cpp

来自「JMVM MPEG MVC/3DAV 测试平台 国际通用标准」· C++ 代码 · 共 1,979 行 · 第 1/4 页

CPP
1,979
字号
  ::memcpy( puc, puc - iStride, 4*sizeof(XPel) );
  puc += iStride;

  ::memcpy( puc, puc - iStride, 4*sizeof(XPel) );
  puc += iStride;

  ::memcpy( puc, puc - iStride, 4*sizeof(XPel) );
}


Void IntraPrediction::xPredMode1Horiz( XPel* puc, Int iStride ) // Horizontal prediction
{
  // If E,F,G,H are inside the picture
  AOF( xIsLeftRef() );

  Int n;

  for( n=0; n<4; n++ )  puc[n] = puc[n-1];
  puc += iStride;

  for( n=0; n<4; n++ )  puc[n] = puc[n-1];
  puc += iStride;

  for( n=0; n<4; n++ )  puc[n] = puc[n-1];
  puc += iStride;

  for( n=0; n<4; n++ )  puc[n] = puc[n-1];
}


Void IntraPrediction::xPredMode2Dc( XPel* puc, Int iStride ) // DC Prediction
{
  UInt uiDcValue;

  if( ! xIsLeftRef() )
  {
    if( ! xIsAboveRef() )
    {
      uiDcValue = 0x80;
    }
    else
    {
//      uiDcValue = (A + B + C + D + 2) >> 2;
      uiDcValue   = puc[-iStride];
      uiDcValue  += puc[1-iStride];
      uiDcValue  += puc[2-iStride];
      uiDcValue  += puc[3-iStride];
      uiDcValue  += 2;
      uiDcValue >>= 2;
    }
  }
  else
  {
    if( ! xIsAboveRef() )
    {
//      uiDcValue = (I + J + K + L + 2) >> 2;
      uiDcValue   = puc[-1];
      uiDcValue  += puc[iStride-1];
      uiDcValue  += puc[2*iStride-1];
      uiDcValue  += puc[3*iStride-1];
      uiDcValue  += 2;
      uiDcValue >>= 2;
    }
    else
    {
//      uiDcValue = ( A + B + C + D + I + J + K + L + 4) >> 3;
      uiDcValue   = puc[-iStride];
      uiDcValue  += puc[1-iStride];
      uiDcValue  += puc[2-iStride];
      uiDcValue  += puc[3-iStride];
      uiDcValue  += puc[-1];
      uiDcValue  += puc[iStride-1];
      uiDcValue  += puc[2*iStride-1];
      uiDcValue  += puc[3*iStride-1];
      uiDcValue  += 4;
      uiDcValue >>= 3;
    }
  }

  Int n;

  for( n=0; n<4; n++ )  puc[n] = uiDcValue;
  puc += iStride;

  for( n=0; n<4; n++ )  puc[n] = uiDcValue;
  puc += iStride;

  for( n=0; n<4; n++ )  puc[n] = uiDcValue;
  puc += iStride;

  for( n=0; n<4; n++ )  puc[n] = uiDcValue;
}



Void IntraPrediction::xPredMode3DiagDownLeft( XPel* puc, Int iStride ) // Diagonal Down Left Pred
{
  AOF( xIsAboveRef() );
  UInt A,B,C,D;
  UInt E,F,G,H;

  xLoadPredictorsABCD ( puc, iStride, A, B, C, D );
  xLoadPredictorsEFGH ( puc, iStride, E, F, G, H );

  puc[0]                                                         = (A + 2*B + C + 2) >> 2;
  puc[1] = puc[iStride+0]                                        = (B + 2*C + D + 2) >> 2;
  puc[2] = puc[iStride+1] = puc[2*iStride+0]                     = (C + 2*D + E + 2) >> 2;
  puc[3] = puc[iStride+2] = puc[2*iStride+1] = puc[3*iStride+0]  = (D + 2*E + F + 2) >> 2;
           puc[iStride+3] = puc[2*iStride+2] = puc[3*iStride+1]  = (E + 2*F + G + 2) >> 2;
                            puc[2*iStride+3] = puc[3*iStride+2]  = (F + 2*G + H + 2) >> 2;
                                               puc[3*iStride+3]  = (G + 2*H + H + 2) >> 2;
}


Void IntraPrediction::xPredMode4DiagDownRight( XPel* puc, Int iStride ) // Diagonal Down Right Pred
{
  AOF( xIsAllLeftAboveRef() )
  UInt A,B,C,D;
  UInt I,J,K,L;
  UInt X;

  xLoadPredictorsABCD ( puc, iStride, A, B, C, D );
  xLoadPredictorsIJKL ( puc, iStride, I, J, K, L );
  xLoadPredictorsX    ( puc, iStride, X );

  puc[3]                                                        = (B + 2 * C + D + 2)/4;
  puc[2] = puc[iStride+3]                                       = (A + 2 * B + C + 2)/4;
  puc[1] = puc[iStride+2] = puc[2*iStride+3]                    = (X + 2 * A + B + 2)/4;
  puc[0] = puc[iStride+1] = puc[2*iStride+2] = puc[3*iStride+3] = (A + 2 * X + I + 2)/4;
           puc[iStride+0] = puc[2*iStride+1] = puc[3*iStride+2] = (X + 2 * I + J + 2)/4;
                            puc[2*iStride+0] = puc[3*iStride+1] = (I + 2 * J + K + 2)/4;
                                               puc[3*iStride+0] = (J + 2 * K + L + 2)/4;
}


Void IntraPrediction::xPredMode5VertRight( XPel* puc, Int iStride )  // Vertical Right Pred
{
  AOF( xIsAllLeftAboveRef() )

  UInt A,B,C,D;
  UInt I,J,K,L;
  UInt X;

  xLoadPredictorsABCD ( puc, iStride, A, B, C, D );
  xLoadPredictorsIJKL ( puc, iStride, I, J, K, L );
  xLoadPredictorsX    ( puc, iStride, X );


  puc[0]         = puc[2*iStride+1] = (X + A + 1) >> 1;
  puc[1]         = puc[2*iStride+2] = (A + B + 1) >> 1;
  puc[2]         = puc[2*iStride+3] = (B + C + 1) >> 1;
  puc[3]                            = (C + D + 1) >> 1;

  puc[iStride+0] = puc[3*iStride+1] = (I + 2*X + A + 2) >> 2;
  puc[iStride+1] = puc[3*iStride+2] = (X + 2*A + B + 2) >> 2;
  puc[iStride+2] = puc[3*iStride+3] = (A + 2*B + C + 2) >> 2;
  puc[iStride+3]                    = (B + 2*C + D + 2) >> 2;

  puc[2*iStride] = (X + 2*I + J + 2) >> 2;
  puc[3*iStride] = (I + 2*J + K + 2) >> 2;
}



Void IntraPrediction::xPredMode6HorizDown( XPel* puc, Int iStride ) // Horizontal DownPred
{
  AOF( xIsAllLeftAboveRef() )

  UInt A,B,C,D;
  UInt I,J,K,L;
  UInt X;

  xLoadPredictorsABCD ( puc, iStride, A, B, C, D );
  xLoadPredictorsIJKL ( puc, iStride, I, J, K, L );
  xLoadPredictorsX    ( puc, iStride, X );

  puc[0] = puc[iStride+2] = (X + I + 1) >> 1;
  puc[1] = puc[iStride+3] = (I + 2*X + A + 2) >> 2;
  puc[2] =                  (X + 2*A + B + 2) >> 2;
  puc[3] =                  (A + 2*B + C + 2) >> 2;

  puc[iStride+0]   = puc[2*iStride+2] = (I + J + 1) >> 1;
  puc[iStride+1]   = puc[2*iStride+3] = (X + 2*I + J + 2) >> 2;
  puc[2*iStride+0] = puc[3*iStride+2] = (J + K + 1) >> 1;
  puc[2*iStride+1] = puc[3*iStride+3] = (I + 2*J + K + 2) >> 2;

  puc[3*iStride+0] = (K + L + 1) >> 1;
  puc[3*iStride+1] = (J + 2*K + L + 2) >> 2;

}


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

  UInt A,B,C,D;
  UInt E,F,G,H;

  xLoadPredictorsABCD ( puc, iStride, A, B, C, D );
  xLoadPredictorsEFGH ( puc, iStride, E, F, G, H );

  puc[0] = (A + B + 1) >> 1;

  puc[1] = puc[2*iStride+0] = (B + C + 1) >> 1;
  puc[2] = puc[2*iStride+1] = (C + D + 1) >> 1;
  puc[3] = puc[2*iStride+2] = (D + E + 1) >> 1;
           puc[2*iStride+3] = (E + F + 1) >> 1;

  puc[iStride+0]                    = (A + 2*B + C + 2) >> 2;
  puc[iStride+1] = puc[3*iStride+0] = (B + 2*C + D + 2) >> 2;
  puc[iStride+2] = puc[3*iStride+1] = (C + 2*D + E + 2) >> 2;
  puc[iStride+3] = puc[3*iStride+2] = (D + 2*E + F + 2) >> 2;
                   puc[3*iStride+3] = (E + 2*F + G + 2) >> 2;
}


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

  UInt I,J,K,L;

  xLoadPredictorsIJKL ( puc, iStride, I, J, K, L );

  puc[0] = (I + J + 1) >> 1;
  puc[1] = (I + 2*J + K + 2) >> 2;
  puc[2] = puc[iStride + 0] = (J + K + 1) >> 1;
  puc[3] = puc[iStride + 1] = (J + 2*K + L + 2) >> 2;

  puc[iStride + 2] = puc[2*iStride + 0] = (K + L + 1) >> 1;
  puc[iStride + 3] = puc[2*iStride + 1] = (K + 2*L + L + 2) >> 2;

  puc[2*iStride + 2] = puc[3*iStride + 0] =
  puc[2*iStride + 3] = puc[3*iStride + 1] =
  puc[3*iStride + 2] = puc[3*iStride + 3] = L;
}


Void IntraPrediction::xPred8x8IMode2Vert( XPel* puc, Int iStride ) // vertical
{
  AOF( xIsAboveRef() );

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


Void IntraPrediction::xPred8x8IMode1Hori( XPel* puc, Int iStride ) // horizontal
{
  AOF( xIsLeftRef() );

  for( UInt n = 0; n < 8; n++ )
  {
    for( UInt m = 0; m < 8; m++ )
    {
      puc[m] = puc[m-1];
    }
    puc += iStride;
  }
}


Void IntraPrediction::xPred8x8IMode0DC( XPel* puc, Int iStride ) // DC prediction
{
  if( ! xIsLeftRef() )
  {
    if( ! xIsAboveRef() )
    {
      xChroma0PredAllOutside( puc, iStride );
    }
    else
    {
      xChroma0PredNoLeftRef( puc, iStride );
    }
  }
  else
  {
    if( ! xIsAboveRef() )
    {
      xChroma0PredNoAboveRef( puc, iStride );
    }
    else
    {
      xChroma0PredAllInside( puc, iStride );
    }
  }
}


Void IntraPrediction::xPred8x8IMode3Plane( XPel* puc, Int iStride ) // plane prediction
{
  Int n, m;
  Int iH = 0;
  Int iV = 0;

  AOF( xIsAllLeftAboveRef() );

  XPel* pucDes = puc;

  puc += 3 - iStride;
  for( n = 1; n < 5; n++ )
  {
    iH += n * (puc[n] - puc[-n]);
  }

  puc += (iStride << 2) - 4;
  for( m = iStride, n = 1; n < 5; n++, m += iStride)
  {
    iV += n * (puc[m] - puc[-m]);
  }
  puc -= 3 * iStride - 1;

  Int iB =  (17 * iH + 16) >> 5;
  Int iC =  (17 * iV + 16) >> 5;
  Int iA = 16 * (puc[(iStride << 3) - (iStride + 1)] + puc[ 7 - iStride ]);
  Int x, y;

  for( y = 0; y < 8; y++ )
  {
    Int iYSum = iA + (y-3) * iC + 16;
    for( x = 0; x < 8; x++ )
    {
      pucDes[x] = gClip((iYSum + (x-3) * iB) >> 5);
    }
    pucDes += iStride;
  }
}




ErrVal IntraPrediction::predictLumaBlock( XPel* puc, Int iStride, UInt uiPredMode, LumaIdx cIdx )
{
  m_uiAvailable = xGetAvailableMask( cIdx );

  switch( uiPredMode )
  {
  case 0:
    {
      xPredMode0Vert( puc, iStride );
      break;
    }
  case 1:
    {
      xPredMode1Horiz( puc, iStride );
      break;
    }
  case 2:
    {
      xPredMode2Dc( puc, iStride );
      break;
    }
  case 3:
    {
      xPredMode3DiagDownLeft( puc, iStride );
      break;
    }
  case 4:
    {
      xPredMode4DiagDownRight( puc, iStride );
      break;
    }
  case 5:
    {
      xPredMode5VertRight( puc, iStride );
      break;
    }
  case 6:
    {
      xPredMode6HorizDown( puc, iStride );
      break;
    }
  case 7:
    {
      xPredMode7VertLeft( puc, iStride );
      break;
    }
  case 8:
    {
      xPredMode8HorizUp( puc, iStride );
      break;
    }
  default:
    {
      assert( 0 );
      return Err::m_nERR;
    }
  }

  return Err::m_nOK;
}




ErrVal IntraPrediction::predictLumaMb( XPel* puc, Int iStride, UInt uiPredMode )
{
  m_uiAvailable = ( m_uiAvailableMaskMb >> 4 ) | m_uiAvailableMaskMb;

  switch( uiPredMode & 0xf )
  {
  case 0:
    {
      xPred16x16IMode0Vert  ( puc, iStride );
      break;
    }
  case 1:
    {
      xPred16x16IMode1Hori  ( puc, iStride );
      break;
    }
  case 2:
    {
      xPred16x16IMode2DC    ( puc, iStride );
      break;
    }
  case 3:
    {
      xPred16x16IMode3Plane ( puc, iStride );
      break;
    }
  default:
    {
      assert( 0 );
      return Err::m_nERR;
    }
  }
  return Err::m_nOK;
}



ErrVal IntraPrediction::predictChromaBlock( XPel* pucCb, XPel* pucCr, Int iStride, UInt uiPredMode )
{
  m_uiAvailable = ( m_uiAvailableMaskMb >> 4 ) | m_uiAvailableMaskMb;

  switch( uiPredMode )
  {
  case 0:
    {
      xPred8x8IMode0DC    ( pucCb, iStride );
      xPred8x8IMode0DC    ( pucCr, iStride );
      break;
    }
  case 1:
    {
      xPred8x8IMode1Hori  ( pucCb, iStride );
      xPred8x8IMode1Hori  ( pucCr, iStride );
      break;
    }
  case 2:
    {
      xPred8x8IMode2Vert  ( pucCb, iStride );
      xPred8x8IMode2Vert  ( pucCr, iStride );
      break;
    }
  case 3:
    {
      xPred8x8IMode3Plane ( pucCb, iStride );
      xPred8x8IMode3Plane ( pucCr, iStride );
      break;
    }
  default:
    {
      assert( 0 );
      return Err::m_nERR;
    }
  }

  return Err::m_nOK;
}









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;

⌨️ 快捷键说明

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