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

📄 cabacwriter.cpp

📁 jsvm开发代码包括抽样,编码,抽取,解码等一系列功能,可以做工具或研究用
💻 CPP
📖 第 1 页 / 共 5 页
字号:

ErrVal CabacWriter::xWriteMvd( MbDataAccess& rcMbDataAccess, Mv cMv, LumaIdx cIdx, ListIdx eLstIdx )
{
  Mv    cMvA;
  Mv    cMvB;

  rcMbDataAccess.getMvdAbove( cMvA, eLstIdx, cIdx );
  rcMbDataAccess.getMvdLeft ( cMvB, eLstIdx, cIdx );

  Short sHor = cMv.getHor();
  Short sVer = cMv.getVer();

  RNOK( xWriteMvdComponent( sHor, cMvA.getAbsHor() + cMvB.getAbsHor(), 0 ) );

  ETRACE_T( "Mvd: x" );
  ETRACE_TY( "ae(v)" );
  ETRACE_V( sHor );
  ETRACE_T( " above " );
  ETRACE_V( cMvA.getHor() );
  ETRACE_T( " left " );
  ETRACE_V( cMvB.getHor() );
  ETRACE_N;

  RNOK( xWriteMvdComponent( sVer, cMvA.getAbsVer() + cMvB.getAbsVer(), 5 ) );

  ETRACE_T( "Mvd: y" );
  ETRACE_TY( "ae(v)" );
  ETRACE_V( sVer );
  ETRACE_T( " above " );
  ETRACE_V( cMvA.getVer() );
  ETRACE_T( " left " );
  ETRACE_V( cMvB.getVer() );
  ETRACE_N;

  return Err::m_nOK;
}




ErrVal CabacWriter::intraPredModeChroma( MbDataAccess& rcMbDataAccess )
{
  UInt uiCtx = rcMbDataAccess.getCtxChromaPredMode();
  UInt uiIntraPredModeChroma = rcMbDataAccess.getMbData().getChromaPredMode();

  if( 0 == uiIntraPredModeChroma )
  {
    CabaEncoder::writeSymbol( 0, m_cChromaPredCCModel.get( 0, uiCtx ) );
  }
  else
  {
    CabaEncoder::writeSymbol( 1, m_cChromaPredCCModel.get( 0, uiCtx ) );

    CabaEncoder::writeUnaryMaxSymbol( uiIntraPredModeChroma - 1,
                                          m_cChromaPredCCModel.get( 0 ) + 3,
                                          0, 2 );

  }

  ETRACE_T( "IntraPredModeChroma" );
  ETRACE_TY( "ae(v)" );
  ETRACE_CODE( uiIntraPredModeChroma );
  ETRACE_N;

  return Err::m_nOK;
}

ErrVal CabacWriter::intraPredModeLuma( MbDataAccess& rcMbDataAccess, LumaIdx cIdx )
{
  Int iIntraPredModeLuma = rcMbDataAccess.encodeIntraPredMode(cIdx);

  RNOK( CabaEncoder::writeSymbol( iIntraPredModeLuma >= 0 ? 0 : 1, m_cIntraPredCCModel.get( 0, 0 ) ) );
  if( iIntraPredModeLuma >= 0 )
  {
    RNOK( CabaEncoder::writeSymbol( (iIntraPredModeLuma & 0x01)     , m_cIntraPredCCModel.get( 0, 1 ) ) );
    RNOK( CabaEncoder::writeSymbol( (iIntraPredModeLuma & 0x02) >> 1, m_cIntraPredCCModel.get( 0, 1 ) ) );
    RNOK( CabaEncoder::writeSymbol( (iIntraPredModeLuma & 0x04) >> 2, m_cIntraPredCCModel.get( 0, 1 ) ) );
  }

  ETRACE_T( "IntraPredModeLuma" );
  ETRACE_TY( "ae(v)" );
  ETRACE_CODE( iIntraPredModeLuma );
  ETRACE_N;

  return Err::m_nOK;
}



ErrVal CabacWriter::cbp( MbDataAccess& rcMbDataAccess )
{
  UInt uiCbp = rcMbDataAccess.getMbData().getMbCbp();
  UInt uiCtx = 0, a, b;

  a = rcMbDataAccess.getLeftLumaCbp ( B4x4Idx( 0 ) );
  b = rcMbDataAccess.getAboveLumaCbp( B4x4Idx( 0 ) ) << 1;

  RNOK( CabaEncoder::writeSymbol( uiCbp & 1, m_cCbpCCModel.get( uiCtx, 3 - (a + b) ) ) );

  a = uiCbp & 1;
  b = rcMbDataAccess.getAboveLumaCbp( B4x4Idx( 2 ) ) << 1;

  RNOK( CabaEncoder::writeSymbol( (uiCbp>>1) & 1, m_cCbpCCModel.get( uiCtx, 3 - (a + b) ) ) );

  a = rcMbDataAccess.getLeftLumaCbp ( B4x4Idx( 8 ) );
  b = (uiCbp  << 1) & 2;

  RNOK( CabaEncoder::writeSymbol( (uiCbp>>2) & 1, m_cCbpCCModel.get( uiCtx, 3 - (a + b) ) ) );

  a = ( uiCbp >> 2 ) & 1;
  b = uiCbp & 2;

  RNOK( CabaEncoder::writeSymbol( (uiCbp>>3) & 1, m_cCbpCCModel.get( uiCtx, 3 - (a + b) ) ) );


  uiCtx = 1;

  UInt  uiLeftChromaCbp   = rcMbDataAccess.getLeftChromaCbp ();
  UInt  uiAboveChromaCbp  = rcMbDataAccess.getAboveChromaCbp();

  a = uiLeftChromaCbp  > 0 ? 1 : 0;
  b = uiAboveChromaCbp > 0 ? 2 : 0;

  UInt uiBit = ( 0 == (uiCbp>>4)) ? 0 : 1;

  RNOK( CabaEncoder::writeSymbol( uiBit, m_cCbpCCModel.get( uiCtx, a + b ) ) );

  if( uiBit )
  {
    a = uiLeftChromaCbp  > 1 ? 1 : 0;
    b = uiAboveChromaCbp > 1 ? 2 : 0;

    uiBit = ( 0 == (uiCbp>>5)) ? 0 : 1;

    RNOK( CabaEncoder::writeSymbol( uiBit, m_cCbpCCModel.get( ++uiCtx, a + b ) ) );
  }

  if( !uiCbp )
  {
    m_uiLastDQpNonZero = 0;
  }

  AOF_DBG( 48 >= uiCbp );

  ETRACE_T( "Cbp" );
  ETRACE_TY( "ae(v)" );
  ETRACE_CODE( uiCbp );
  ETRACE_N;

  return Err::m_nOK;
}



ErrVal CabacWriter::residualBlock( MbDataAccess&  rcMbDataAccess,
                                   LumaIdx        cIdx,
                                   ResidualMode   eResidualMode )
{
  const Bool bFrame    = ( FRAME == rcMbDataAccess.getMbPicType());
  const UChar* pucScan = ( eResidualMode==LUMA_I16_DC ? ((bFrame) ? g_aucLumaFrameDCScan : g_aucLumaFieldDCScan) : ((bFrame) ? g_aucFrameScan : g_aucFieldScan) );

  ETRACE_T( "LUMA:" );
  ETRACE_V( cIdx );
  ETRACE_N;

  TCoeff* piCoeff = rcMbDataAccess.getMbTCoeffs().get( cIdx );

  UInt uiNumSig = xGetNumberOfSigCoeff( piCoeff, eResidualMode, pucScan );

  RNOK( xWriteBCbp( rcMbDataAccess, uiNumSig, eResidualMode, cIdx ) );

  if( uiNumSig )
  {
    RNOK( xWriteCoeff( uiNumSig, piCoeff, eResidualMode, pucScan, bFrame ) );
  }
  return Err::m_nOK;
}




ErrVal CabacWriter::residualBlock( MbDataAccess&  rcMbDataAccess,
                                   ChromaIdx      cIdx,
                                   ResidualMode   eResidualMode )
{
  const Bool bFrame    = ( FRAME == rcMbDataAccess.getMbPicType());
  const UChar* pucScan;

  switch( eResidualMode )
  {
  case CHROMA_DC:
    {
      ETRACE_T( "CHROMA_DC:" );
      pucScan = g_aucIndexChromaDCScan;
      break;
    }
  case CHROMA_AC:
    {
      ETRACE_T( "CHROMA_AC:" );
      pucScan = (bFrame ? g_aucFrameScan : g_aucFieldScan);
      break;
    }
  default:
    {
      AF();
      return Err::m_nERR;
    }
  }
  ETRACE_V( cIdx );
  ETRACE_N;

  TCoeff* piCoeff = rcMbDataAccess.getMbTCoeffs().get( cIdx );

  UInt uiNumSig = xGetNumberOfSigCoeff( piCoeff, eResidualMode, pucScan );

  RNOK( xWriteBCbp( rcMbDataAccess, uiNumSig, eResidualMode, cIdx ) );

  if( uiNumSig )
  {
    RNOK( xWriteCoeff( uiNumSig, piCoeff, eResidualMode, pucScan, bFrame ) );
  }

  return Err::m_nOK;
}




ErrVal CabacWriter::xWriteBCbp( MbDataAccess& rcMbDataAccess, UInt uiNumSig, ResidualMode eResidualMode, LumaIdx cIdx )
{
  UInt uiBitPos = 0;

  if( LUMA_SCAN == eResidualMode || LUMA_I16_AC == eResidualMode )
  {
    uiBitPos = cIdx;
  }
  else if( LUMA_I16_DC == eResidualMode )
  {
    uiBitPos = 26;
  }
  else
  {
    // full stop
    AF();
  }

  UInt uiCtx      = rcMbDataAccess.getCtxCodedBlockBit( uiBitPos );
  UInt uiBit      = uiNumSig ? 1 : 0;

  RNOK( CabaEncoder::writeSymbol( uiBit, m_cBCbpCCModel.get( type2ctx1[ eResidualMode ], uiCtx) ) );

  rcMbDataAccess.getMbData().setBCBP( uiBitPos, uiBit);

  return Err::m_nOK;
}


ErrVal CabacWriter::xWriteBCbp( MbDataAccess& rcMbDataAccess, UInt uiNumSig, ResidualMode eResidualMode, ChromaIdx cIdx )
{
  UInt uiBitPos;

  if( CHROMA_AC == eResidualMode )
  {
    uiBitPos = 16 + cIdx;
  }
  else if( CHROMA_DC == eResidualMode )
  {
    uiBitPos = 24 + cIdx.plane();
  }
  else
  {
    AF();
    return Err::m_nERR;
  }

  UInt uiCtx      = rcMbDataAccess.getCtxCodedBlockBit( uiBitPos );
  UInt uiBit      = uiNumSig ? 1 : 0;

  RNOK( CabaEncoder::writeSymbol( uiBit, m_cBCbpCCModel.get( type2ctx1[ eResidualMode ], uiCtx) ) );

  rcMbDataAccess.getMbData().setBCBP( uiBitPos, uiBit);

  return Err::m_nOK;
}


UInt CabacWriter::xGetNumberOfSigCoeff( TCoeff* piCoeff, ResidualMode eResidualMode, const UChar* pucScan )
{
  UInt uiNumSig = 0;
  UInt uiStart  = ( CHROMA_AC == eResidualMode || LUMA_I16_AC == eResidualMode )  ? 1 : 0 ;
  UInt uiStop   = ( CHROMA_DC == eResidualMode                                 ) ? 4 : 16;

  for( UInt ui = uiStart; ui < uiStop; ui++ )
  {
    if( piCoeff[ pucScan[ ui ] ] )
    {
      uiNumSig++;
    }
  }

  return uiNumSig;
}


ErrVal CabacWriter::xWriteCoeff( UInt         uiNumSig,
                                 TCoeff*      piCoeff,
                                 ResidualMode eResidualMode,
                                 const UChar* pucScan, 
                                 Bool         bFrame )
{
  CabacContextModel2DBuffer&  rcMapCCModel  = (bFrame ? m_cMapCCModel : m_cFldMapCCModel );
  CabacContextModel2DBuffer&  rcLastCCModel = (bFrame ? m_cLastCCModel: m_cFldLastCCModel);
  UInt uiCodedSig = 0;
  UInt uiStart    = 0;
  UInt uiStop     = 15;

  if( CHROMA_AC == eResidualMode || LUMA_I16_AC == eResidualMode )
  {
    uiStart = 1;
  }
  if( CHROMA_DC == eResidualMode )
  {
    uiStop = 3;
  }
  else if( LUMA_I16_DC == eResidualMode)
  {
    uiStop = 15;
  }


  UInt ui;
  //----- encode significance map -----
  for( ui = uiStart; ui < uiStop; ui++ ) // if last coeff is reached, it has to be significant
  {
    UInt uiSig = piCoeff[ pucScan[ ui ] ] ? 1 : 0;
    RNOK( CabaEncoder::writeSymbol( uiSig, rcMapCCModel.get( type2ctx2 [eResidualMode], ui ) ) );

    if( uiSig )
    {
      UInt uiLast = (++uiCodedSig == uiNumSig ? 1 : 0);

      RNOK( CabaEncoder::writeSymbol( uiLast, rcLastCCModel.get( type2ctx2 [eResidualMode], ui ) ) );

      if( uiLast)
      {
        break;
      }
    }
  }

  int   c1 = 1;
  int   c2 = 0;
  //----- encode significant coefficients -----
  ui++;
  while( (ui--) != uiStart )
  {
    UInt  uiAbs, uiSign;
    Int   iCoeff = piCoeff[ pucScan[ ui ] ];

    if( iCoeff )
    {
      if( iCoeff > 0) { uiAbs = static_cast<UInt>( iCoeff);  uiSign = 0; }
      else            { uiAbs = static_cast<UInt>(-iCoeff);  uiSign = 1; }

      UInt uiCtx    = min (c1, 4);
      UInt uiSymbol = uiAbs > 1 ? 1 : 0;
      RNOK( CabaEncoder::writeSymbol( uiSymbol, m_cOneCCModel.get( type2ctx1 [eResidualMode], uiCtx ) ) );

      if( uiSymbol )
      {
        uiCtx  = min (c2,4);
        uiAbs -= 2;
        c1     = 0;
        c2++;
        RNOK( CabaEncoder::writeExGolombLevel( uiAbs, m_cAbsCCModel.get( type2ctx1 [eResidualMode], uiCtx ) ) );
      }
      else if( c1 )
      {
        c1++;
      }
      RNOK( CabaEncoder::writeEPSymbol( uiSign ) );
    }
  }

  return Err::m_nOK;
}


ErrVal CabacWriter::terminatingBit ( UInt uiIsLast )
{
  RNOK( CabaEncoder::writeTerminatingBit( uiIsLast ) );

  ETRACE_T( "EOS" );
  ETRACE_CODE( uiIsLast );
  ETRACE_N;

  return Err::m_nOK;
}


ErrVal CabacWriter::deltaQp( MbDataAccess& rcMbDataAccess )
{
  Int   iDQp  = rcMbDataAccess.getDeltaQp();
  UInt  uiCtx = m_uiLastDQpNonZero;
  UInt  uiDQp = ( iDQp ? 1 : 0 );

  RNOK( CabaEncoder::writeSymbol( uiDQp, m_cDeltaQpCCModel.get( 0, uiCtx ) ) );

⌨️ 快捷键说明

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