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

📄 uvlcwriter.cpp

📁 jsvm开发代码包括抽样,编码,抽取,解码等一系列功能,可以做工具或研究用
💻 CPP
📖 第 1 页 / 共 5 页
字号:
{
  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 Bool    bFrame  = ( FRAME == rcMbDataAccess.getMbPicType());
  const UChar*  pucScan = (bFrame) ? g_aucFrameScan64 : g_aucFieldScan64;
  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,
                          Bool           b8x8,
                          LumaIdx        cIdx )
{
  UInt    uiSymbol  = 0;
  TCoeff* piCoeff;
  TCoeff* piBCoeff;
  const Bool    bFrame  = ( FRAME == rcMbDataAccess.getMbPicType());
  const UChar*  pucScan = (bFrame) ? g_aucFrameScan : g_aucFieldScan;
  UInt    uiOffset8x8   = (cIdx.y() % 2) * 2 + (cIdx.x() % 2);
  B8x8Idx c8x8Idx(cIdx);

  if( b8x8 )
  {
    piCoeff   = rcMbDataAccess.    getMbTCoeffs().get8x8( c8x8Idx );
    piBCoeff  = rcMbDataAccessBase.getMbTCoeffs().get8x8( c8x8Idx );
    pucScan   = g_aucFrameScan64;
  }
  else
  {
    piCoeff   = rcMbDataAccess.    getMbTCoeffs().get( cIdx );
    piBCoeff  = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
    pucScan   = g_aucFrameScan;
  }

  for( UInt ui = 0; ui < 16; ui++ )  
  {
    UInt uiScanIdx = b8x8 ? (ui * 4 + uiOffset8x8) : ui;
    if( piCoeff[ pucScan[uiScanIdx] ] && !piBCoeff[ pucScan[uiScanIdx] ] )
    {
      uiSymbol = 1;
      break;
    }
  }
  return ( uiSymbol == 1 );
}

Bool
UvlcWriter::RQencodeBCBP_4x4( MbDataAccess&  rcMbDataAccess,
                               MbDataAccess&  rcMbDataAccessBase,
                               Bool           b8x8,
                               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, b8x8, cTmp);

        rcMbDataAccess.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 ) );
     // ETRACE_N;
    } 
    else 
    {
      ANOK( xWriteCode( g_auiISymCode[2][uiCode], g_auiISymLen[2][uiCode] ) );
      //ETRACE_N;
    }
    // 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, b8x8, 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 );
  const Bool    bFrame  = ( FRAME == rcMbDataAccess.getMbPicType());
  const UChar*  pucScan = (bFrame) ? g_aucFrameScan : g_aucFieldScan;

  for( UInt ui = 1; ui < 16; ui++ )  
  {
    if( piCoeff[ pucScan[ui] ] && !piBCoeff[ pucScan[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::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 Bool    bFrame  = ( FRAME == rcMbDataAccess.getMbPicType());
  const UChar*  pucScan = (bFrame) ? g_aucFrameScan64 : g_aucFieldScan64;

  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,
                                      Bool            b8x8,
                                      LumaIdx         cIdx,
                                      UInt            uiScanIndex,
                                      Bool&           rbLast,
                                      UInt&           ruiNumCoefWritten )
{
  TCoeff*       piCoeff;
  TCoeff*       piCoeffBase;
  const Bool    bFrame  = ( FRAME == rcMbDataAccess.getMbPicType());
  const UChar*  pucScan = (bFrame) ? g_aucFrameScan : g_aucFieldScan;
  UInt          uiStart;
  UInt          uiStop;
  UInt          uiStride;

  if( b8x8 )
  {
    UInt    uiOffset8x8   = (cIdx.y() % 2) * 2 + (cIdx.x() % 2);
    B8x8Idx c8x8Idx(cIdx);

    piCoeff     = rcMbDataAccess    .getMbTCoeffs().get8x8( c8x8Idx );
    piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get8x8( c8x8Idx );
    pucScan     = g_aucFrameScan64;
    uiStart     = uiOffset8x8;
    uiStop      = 64;
    uiStride    = 4;
    uiScanIndex = uiScanIndex * 4 + uiOffset8x8;
  }
  else
  {
    piCoeff     = rcMbDataAccess    .getMbTCoeffs().get( cIdx );
    piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
    pucScan     = g_aucFrameScan;
    uiStart     = 0;
    uiStop      = 16;
    uiStride    = 1;
  }

  ROT( piCoeffBase[pucScan[uiScanIndex]] );

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

  RNOK( xRQencodeNewTCoeffs( piCoeff, piCoeffBase, uiStart, uiStop, uiStride, 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 Bool    bFrame      = ( FRAME == rcMbDataAccess.getMbPicType());
  const UChar*  pucScan     = ( eResidualMode == CHROMA_DC ? g_aucIndexChromaDCScan : ((bFrame) ? g_aucFrameScan : g_aucFieldScan));
  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 = uiStart/uiStride;
  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;

⌨️ 快捷键说明

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