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

📄 uvlcwriter.cpp

📁 JMVM MPEG MVC/3DAV 测试平台 国际通用标准
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  ETRACE_T( "  PCM SAMPLES: " );

  RNOK( m_pcBitWriteBufferIf->writeAlignZero() );

  AOF_DBG( rcMbDataAccess.getMbData().isPCM() );

  rcMbDataAccess.getMbTCoeffs().setAllCoeffCount( 16 );
  Pel* pSrc = rcMbDataAccess.getMbTCoeffs().getPelBuffer();

  const UInt uiFactor = 8*8;
  const UInt uiSize   = uiFactor*2*3;
  RNOK( m_pcBitWriteBufferIf->samples( pSrc, uiSize ) );

  ETRACE_N;
  ETRACE_COUNT( uiFactor*6 );

  return Err::m_nOK;
}



ErrVal UvlcWriter::xWriteRefFrame( Bool bWriteBit, UInt uiRefFrame )
{
  ETRACE_T( "RefFrame" );

  if( bWriteBit )
  {
    RNOK( xWriteFlag( 1-uiRefFrame ) );
  }
  else
  {
    RNOK( xWriteUvlcCode( uiRefFrame ) );
  }

  ETRACE_V( uiRefFrame+1 );
  ETRACE_N;
  return Err::m_nOK;
}


ErrVal UvlcWriter::xWriteMotionPredFlag( Bool bFlag )
{
  ETRACE_T( "MotionPredFlag" );

  UInt  uiCode = ( bFlag ? 1 : 0 );
  RNOK( xWriteFlag( uiCode) );

  ETRACE_V( uiCode );
  ETRACE_N;
  return Err::m_nOK;
}


ErrVal UvlcWriter::transformSize8x8Flag( MbDataAccess& rcMbDataAccess ) 
{
  ETRACE_T( "transformSize8x8Flag:" );

  UInt  uiCode = rcMbDataAccess.getMbData().isTransformSize8x8() ? 1 : 0;
  RNOK( xWriteFlag( uiCode) );

  ETRACE_V( uiCode );
  ETRACE_N;
  return Err::m_nOK;
}





ErrVal UvlcWriter::residualBlock8x8( MbDataAccess&  rcMbDataAccess,
                                     B8x8Idx        c8x8Idx,
                                     ResidualMode   eResidualMode )
{
  ROF( eResidualMode == LUMA_SCAN );

  const UChar*  pucScan = g_aucFrameScan64;
  const TCoeff* piCoeff = rcMbDataAccess.getMbTCoeffs().get8x8( c8x8Idx );

  UInt  uiBlk;
  Int   iLevel;
  Int   iOverallRun = 0;
  UInt  uiPos       = 0;
  UInt  uiMaxPos    = 64;

  Int   aaiLevelRun     [4][32];
  Int   aiRun           [4]     = { 0, 0, 0, 0 };
  UInt  auiTrailingOnes [4]     = { 0, 0, 0, 0 };
  UInt  auiTotalRun     [4]     = { 0, 0, 0, 0 };
  UInt  auiCoeffCnt     [4]     = { 0, 0, 0, 0 };

  while( uiPos < uiMaxPos )
  {
    uiBlk = ( uiPos % 4 );

    if( ( iLevel = piCoeff[ pucScan[ uiPos++ ] ] ) )
    {
      if( abs(iLevel) == 1 )
      {
        m_uiCoeffCost         += COEFF_COST8x8[ iOverallRun ];
        auiTrailingOnes[uiBlk]++;
      }
      else
      {
        m_uiCoeffCost         += MAX_VALUE;
        auiTrailingOnes[uiBlk] = 0;
      }

      aaiLevelRun[uiBlk][auiCoeffCnt[uiBlk]]      = iLevel;
      aaiLevelRun[uiBlk][auiCoeffCnt[uiBlk]+0x10] = aiRun[uiBlk];
      auiTotalRun[uiBlk]  += aiRun[uiBlk];
      auiCoeffCnt[uiBlk]  ++;
      aiRun      [uiBlk]  = 0;
      iOverallRun         = 0;
    }
    else
    {
      aiRun[uiBlk]++;
      iOverallRun ++;
    }
  }


  //===== loop over 4x4 blocks =====
  for( uiBlk = 0; uiBlk < 4; uiBlk++ )
  {
    if( auiTrailingOnes[uiBlk] > 3 )
    {
      auiTrailingOnes[uiBlk] = 3;
    }
    B4x4Idx cIdx( c8x8Idx.b4x4() + 4*(uiBlk/2) + (uiBlk%2) );

    xPredictNonZeroCnt( rcMbDataAccess, cIdx, auiCoeffCnt[uiBlk], auiTrailingOnes[uiBlk] );
    xWriteRunLevel    ( aaiLevelRun[uiBlk],   auiCoeffCnt[uiBlk], auiTrailingOnes[uiBlk], 16, auiTotalRun[uiBlk] );
  }

  return Err::m_nOK;
}


Bool
UvlcWriter::RQencodeCBP_8x8( MbDataAccess& rcMbDataAccess,
                              MbDataAccess& rcMbDataAccessBase,
                              B8x8Idx       c8x8Idx )
{
  UInt uiSymbol  = ( ( rcMbDataAccess.getMbData().getMbCbp() >> c8x8Idx.b8x8Index() ) & 1 ? 1 : 0 );

  if( uiSymbol )
  {
    rcMbDataAccessBase.getMbData().setMbCbp( rcMbDataAccessBase.getMbData().getMbCbp() | ( 1 << c8x8Idx.b8x8Index() ) );
  }

  return ( uiSymbol == 1 );
}

Bool
UvlcWriter::RQpeekCbp4x4( MbDataAccess&  rcMbDataAccess,
                          MbDataAccess&  rcMbDataAccessBase,
                          LumaIdx        cIdx )
{
  UInt    uiSymbol  = 0;
  TCoeff* piCoeff   = rcMbDataAccess.    getMbTCoeffs().get( cIdx );
  TCoeff* piBCoeff  = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );

  for( UInt ui = 0; ui < 16; ui++ )  
  {
    if( piCoeff[ g_aucFrameScan[ui] ] && !piBCoeff[ g_aucFrameScan[ui] ] )
    {
      uiSymbol = 1;
      break;
    }
  }
  return ( uiSymbol == 1 );
}

Bool
UvlcWriter::RQencodeBCBP_4x4( MbDataAccess&  rcMbDataAccess,
                               MbDataAccess&  rcMbDataAccessBase,
                               LumaIdx        cIdx )
{
  if ( (cIdx.x() %2) == 0 && (cIdx.y() %2) == 0)
  {
    // Write
    UInt    uiCode    = 0;
    UInt    uiLen     = 0;
    UInt uiFlip = (m_uiCbpStat4x4[1] > m_uiCbpStat4x4[0]) ? 1 : 0;
    UInt uiVlc = (m_uiCbpStat4x4[uiFlip] < 2*m_uiCbpStat4x4[1-uiFlip]) ? 0 : 2;

    for( Int iY=cIdx.y(); iY<cIdx.y()+2; iY++)
      for ( Int iX=cIdx.x(); iX<cIdx.x()+2; iX++)
      {
        UInt uiSymbol = 0;
        B4x4Idx cTmp(iY*4+iX);
        uiSymbol = RQpeekCbp4x4(rcMbDataAccess, rcMbDataAccessBase, cTmp);
        rcMbDataAccessBase.getMbData().setBCBP( cTmp, uiSymbol );
        uiCode <<= 1;
        uiCode |= uiSymbol;
        uiLen++;
        m_uiCbpStat4x4[uiSymbol]++;
      }

    if (uiFlip)
      uiCode = uiCode ^ ((1<<uiLen)-1);
    if (uiVlc == 0)
    {
      ANOK( xWriteCode( uiCode, uiLen ) );
    } else {
      ANOK( xWriteCode( g_auiISymCode[2][uiCode], g_auiISymLen[2][uiCode] ) );
    }
    // Scaling
    if (m_uiCbpStat4x4[0]+m_uiCbpStat4x4[1] > 512)
    {
      m_uiCbpStat4x4[0] >>= 1;
      m_uiCbpStat4x4[1] >>= 1;
    }
    ETRACE_T( "BCBP_4x4" );
    ETRACE_V( uiCode );
    ETRACE_N;
  }
  return RQpeekCbp4x4(rcMbDataAccess, rcMbDataAccessBase, cIdx);
}

Bool
UvlcWriter::RQencodeCBP_Chroma( MbDataAccess& rcMbDataAccess,
                                 MbDataAccess& rcMbDataAccessBase )
{
  UInt  uiSymbol          = ( ( rcMbDataAccess.getMbData().getMbCbp() >> 4 ) ? 1 : 0 );

  ETRACE_T( "CBP_Chroma" );
  ETRACE_V( uiSymbol );
  ETRACE_N;

  if( uiSymbol )
  {
    rcMbDataAccessBase.getMbData().setMbCbp( rcMbDataAccessBase.getMbData().getMbCbp() | 0x10 );
  }
  return ( uiSymbol == 1 );
}

Bool
UvlcWriter::RQencodeBCBP_ChromaDC( MbDataAccess&   rcMbDataAccess,
                                    MbDataAccess&   rcMbDataAccessBase,
                                    ChromaIdx       cIdx )
{
  UInt    uiSymbol  = 0;
  TCoeff* piCoeff   = rcMbDataAccess.getMbTCoeffs().get( cIdx );
  TCoeff* piBCoeff  = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );

  for( UInt ui = 0; ui < 4; ui++ )  
  {
    if( piCoeff[ g_aucIndexChromaDCScan[ui] ] && !piBCoeff[ g_aucIndexChromaDCScan[ui] ] )
    {
      uiSymbol = 1;
      break;
    }
  }

  ANOK( xWriteFlag( uiSymbol ) );
  ETRACE_T( "BCBP_ChromaDC" );
  ETRACE_V( uiSymbol );
  ETRACE_N;

  rcMbDataAccessBase.getMbData().setBCBP( 24 + cIdx.plane(), uiSymbol );
  
  return ( uiSymbol == 1 );
}


Bool
UvlcWriter::RQencodeBCBP_ChromaAC( MbDataAccess&  rcMbDataAccess,
                                    MbDataAccess&  rcMbDataAccessBase,
                                    ChromaIdx      cIdx )
{
  UInt    uiSymbol  = 0;
  TCoeff* piCoeff   = rcMbDataAccess.getMbTCoeffs().get( cIdx );
  TCoeff* piBCoeff  = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );

  for( UInt ui = 1; ui < 16; ui++ )  
  {
    if( piCoeff[ g_aucFrameScan[ui] ] && !piBCoeff[ g_aucFrameScan[ui] ] )
    {
      uiSymbol = 1;
      break;
    }
  }

  ANOK( xWriteFlag( uiSymbol ) );
  ETRACE_T( "BCBP_ChromaAC" );
  ETRACE_V( uiSymbol );
  ETRACE_N;

  rcMbDataAccessBase.getMbData().setBCBP( 16 + cIdx, uiSymbol );
  
  return ( uiSymbol == 1 );
}

Bool
UvlcWriter::RQencodeCBP_ChromaAC( MbDataAccess& rcMbDataAccess,
                                   MbDataAccess& rcMbDataAccessBase )
{
  UInt  uiSymbol          = ( ( rcMbDataAccess.getMbData().getMbCbp() >> 5 ) ? 1 : 0 );

  ETRACE_T( "CBP_ChromaAC" );
  ETRACE_V( uiSymbol );
  ETRACE_N;

  if( uiSymbol )
  {
    rcMbDataAccessBase.getMbData().setMbCbp( ( rcMbDataAccessBase.getMbData().getMbCbp() & 0xF ) | 0x20 );
  }
  return ( uiSymbol == 1 );
}

ErrVal
UvlcWriter::RQencodeDeltaQp( MbDataAccess& rcMbDataAccess )
{
  ETRACE_T ("DQp");

  RNOK( xWriteSvlcCode( rcMbDataAccess.getDeltaQp() ) );

  ETRACE_TY ("se(v)");
  ETRACE_N;

  return Err::m_nOK;
}

ErrVal
UvlcWriter::RQencode8x8Flag( MbDataAccess& rcMbDataAccess,
                              MbDataAccess& rcMbDataAccessBase ) 
{
  UInt uiSymbol = rcMbDataAccess.getMbData().isTransformSize8x8() ? 1 : 0;
 
  RNOK( xWriteFlag( uiSymbol ) );
  ETRACE_T( "TRAFO_8x8" );
  ETRACE_V( uiSymbol );
  ETRACE_N;

  rcMbDataAccessBase.getMbData().setTransformSize8x8( rcMbDataAccess.getMbData().isTransformSize8x8() );

  return Err::m_nOK;
}

ErrVal
UvlcWriter::RQeo8b( Bool& bEob )
{
  RNOK( xWriteFlag( bEob ? 1 : 0 ) );
  return Err::m_nOK;
}

ErrVal
UvlcWriter::RQencodeNewTCoeff_8x8( MbDataAccess&   rcMbDataAccess,
                                    MbDataAccess&   rcMbDataAccessBase,
                                    B8x8Idx         c8x8Idx,
                                    UInt            uiScanIndex,
                                    Bool&           rbLast,
                                    UInt&           ruiNumCoefWritten )
{
  TCoeff*       piCoeff     = rcMbDataAccess    .getMbTCoeffs().get8x8( c8x8Idx );
  TCoeff*       piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get8x8( c8x8Idx );
  const UChar*  pucScan     = g_aucFrameScan64;

  ROT( piCoeffBase[pucScan[uiScanIndex]] );

  ETRACE_T( "LUMA_8x8_NEW" );
  ETRACE_V( c8x8Idx.b8x8Index() );
  ETRACE_V( uiScanIndex );
  ETRACE_N;

  rcMbDataAccessBase.getMbData().setBCBP( c8x8Idx.b4x4(),   1 );
  rcMbDataAccessBase.getMbData().setBCBP( c8x8Idx.b4x4()+1, 1 );
  rcMbDataAccessBase.getMbData().setBCBP( c8x8Idx.b4x4()+4, 1 );
  rcMbDataAccessBase.getMbData().setBCBP( c8x8Idx.b4x4()+5, 1 );

  UInt auiEobShift[16];
  memset(auiEobShift, 0, sizeof(UInt)*16);

  RNOK( xRQencodeNewTCoeffs( piCoeff, piCoeffBase, uiScanIndex%4, 64, 4, pucScan, uiScanIndex, auiEobShift, rbLast, ruiNumCoefWritten ) );

  return Err::m_nOK;
}

ErrVal
UvlcWriter::RQencodeNewTCoeff_Luma ( MbDataAccess&   rcMbDataAccess,
                                      MbDataAccess&   rcMbDataAccessBase,
                                      ResidualMode    eResidualMode,
                                      LumaIdx         cIdx,
                                      UInt            uiScanIndex,
                                      Bool&           rbLast,
                                      UInt&           ruiNumCoefWritten )
{
  TCoeff*       piCoeff     = rcMbDataAccess    .getMbTCoeffs().get( cIdx );
  TCoeff*       piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
  const UChar*  pucScan     = g_aucFrameScan;
  UInt          uiStart     = 0;
  UInt          uiStop      = 16;

  ROT( piCoeffBase[pucScan[uiScanIndex]] );

  ETRACE_T( "LUMA_4x4_NEW" );
  ETRACE_V( cIdx.b4x4() );
  ETRACE_V( uiScanIndex );
  ETRACE_N;

  RNOK( xRQencodeNewTCoeffs( piCoeff, piCoeffBase, uiStart, uiStop, 1, pucScan, uiScanIndex, m_auiShiftLuma, rbLast, ruiNumCoefWritten ) );
  return Err::m_nOK;
}

ErrVal
UvlcWriter::RQencodeNewTCoeff_Chroma ( MbDataAccess&   rcMbDataAccess,
                                        MbDataAccess&   rcMbDataAccessBase,
                                        ResidualMode    eResidualMode,
                                        ChromaIdx       cIdx,
                                        UInt            uiScanIndex,
                                        Bool&           rbLast,
                                        UInt&           ruiNumCoefWritten )
{
  TCoeff*       piCoeff     = rcMbDataAccess    .getMbTCoeffs().get( cIdx );
  TCoeff*       piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
  const UChar*  pucScan     = ( eResidualMode == CHROMA_DC ? g_aucIndexChromaDCScan : g_aucFrameScan );
  UInt          uiStart     = ( eResidualMode == CHROMA_AC ? 1 : 0  );
  UInt          uiStop      = ( eResidualMode == CHROMA_DC ? 4 : 16 );

  ROT( piCoeffBase[pucScan[uiScanIndex]] );

  ETRACE_T( "CHROMA_4x4_NEW" );
  ETRACE_V( cIdx );
  ETRACE_V( uiScanIndex );
  ETRACE_N;

  RNOK( xRQencodeNewTCoeffs( piCoeff, piCoeffBase, uiStart, uiStop, 1, pucScan, uiScanIndex, m_auiShiftChroma, rbLast, ruiNumCoefWritten ) );

  return Err::m_nOK;
}

ErrVal
UvlcWriter::xRQencodeNewTCoeffs( TCoeff*       piCoeff,
                                 TCoeff*       piCoeffBase,
                                 UInt          uiStart,
                                 UInt          uiStop,
                                 UInt          uiStride,
                                 const UChar*  pucScan,
                                 UInt          uiScanIndex,
                                 UInt*         pauiEobShift,
                                 Bool&         rbLast,
                                 UInt&         ruiNumCoefWritten )
{
  UInt ui;

  UInt uiCycle = 0;
  for ( ui=uiStart; ui<uiScanIndex; ui+=uiStride )
  {
    if ( !piCoeffBase[pucScan[ui]] && piCoeff[pucScan[ui]] )
    {
      uiCycle = ui/uiStride + 1;
    }
  }
  AOF( uiCycle < uiStop );
  Bool bSkipEob = !rbLast;
  ruiNumCoefWritten = 0;

  if( rbLast )
  {
    rbLast = true;
    for( ui = uiScanIndex; ui < uiStop; ui+=uiStride )
    {
      if( piCoeff[pucScan[ui]] && !piCoeffBase[pucScan[ui]] )
      {
        rbLast = false;
        break;
      }
    }
    if (rbLast) {

      UInt uiCountMag2;
      UInt uiLastPos = 1;
      for( ui = uiStart; ui < uiStop; ui+=uiStride )
      {
        if ( ! piCoeffBase[pucScan[ui]] )
          uiLastPos++;
        if( piCoeff[pucScan[ui]] && ! piCoeffBase[pucScan[ui]])
        {
          uiLastPos = 1;
        }
      }
      RNOK( xRQencodeSigMagGreater1( piCoeff, piCoeffBase, uiLastPos, uiStart, uiStop, uiCycle, pucScan, uiCountMag2, uiStride ) );

      if ( uiCountMag2 == 0 )
      {
        RNOK( xWriteSigRunCode( min(pauiEobShift[uiCycle], uiLastPos), m_auiBestCodeTabMap[uiCycle] ) );
      }
    }
    ROTRS(rbLast, Err::m_nOK);
  } else
    rbLast = false;

  //===== SIGNIFICANCE BIT ======
  UInt uiSig;
  do
  {
    ruiNumCoefWritten++;

    UInt uiLastScanPosition = uiScanIndex + uiStride;
    while (uiLastScanPosition < uiStop && piCoeffBase[pucScan[uiLastScanPosition]])
      uiLastScanPosition += uiStride;

    if (uiLastScanPosition < uiStop)
    {
      uiSig = piCoeff[pucScan[uiScanIndex] ] ? 1 : 0;
    } else {
      uiSig = 1;
    }

    if( uiSig )
    {
      break;
    }

    uiScanIndex+=uiStride;
    while (uiScanIndex < uiStop && piCoeffBase[pucScan[uiScanIndex]])

⌨️ 快捷键说明

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