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

📄 uvlcreader.cpp

📁 jsvm开发代码包括抽样,编码,抽取,解码等一系列功能,可以做工具或研究用
💻 CPP
📖 第 1 页 / 共 5 页
字号:
{  
  UInt uiTemp;
  UInt uiLength;
  UInt uiCode;
  UInt uiLevAbs;
  UInt uiSb;
  UInt uiSign;
  UInt uiAddBit;
  UInt uiOffset;
  
  UInt uiNumPrefix = 0;
  UInt uiShift     = uiVlcLength - 1;
  UInt uiEscape    = (15<<uiShift)+1;
  
  // read pre zeros
  do
  {
    RNOK( m_pcBitReadBuffer->get( uiTemp, 1 ) );
    uiNumPrefix++;
  } while ( uiTemp == 0 );

  uiLength = uiNumPrefix;
  uiCode   = 1;
  uiNumPrefix--;
  
  if (uiNumPrefix < 15)
  {
    uiLevAbs = (uiNumPrefix<<uiShift) + 1;
    
    if ( uiVlcLength-1 )
    {
      RNOK( m_pcBitReadBuffer->get( uiSb, uiVlcLength-1 ) );
      uiCode = (uiCode << (uiVlcLength-1) )| uiSb;
      uiLevAbs += uiSb;
      uiLength += (uiVlcLength-1);

    }

    // read 1 bit -> sign
    RNOK( m_pcBitReadBuffer->get( uiSign, 1 ) );
    uiCode = (uiCode << 1)| uiSign;
    uiLength++;
  }
  else // escape
  {
    uiAddBit = uiNumPrefix - 15;

    RNOK( m_pcBitReadBuffer->get( uiSb, (11+uiAddBit) ) );
    uiCode = (uiCode << (11+uiAddBit) )| uiSb;

    uiLength += (11+uiAddBit);
    uiOffset  = (2048<<uiAddBit)+uiEscape-2048;
    uiLevAbs  = uiSb + uiOffset;

    // read 1 bit -> sign
    RNOK( m_pcBitReadBuffer->get( uiSign, 1 ) );
    uiCode = (uiCode << 1)| uiSign;
    uiLength++;
  }
  
  iLevel = (uiSign) ? -(Int)uiLevAbs : (Int)uiLevAbs;

  DTRACE_POS;
  DTRACE_T( "  VLCN lev: " );
  DTRACE_CODE( iLevel );
  DTRACE_N;
  DTRACE_COUNT( uiLength );

  return Err::m_nOK;
}

Bool UvlcReader::isEndOfSlice()
{
  UInt uiEOS = ( m_uiRun > 1 ) ? 0 : !( moreRBSPData() );
  return (uiEOS == 1);
}

ErrVal UvlcReader::finishSlice( )
{
  if( m_bRunLengthCoding && m_uiRun )
  {
    DTRACE_T( "Run" );
    RNOK( xGetUvlcCode( m_uiRun ) );
    DTRACE_N;
  }

  return Err::m_nOK;
}

ErrVal UvlcReader::residualBlock8x8( MbDataAccess&  rcMbDataAccess,
                                     B8x8Idx        c8x8Idx )
{
  const Bool bFrame = ( FRAME == rcMbDataAccess.getMbPicType());
  const UChar* pucScan = (bFrame) ? g_aucFrameScan64 : g_aucFieldScan64;
  TCoeff* piCoeff = rcMbDataAccess.getMbTCoeffs().get8x8( c8x8Idx );

  UInt  uiBlk;
  UInt  uiPos;

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

  //Heiner Kirchhoffer fix  
  for ( uiBlk  = 0; uiBlk < 4; uiBlk++ )
   for ( uiPos = 0; uiPos < 32; uiPos++ )
     aaiLevelRun[uiBlk][uiPos] = 0;
  //
  
  {
    UInt uiBitPos = c8x8Idx;
    rcMbDataAccess.getMbData().setBCBP( uiBitPos,   1);
    rcMbDataAccess.getMbData().setBCBP( uiBitPos+1, 1);
    rcMbDataAccess.getMbData().setBCBP( uiBitPos+4, 1);
    rcMbDataAccess.getMbData().setBCBP( uiBitPos+5, 1);
  }
  //===== loop over 4x4 blocks =====
  for( uiBlk = 0; uiBlk < 4; uiBlk++ )
  {
    B4x4Idx cIdx( c8x8Idx.b4x4() + 4*(uiBlk/2) + (uiBlk%2) );

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

    uiPos = ((auiTotalRun[uiBlk] + auiCoeffCnt[uiBlk] - 1) << 2) + uiBlk;
    for ( Int i = (Int)auiCoeffCnt[uiBlk]; i > 0; i-- )
    {
      piCoeff[ pucScan [uiPos] ] = aaiLevelRun[uiBlk][i-1];
      uiPos -= 4;
      for ( Int j = 0; j < aaiLevelRun[uiBlk][i-1+0x10]; j++ )
      {
        piCoeff[ pucScan [uiPos] ] = 0;
        uiPos -= 4;
      }
    }

  }


  return Err::m_nOK;
}

Bool
UvlcReader::RQpeekCbp4x4(      MbDataAccess&  rcMbDataAccessBase,
                               LumaIdx        cIdx )
{
  UInt    uiSymbol  = 0;

  uiSymbol = rcMbDataAccessBase.getMbData().getBCBP( cIdx );
  
  return ( uiSymbol == 1 );
}


ErrVal
UvlcReader::RQdecodeNewTCoeff_8x8( MbDataAccess&   rcMbDataAccess,
                                   MbDataAccess&   rcMbDataAccessBase,
                                   B8x8Idx         c8x8Idx,
                                   UInt            uiScanIndex,
                                   Bool&           rbLast,
                                   UInt&           ruiNumCoefRead )
{
  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]] );

  DTRACE_T( "LUMA_8x8_NEW" );
  DTRACE_V( c8x8Idx.b8x8Index() );
  DTRACE_V( uiScanIndex );
  DTRACE_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( xRQdecodeNewTCoeffs( piCoeff, piCoeffBase, uiScanIndex%4, 64, 4, pucScan, uiScanIndex, auiEobShift, rbLast, ruiNumCoefRead ) );

  return Err::m_nOK;
}



ErrVal
UvlcReader::RQdecodeTCoeffRef_8x8( MbDataAccess&   rcMbDataAccess,
                                    MbDataAccess&   rcMbDataAccessBase,
                                    B8x8Idx         c8x8Idx,
                                  UInt            uiScanIndex,
                                  UInt            uiCtx )
{
  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;

  DTRACE_T( "LUMA_8x8_REF" );
  DTRACE_V( c8x8Idx.b8x8Index() );
  DTRACE_V( uiScanIndex );
  DTRACE_N;

  RNOKS( xRQdecodeTCoeffsRef( piCoeff, piCoeffBase, pucScan, uiScanIndex ) );

  return Err::m_nOK;
}

ErrVal
UvlcReader::RQdecodeNewTCoeff_Luma ( MbDataAccess&   rcMbDataAccess,
                                      MbDataAccess&   rcMbDataAccessBase,
                                      ResidualMode    eResidualMode,
                                      Bool            b8x8,
                                      LumaIdx         cIdx,
                                      UInt            uiScanIndex,
                                      Bool&           rbLast,
                                      UInt&           ruiNumCoefRead )
{
  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;
  }

  DTRACE_T( "LUMA_4x4_NEW" );
  DTRACE_V( cIdx.b4x4() );
  DTRACE_V( uiScanIndex );
  DTRACE_N;

  RNOKS( xRQdecodeNewTCoeffs( piCoeff, piCoeffBase, uiStart, uiStop, uiStride, pucScan, uiScanIndex, m_auiShiftLuma, rbLast, ruiNumCoefRead ) );

  return Err::m_nOK;
}


ErrVal
UvlcReader::RQdecodeTCoeffRef_Luma ( MbDataAccess&   rcMbDataAccess,
                                     MbDataAccess&   rcMbDataAccessBase,
                                     LumaIdx         cIdx,
                                     UInt            uiScanIndex,
                                     UInt            uiCtx )
{
  TCoeff*       piCoeff     = rcMbDataAccess    .getMbTCoeffs().get( cIdx );
  TCoeff*       piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
  const Bool    bFrame      = ( FRAME == rcMbDataAccess.getMbPicType());
  const UChar*  pucScan     = (bFrame) ? g_aucFrameScan : g_aucFieldScan;

  DTRACE_T( "LUMA_4x4_REF" );
  DTRACE_V( cIdx.b4x4() );
  DTRACE_V( uiScanIndex );
  DTRACE_N;

  RNOKS( xRQdecodeTCoeffsRef( piCoeff, piCoeffBase, pucScan, uiScanIndex ) );

  return Err::m_nOK;
}

ErrVal
UvlcReader::RQdecodeNewTCoeff_Chroma( MbDataAccess&   rcMbDataAccess,
                                        MbDataAccess&   rcMbDataAccessBase,
                                        ResidualMode    eResidualMode,
                                        ChromaIdx       cIdx,
                                        UInt            uiScanIndex,
                                        Bool&           rbLast,
                                        UInt&           ruiNumCoefRead )
{
  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]] );

  DTRACE_T( "CHROMA_4x4_NEW" );
  DTRACE_V( cIdx );
  DTRACE_V( uiScanIndex );
  DTRACE_N;

  RNOKS( xRQdecodeNewTCoeffs( piCoeff, piCoeffBase, uiStart, uiStop, 1, pucScan, uiScanIndex, m_auiShiftChroma, rbLast, ruiNumCoefRead ) );

  return Err::m_nOK;
}

ErrVal
UvlcReader::RQdecodeTCoeffRef_Chroma ( MbDataAccess&   rcMbDataAccess,
                                       MbDataAccess&   rcMbDataAccessBase,
                                       ResidualMode    eResidualMode,
                                       ChromaIdx       cIdx,
                                       UInt            uiScanIndex,
                                       UInt            uiCtx )
{
  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 );


  DTRACE_T( "CHROMA_4x4_REF" );
  DTRACE_V( cIdx );
  DTRACE_V( uiScanIndex );
  DTRACE_N;

  RNOKS( xRQdecodeTCoeffsRef( piCoeff, piCoeffBase, pucScan, uiScanIndex ) );

  return Err::m_nOK;
}

ErrVal
UvlcReader::xRQdecodeNewTCoeffs( TCoeff*       piCoeff,
                                  TCoeff*       piCoeffBase,
                                  UInt          uiStart,
                                  UInt          uiStop,
                                  UInt          uiStride,
                                  const UChar*  pucScan,
                                  UInt          uiScanIndex,
                                  UInt*         pauiEobShift,
                                  Bool&         rbLast,
                                  UInt&         ruiNumCoefRead )
{
  UInt ui=0;

  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 );
  DTRACE_T("NewTCoeffs-uiCycle: ");
  DTRACE_V(uiCycle);
  DTRACE_N;
  ruiNumCoefRead = 0;

  Bool bSkipEob = !rbLast;
  UInt uiSymbol;
  RNOKS( xGetSigRunCode( uiSymbol, m_auiBestCodeTab[uiCycle] ) );

  if( rbLast )
  {
    // Determine "overshoot" symbol
    UInt uiOvershoot = 1;
    for( ui = uiStart; ui < uiStop; ui+=uiStride )
    {
      if ( ! piCoeffBase[pucScan[ui]] )
        uiOvershoot++;
      if( ui < uiScanIndex && piCoeff[pucScan[ui]] && ! piCoeffBase[pucScan[ui]])
      {
        uiOvershoot = 0;
      }
    }
    if ( uiSymbol > uiOvershoot )
    {
      RNOKS( xRQdecodeSigMagGreater1( piCoeff, piCoeffBase, pucScan, uiSymbol-uiOvershoot-1, uiStart, uiStop, uiStride ) );
      rbLast = true;
    } else {
      rbLast = uiSymbol == min( pauiEobShift[uiCycle], uiOvershoot );
    }
    ROTRS(rbLast, Err::m_nOK);
  } else
    rbLast = false;

  //===== SIGNIFICANCE BIT ======
  UInt uiNumCoef = uiSymbol + ((bSkipEob || uiSymbol <= pauiEobShift[uiCycle]) ? 1 : 0);
  AOT( uiNumCoef > uiStop );
  do
  {
    ruiNumCoefRead++;

    if ( --uiNumCoef == 0 )
    {
      break;
    }

    uiScanIndex += uiStride;
    while (uiScanIndex < uiStop && piCoeffBase[pucScan[uiScanIndex]])
      uiScanIndex += uiStride;
  }
  while ( true );
  RNOKS( xGetFlag( uiSymbol ) );
  piCoeff[pucScan[uiScanIndex]] = uiSymbol ? -1 : 1;

  // Check whether any more nonzero values
  Bool bFinished = true;
  for( ui=uiScanIndex+uiStride; ui<uiStop; ui+=uiStride )
  {
    bFinished &= ( piCoeffBase[pucScan[ui]] != 0 );
    if( !bFinished )
      break;
  }
  if( bFinished )
  {
    uiSymbol = 0;
    RNOKS( xGetSigRunCode( uiSymbol, m_auiBestCodeTab[uiCycle] ) );
    if( uiSymbol > 0 )
    {
      RNOKS( xRQdecodeSigMagGreater1( piCoeff, piCoeffBase, pucScan, uiSymbol-1, uiStart, uiStop, uiStride ) );
    }
  }
  return Err::m_nOK;
}

ErrVal
UvlcReader::xRQdecodeSigMagGreater1( TCoeff* piCoeff,
                                     TCoeff* piCoeffBase,
                                     const UChar* pucScan,
                                     UInt    uiTermSym,
                                     UInt    uiStart,
                                     UInt    uiStop,
                                     UInt    uiStride )
{
  // Find optimal terminating code
  UInt ui;
  UInt uiCountMag1 = 0;
  for (ui=uiStart; ui<uiStop; ui+=uiStride )
  {
    if ( !piCoeffBase[pucScan[ui]] && piCoeff[pucScan[ui]] )
    {
      uiCountMag1++;
    }
  }
  UInt uiMaxMag;
  UInt uiCountMag2;
  if ( uiTermSym < uiCountMag1*2 )
  {
    uiMaxMag    = (uiTermSym % 2) + 2;
    uiCountMag2 = (uiTermSym / 2) + 1;
  } else {
    uiMaxMag    = (uiTermSym / uiCountMag1) + 2;
    uiCountMag2 = (uiTermSym % uiCountMag1) + 1;
  }
  UInt auiRemMag[16];
  ::memset(auiRemMag, 0x0, 16*sizeof(UInt));
  UInt uiFlip      = 0;
  UInt uiRemaining = uiCountMag2;
  UInt uiEnd       = uiCountMag1;
  UInt uiCount     = 0;
  for (ui=uiStart; ui<uiStop; ui+=uiStride )
  {
    if( piCoeff[pucScan[ui]] && ! piCoeffBase[pucScan[ui]])
    {
      if( uiRemaining+uiCount == uiEnd )
      {
        auiRemMag[ui/uiStride] = 1-uiFlip;
        uiRemaining--;
      } else {
        RNOKS( xGetFlag( auiRemMag[ui/uiStride] ) );
        uiRemaining -= auiRemMag[ui/uiStride] ? 1-uiFlip : uiFlip;
      }
      if( uiRemaining == 0 )
        break;
      uiCount++;
    }
  }

  UInt uiOutstanding = uiCountMag2;
  Bool bSeenMaxMag   = false;
  for(ui = uiStart; ui < uiStop; ui+=uiStride )
  {
    if( !bSeenMaxMag && uiOutstanding == 1 )
      break;
    if( auiRemMag[ui/uiStride] )
    {
      UInt uiBit;
      UInt uiSymbol = 0;
      for ( UInt uiCutoff=1; uiCutoff<uiMaxMag; uiCutoff++ )
      {
        auiRemMag[ui/uiStride] = 0;
        RNOKS( xGetFlag( uiBit ) );
        if( uiBit )
          uiSymbol++;
        else
          break;
      }
      uiSymbol += 2;
      piCoeff[pucScan[ui]] = (piCoeff[pucScan[ui]] > 0) ? (Int)uiSymbol : -(Int)uiSymbol;
      bSeenMaxMag |= ( uiSymbol == uiMaxMag );
      uiOutstanding--;
      if( uiOutstanding == 0 )
        break;
    }
  }
  for (ui=uiStart; ui<uiStop; ui+=uiStride )
  {
    if ( auiRemMag[ui/uiStride] )
    {
      piCoeff[pucScan[ui]] = ( piCoeff[pucScan[ui]] > 0 ) ? (Int)uiMaxMag : -(Int)uiMaxMag;
    }
  }

  return Err::m_nOK;

⌨️ 快捷键说明

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