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

📄 mbdecoder.cpp

📁 JMVM MPEG MVC/3DAV 测试平台 国际通用标准
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    RNOK( m_pcMotionCompensation->calculateMb ( rcMbDataAccess, true ) );
    rcRecYuvBuffer.setZero();
  }
  else
  {
    RNOK( m_pcMotionCompensation->compensateMbMotionSkip( rcMbDataAccess, &rcRecYuvBuffer, false ) );	
  }

  rcPredIntYuvMbBuffer.loadBuffer( &rcRecYuvBuffer );
    
  MbTransformCoeffs& rcCoeffs = m_cTCoeffs;

  m_pcTransform->setClipMode( false );
  
  if( rcMbDataAccess.getMbData().isTransformSize8x8() )
  {
    for( B8x8Idx cIdx8x8; cIdx8x8.isLegal(); cIdx8x8++ )
    {
      if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx8x8 ) )
      {
        RNOK( m_pcTransform->invTransform8x8Blk( rcResIntYuvMbBuffer.getYBlk( cIdx8x8 ),
                                                 rcResIntYuvMbBuffer.getLStride(),
                                                 rcCoeffs.get8x8(cIdx8x8) ) );
      }
    }
  }
  else
  {
    for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
    {
      if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx ) )
      {
        RNOK( m_pcTransform->invTransform4x4Blk( rcResIntYuvMbBuffer.getYBlk( cIdx ),
                                                 rcResIntYuvMbBuffer.getLStride(),
                                                 rcCoeffs.get(cIdx) ) );
      }
    }
  }

  UInt uiChromaCbp = rcMbDataAccess.getMbData().getCbpChroma4x4();
  IntYuvMbBuffer cPredBuffer;
  RNOK( xDecodeChroma( rcMbDataAccess, rcResIntYuvMbBuffer, cPredBuffer, uiChromaCbp, false ) );
  m_pcTransform->setClipMode( true );
 
  IntYuvMbBuffer  cIntYuvMbBuffer;
  cIntYuvMbBuffer. loadLuma      ( rcPredIntYuvMbBuffer );
  cIntYuvMbBuffer. loadChroma    ( rcPredIntYuvMbBuffer );  
  cIntYuvMbBuffer. add           ( rcResIntYuvMbBuffer );
  rcRecYuvBuffer.  loadBufferClip( &cIntYuvMbBuffer );

  return Err::m_nOK;
}
#endif  // JVT-W081


ErrVal MbDecoder::xDecodeChroma( MbDataAccess& rcMbDataAccess, YuvMbBuffer& rcRecYuvBuffer, UInt uiChromaCbp, Bool bPredChroma )
{
  MbTransformCoeffs& rcCoeffs = m_cTCoeffs;

  Pel*  pucCb   = rcRecYuvBuffer.getMbCbAddr();
  Pel*  pucCr   = rcRecYuvBuffer.getMbCrAddr();
  Int   iStride = rcRecYuvBuffer.getCStride();

  if( bPredChroma )
  {
    RNOK( m_pcIntraPrediction->predictChromaBlock( pucCb, pucCr, iStride, rcMbDataAccess.getMbData().getChromaPredMode() ) );
  }

  ROTRS( 0 == uiChromaCbp, Err::m_nOK );

  Int                 iScale;
  Bool                bIntra    = rcMbDataAccess.getMbData().isIntra();
  UInt                uiUScalId = ( bIntra ? 1 : 4 );
  UInt                uiVScalId = ( bIntra ? 2 : 5 );
  const UChar*        pucScaleU = rcMbDataAccess.getSH().getScalingMatrix( uiUScalId );
  const UChar*        pucScaleV = rcMbDataAccess.getSH().getScalingMatrix( uiVScalId );

  // scaling has already been performed on DC coefficients
  iScale = ( pucScaleU ? pucScaleU[0] : 16 );
  m_pcTransform->invTransformChromaDc( rcCoeffs.get( CIdx(0) ), iScale );     
  iScale = ( pucScaleV ? pucScaleV[0] : 16 );
  m_pcTransform->invTransformChromaDc( rcCoeffs.get( CIdx(4) ), iScale );

  RNOK( m_pcTransform->invTransformChromaBlocks( pucCb, iStride, rcCoeffs.get( CIdx(0) ) ) );
  RNOK( m_pcTransform->invTransformChromaBlocks( pucCr, iStride, rcCoeffs.get( CIdx(4) ) ) );

  return Err::m_nOK;
}



ErrVal MbDecoder::xDecodeMbIntra4x4( MbDataAccess& rcMbDataAccess, 
                                     IntYuvMbBuffer& cYuvMbBuffer,
                                     IntYuvMbBuffer&  rcPredBuffer )
{
  Int  iStride = cYuvMbBuffer.getLStride();

  MbTransformCoeffs& rcCoeffs = m_cTCoeffs;

  for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
  {
    rcMbDataAccess.getMbData().intraPredMode( cIdx ) = rcMbDataAccess.decodeIntraPredMode( cIdx );

    XPel* puc = cYuvMbBuffer.getYBlk( cIdx );

    UInt uiPredMode = rcMbDataAccess.getMbData().intraPredMode( cIdx );
    RNOK( m_pcIntraPrediction->predictLumaBlock( puc, iStride, uiPredMode, cIdx ) );

    rcPredBuffer.loadLuma( cYuvMbBuffer, cIdx );

    if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx ) )
    {
      RNOK( m_pcTransform->invTransform4x4Blk( puc, iStride, rcCoeffs.get( cIdx ) ) );
    }
  }

  UInt uiChromaCbp = rcMbDataAccess.getMbData().getCbpChroma4x4();
  RNOK( xDecodeChroma( rcMbDataAccess, cYuvMbBuffer, rcPredBuffer, uiChromaCbp, true ) );

  return Err::m_nOK;
}




ErrVal MbDecoder::xDecodeMbIntra8x8( MbDataAccess&   rcMbDataAccess,
                                     IntYuvMbBuffer& cYuvMbBuffer,
                                     IntYuvMbBuffer& rcPredBuffer )
{
  Int  iStride = cYuvMbBuffer.getLStride();

  MbTransformCoeffs& rcCoeffs = m_cTCoeffs;

  for( B8x8Idx cIdx; cIdx.isLegal(); cIdx++ )
  {
    {
      Int iPredMode = rcMbDataAccess.decodeIntraPredMode( cIdx );
      for( S4x4Idx cIdx4x4( cIdx ); cIdx4x4.isLegal( cIdx ); cIdx4x4++ )
      {
        rcMbDataAccess.getMbData().intraPredMode( cIdx4x4 ) = iPredMode;
      }
    }

    XPel* puc = cYuvMbBuffer.getYBlk( cIdx );

    const UInt uiPredMode = rcMbDataAccess.getMbData().intraPredMode( cIdx );

    RNOK( m_pcIntraPrediction->predictLuma8x8Block( puc, iStride, uiPredMode, cIdx ) );

    rcPredBuffer.loadLuma( cYuvMbBuffer, cIdx );

    if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx ) )
    {
      RNOK( m_pcTransform->invTransform8x8Blk( puc, iStride, rcCoeffs.get8x8( cIdx ) ) );
    }

  }

  UInt uiChromaCbp = rcMbDataAccess.getMbData().getCbpChroma4x4();
  RNOK( xDecodeChroma( rcMbDataAccess, cYuvMbBuffer, rcPredBuffer, uiChromaCbp, true ) );

  return Err::m_nOK;
}



ErrVal MbDecoder::xDecodeMbIntraBL( MbDataAccess&     rcMbDataAccess,
                                    IntYuvPicBuffer*  pcRecYuvBuffer,
                                    IntYuvMbBuffer&   rcPredBuffer,
                                    IntYuvPicBuffer*  pcBaseYuvBuffer )
{
  IntYuvMbBuffer      cYuvMbBuffer;
  MbTransformCoeffs&  rcCoeffs = m_cTCoeffs;

  cYuvMbBuffer.loadBuffer ( pcBaseYuvBuffer );
  rcPredBuffer.loadLuma   ( cYuvMbBuffer );
  rcPredBuffer.loadChroma ( cYuvMbBuffer );

  if( rcMbDataAccess.getMbData().isTransformSize8x8() )
  {
    for( B8x8Idx cIdx; cIdx.isLegal(); cIdx++ )
    {
      if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx ) )
      {
        RNOK( m_pcTransform->invTransform8x8Blk( cYuvMbBuffer.getYBlk( cIdx ),
                                                 cYuvMbBuffer.getLStride(),
                                                 rcCoeffs.get8x8(cIdx) ) );
      }
    }
  }
  else
  {
    for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
    {
      if( rcMbDataAccess.getMbData().is4x4BlkCoded( cIdx ) )
      {
        RNOK( m_pcTransform->invTransform4x4Blk( cYuvMbBuffer.getYBlk( cIdx ),
                                                 cYuvMbBuffer.getLStride(),
                                                 rcCoeffs.get(cIdx) ) );
      }
    }
  }

  UInt uiChromaCbp = rcMbDataAccess.getMbData().getCbpChroma4x4();
  RNOK( xDecodeChroma( rcMbDataAccess, cYuvMbBuffer, rcPredBuffer, uiChromaCbp, false ) );

  pcRecYuvBuffer->loadBuffer( &cYuvMbBuffer );

  return Err::m_nOK;
}



ErrVal MbDecoder::xDecodeMbIntra16x16( MbDataAccess&    rcMbDataAccess,
                                       IntYuvMbBuffer&  cYuvMbBuffer,
                                       IntYuvMbBuffer& rcPredBuffer )
{
  Int  iStride = cYuvMbBuffer.getLStride();

  RNOK( m_pcIntraPrediction->predictLumaMb( cYuvMbBuffer.getMbLumAddr(), iStride, rcMbDataAccess.getMbData().intraPredMode() ) );

  rcPredBuffer.loadLuma( cYuvMbBuffer );

  MbTransformCoeffs& rcCoeffs = m_cTCoeffs;

  Quantizer           cQuantizer;   cQuantizer.setQp    ( rcMbDataAccess, false );
  const QpParameter   rcLQp       = cQuantizer.getLumaQp();
  Int                 iScaleY     = g_aaiDequantCoef[rcLQp.rem()][0] << rcLQp.per();
  const UChar*        pucScaleY   = rcMbDataAccess.getSH().getScalingMatrix( 0 );

  if( pucScaleY )
  {
    iScaleY  *= pucScaleY[0];
    iScaleY >>= 4;
  }

  RNOK( m_pcTransform->invTransformDcCoeff( rcCoeffs.get( B4x4Idx(0) ), iScaleY ) );

  for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
  {
    RNOK( m_pcTransform->invTransform4x4Blk( cYuvMbBuffer.getYBlk( cIdx ), iStride, rcCoeffs.get( cIdx ) ) );
  }

  UInt uiChromaCbp = rcMbDataAccess.getMbData().getCbpChroma16x16();
  RNOK( xDecodeChroma( rcMbDataAccess, cYuvMbBuffer, rcPredBuffer, uiChromaCbp, true ) );

  return Err::m_nOK;
}


ErrVal MbDecoder::xDecodeChroma( MbDataAccess&    rcMbDataAccess,
                                 IntYuvMbBuffer&  rcRecYuvBuffer,
                                 IntYuvMbBuffer&  rcPredMbBuffer,
                                 UInt             uiChromaCbp,
                                 Bool             bPredChroma )
{
  MbTransformCoeffs& rcCoeffs = m_cTCoeffs;

  XPel* pucCb   = rcRecYuvBuffer.getMbCbAddr();
  XPel* pucCr   = rcRecYuvBuffer.getMbCrAddr();
  Int   iStride = rcRecYuvBuffer.getCStride();

  if( bPredChroma )
  {
    RNOK( m_pcIntraPrediction->predictChromaBlock( pucCb, pucCr, iStride, rcMbDataAccess.getMbData().getChromaPredMode() ) );
    rcPredMbBuffer.loadChroma( rcRecYuvBuffer );
  }

  ROTRS( 0 == uiChromaCbp, Err::m_nOK );
  
  Int                 iScale;
  Bool                bIntra    = rcMbDataAccess.getMbData().isIntra();
  UInt                uiUScalId = ( bIntra ? 1 : 4 );
  UInt                uiVScalId = ( bIntra ? 2 : 5 );
  const UChar*        pucScaleU = rcMbDataAccess.getSH().getScalingMatrix( uiUScalId );
  const UChar*        pucScaleV = rcMbDataAccess.getSH().getScalingMatrix( uiVScalId );

  // scaling has already been performed on DC coefficients
  iScale = ( pucScaleU ? pucScaleU[0] : 16 );
  m_pcTransform->invTransformChromaDc( rcCoeffs.get( CIdx(0) ), iScale );     
  iScale = ( pucScaleV ? pucScaleV[0] : 16 );
  m_pcTransform->invTransformChromaDc( rcCoeffs.get( CIdx(4) ), iScale );

  RNOK( m_pcTransform->invTransformChromaBlocks( pucCb, iStride, rcCoeffs.get( CIdx(0) ) ) );
  RNOK( m_pcTransform->invTransformChromaBlocks( pucCr, iStride, rcCoeffs.get( CIdx(4) ) ) );

  return Err::m_nOK;
}




ErrVal
MbDecoder::xScale4x4Block( TCoeff*            piCoeff,
                           const UChar*       pucScale,
                           UInt               uiStart,
                           const QpParameter& rcQP )
{
  if( pucScale )
  {
    Int iAdd = ( rcQP.per() <= 3 ? ( 1 << ( 3 - rcQP.per() ) ) : 0 );
    
    for( UInt ui = uiStart; ui < 16; ui++ )
    {
      piCoeff[ui] = ( ( piCoeff[ui] * g_aaiDequantCoef[rcQP.rem()][ui] * pucScale[ui] + iAdd ) << rcQP.per() ) >> 4;
    }
  }
  else
  {
    for( UInt ui = uiStart; ui < 16; ui++ )
    {
      piCoeff[ui] *= ( g_aaiDequantCoef[rcQP.rem()][ui] << rcQP.per() );
    }
  }

  return Err::m_nOK;
}


ErrVal
MbDecoder::xScale8x8Block( TCoeff*            piCoeff,
                           const UChar*       pucScale,
                           const QpParameter& rcQP )
{
  Int iAdd = ( rcQP.per() <= 5 ? ( 1 << ( 5 - rcQP.per() ) ) : 0 );

  if( pucScale )
  {
    for( UInt ui = 0; ui < 64; ui++ )
    {
      piCoeff[ui] = ( ( piCoeff[ui] * g_aaiDequantCoef64[rcQP.rem()][ui] * pucScale[ui] + iAdd ) << rcQP.per() ) >> 6;
    }
  }
  else
  {
    for( UInt ui = 0; ui < 64; ui++ )
    {
      piCoeff[ui] = ( ( piCoeff[ui] * g_aaiDequantCoef64[rcQP.rem()][ui] * 16 + iAdd ) << rcQP.per() ) >> 6;
    }
  }

  return Err::m_nOK;
}


ErrVal
MbDecoder::xScaleTCoeffs( MbDataAccess& rcMbDataAccess )
{
  Quantizer cQuantizer;
  cQuantizer.setQp( rcMbDataAccess, false );
  
  const QpParameter&  cLQp      = cQuantizer.getLumaQp  ();
  const QpParameter&  cCQp      = cQuantizer.getChromaQp();
  Bool                bIntra    = rcMbDataAccess.getMbData().isIntra();
  Bool                b8x8      = rcMbDataAccess.getMbData().isTransformSize8x8();
  Bool                b16x16    = rcMbDataAccess.getMbData().isIntra16x16();
  UInt                uiYScalId = ( bIntra ? ( b8x8 && !b16x16 ? 6 : 0 ) : ( b8x8 ? 7 : 3 ) );
  UInt                uiUScalId = ( bIntra ? 1 : 4 );
  UInt                uiVScalId = ( bIntra ? 2 : 5 );
  const UChar*        pucScaleY = rcMbDataAccess.getSH().getScalingMatrix( uiYScalId );
  const UChar*        pucScaleU = rcMbDataAccess.getSH().getScalingMatrix( uiUScalId );
  const UChar*        pucScaleV = rcMbDataAccess.getSH().getScalingMatrix( uiVScalId );

  //===== copy all coefficients =====
  MbTransformCoeffs& rcTCoeffs = m_cTCoeffs;
  rcTCoeffs.copyFrom( rcMbDataAccess.getMbTCoeffs() );

  //===== luma =====
  if( b16x16 )
  {
    //===== INTRA_16x16 =====
    for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
    {
      RNOK( xScale4x4Block( rcTCoeffs.get( cIdx ), pucScaleY, 1, cLQp ) );
    }
  }
  else if( b8x8 )
  {
    //===== 8x8 BLOCKS =====
    for( B8x8Idx cIdx; cIdx.isLegal(); cIdx++ )
    {
      RNOK( xScale8x8Block( rcTCoeffs.get8x8( cIdx ), pucScaleY, cLQp ) );
    }
  }
  else
  {
    //===== 4x4 BLOCKS =====
    for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
    {
      RNOK( xScale4x4Block( rcTCoeffs.get( cIdx ), pucScaleY, 0, cLQp ) );
    }
  }

⌨️ 快捷键说明

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