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

📄 uvlcreader.cpp

📁 JMVM MPEG MVC/3DAV 测试平台 国际通用标准
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  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 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]] );

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

  RNOK( 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 )
{
  TCoeff*       piCoeff     = rcMbDataAccess    .getMbTCoeffs().get( cIdx );
  TCoeff*       piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
  const UChar*  pucScan     = ( eResidualMode == CHROMA_DC ? g_aucIndexChromaDCScan : g_aucFrameScan );

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

  RNOK( 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 = 0;
  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;
  RNOK( 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 = 1;
      }
    }
    if ( uiSymbol > uiOvershoot )
    {
      RNOK( xRQdecodeSigMagGreater1( piCoeff, piCoeffBase, pucScan, uiSymbol-uiOvershoot-1, uiStart, uiStop, uiStride ) );
      rbLast = true;
    } else {
      rbLast = ( uiSymbol == pauiEobShift[uiCycle]) || ( uiSymbol == 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 );
  RNOK( 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;
    RNOK( xGetSigRunCode( uiSymbol, m_auiBestCodeTab[uiCycle] ) );
    if( uiSymbol > 0 )
    {
      RNOK( 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 {
        RNOK( 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;
        RNOK( 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;
}


ErrVal
UvlcReader::xRQdecodeTCoeffsRef( TCoeff*       piCoeff,
                                 TCoeff*       piCoeffBase,
                                 const UChar*  pucScan,
                                 UInt          uiScanIndex )
{
  if(m_uiRefSymCounter == CAVLC_SYMGRP_SIZE)
  {
    UInt uiDenom = 9;
    RNOK( m_pSymGrp->xFetchSymbol( CAVLC_SYMGRP_SIZE ) );
    UInt uiCode = m_pSymGrp->GetCode();

    for(UInt ui = 0; ui < CAVLC_SYMGRP_SIZE; ui++)
    {
      UChar ucSym;
      ucSym = uiCode/uiDenom;
      m_auiSymbolBuf[ui] = ucSym;

      uiCode = (uiCode % uiDenom);
      uiDenom /= 3;
    }
    m_uiRefSymCounter = 0;
  }

  if (m_auiSymbolBuf[m_uiRefSymCounter] > 0) {
    UInt uiSymbol = m_auiSymbolBuf[m_uiRefSymCounter] - 1;
    UInt uiSignBL = ( piCoeffBase[pucScan[uiScanIndex]] < 0 ? 1 : 0 );
    UInt uiSignEL = ( uiSignBL ^ uiSymbol );
    piCoeff[pucScan[uiScanIndex]] = ( uiSignEL ? -1 : 1 );
  }
  m_uiRefSymCounter++;

  return Err::m_nOK;
}

ErrVal
UvlcReader::xGetGolomb(UInt& uiSymbol, UInt uiK)
{
  UInt uiCode;
  UInt uiR;
  UInt uiQ = 0;
  UInt uiC = 0;
  UInt uiT = uiK >> 1;

  while ( uiT > 0 )
  {
    uiC++;
    uiT >>= 1;
  }

  // Unary part
  do {
    RNOK( xGetFlag( uiCode ) );
    uiQ++;
  } while ( uiCode != 0 );
  uiQ--;

  uiSymbol = uiQ * uiK;

  if ( uiC == 0 )
  {
    return Err::m_nOK;
  }

  // Binary part
  RNOK( xGetFlag( uiCode ) );
  if ( uiCode == 0 )
  {
    if ( uiC > 1 )
    {
      RNOK( xGetCode( uiR, uiC-1 ) );
    } else {
      uiR = 0;
    }
  } else {
    RNOK( xGetCode( uiCode, uiC ) );
    uiR = uiCode + uiC;
  }
  DTRACE_N;

  uiSymbol += uiR;

  return Err::m_nOK;
}

ErrVal
UvlcReader::RQdecodeEobOffsets_Luma()
{
  RNOK( m_pSymGrp->Init() );
  m_uiCbpStat4x4[0] = m_uiCbpStat4x4[1] = 0;
  m_uiCbpStats[0][0] = m_uiCbpStats[0][1] = m_uiCbpStats[1][0] = m_uiCbpStats[1][1] = 0;

  RNOK( xRQdecodeEobOffsets( m_auiShiftLuma, 16 ) );
  return Err::m_nOK;
}

ErrVal
UvlcReader::RQdecodeEobOffsets_Chroma()
{
  m_auiShiftChroma[0] = 15;
  RNOK( xRQdecodeEobOffsets( m_auiShiftChroma+1, 15 ) );
  return Err::m_nOK;
}

ErrVal
UvlcReader::xRQdecodeEobOffsets( UInt* pauiShift, UInt uiMax )
{
  UInt uiNumEnd = 1;
  for (UInt uiEc=0; uiEc<3; uiEc++)
  {
    UInt uiCode;
    RNOK( xGetFlag( uiCode ) );
    if (uiCode)
    {
      uiNumEnd++;
    } else {
      break;
    }
  }
  if (uiNumEnd == 4)
  {
    uiNumEnd = 0;
  }
  for (UInt ui=0; ui<uiNumEnd; ui++)
  {
    pauiShift[ui] = uiMax - 1;
  }
  UInt uiLevel;
  RNOK( xGetGolomb( uiLevel, 2 ) );
  pauiShift[uiNumEnd] = uiLevel;
  RNOK( xDecodeMonSeq( pauiShift+uiNumEnd+1, uiLevel, uiMax-uiNumEnd-1 ) );

  return Err::m_nOK;
}


ErrVal
UvlcReader::RQdecodeBestCodeTableMap( UInt uiMaxH )
{
  UInt uiW = uiMaxH-1;

  memset(m_auiBestCodeTab, 0, sizeof(UInt)*uiMaxH);

  RNOK( xGetCode(uiW, 4) );

  for(UInt uiH = 0; uiH <= uiW; uiH++)
  {
    RNOK(xGetSigRunTabCode(m_auiBestCodeTab[uiH]));
  }

  return Err::m_nOK;
}

ErrVal
UvlcReader::RQvlcFlush()
{
  return Err::m_nOK;
}

ErrVal
UvlcReader::RQupdateVlcTable()
{
  m_pSymGrp->UpdateVlc();
  m_uiRefSymCounter = CAVLC_SYMGRP_SIZE;
  return Err::m_nOK;
}


ErrVal
UvlcReader::xDecodeMonSeq ( UInt* auiSeq, UInt uiStart, UInt uiLen )
{
  UInt uiPos   = 0;
  UInt uiLevel = uiStart;
  while ( uiLevel > 0 && uiPos < uiLen )
  {
    UInt uiRun;
    RNOK( xGetGolomb( uiRun, 1 ) );
    for (UInt ui=0; ui<uiRun; ui++,uiPos++)
      auiSeq[uiPos] = uiLevel;
    uiLevel--;
  }
  for (; uiPos < uiLen; uiPos++)
  {
    auiSeq[uiPos] = 0;
  }
  DTRACE_N;
  return Err::m_nOK;
}

ErrVal 
UvlcReader::xGetSigRunCode( UInt& uiVal, UInt uiCodeTab )
{
  if( uiCodeTab == 0)
  {
    RNOK(xGetUnaryCode( uiVal ));
  }
  else if( uiCodeTab == 1)
  {
    RNOK(xGetCodeCB1( uiVal ));
  }
  else if( uiCodeTab == 2)
  {
    RNOK(xGetCodeCB2( uiVal ));
  }
  else if( uiCodeTab == 3)
  {
    UInt uiCode; 

    RNOK( xGetFlag( uiCode ) );

    if(uiCode == 1)
    {
      uiVal = 0;
    }
    else
    {
      RNOK( xGetCodeCB2( uiCode ) );
      uiVal = uiCode+1;
    }
  }
  else
  {
    UInt uiCode; 

    RNOK( xGetFlag( uiCode ) );

    if(uiCode == 1)
    {
      uiVal = 0;
    }
    else
    {
      RNOK( xGetCodeCB1( uiCode ) );
      uiVal = uiCode+1;
    }
  }

  return Err::m_nOK;
}

ErrVal 
UvlcReader::xGetCodeCB1 ( UInt& uiVal )
{
  UInt uiPrefixLen = 0;
  UInt uiFlag;

  do
  {
    RNOK(xGetFlag(uiFlag));
    uiPrefixLen++;
  }
  while (uiFlag == 0);
  RNOK( xGetFlag( uiFlag) );
  
  uiVal = (2*(uiPrefixLen-1))+(1-uiFlag);
  return Err::m_nOK;
}

ErrVal 
UvlcReader::xGetCodeCB2( UInt& uiVal )
{
  UInt uiPrefixLen = 0;
  UInt uiCode;

  do
  {
    RNOK( xGetCode( uiCode, 2) );
    uiPrefixLen++;
  }
  while (uiCode == 0);

  uiVal = (3*(uiPrefixLen-1))+(3-uiCode);
  return Err::m_nOK;
}

ErrVal 
UvlcReader::xGetUnaryCode( UInt& uiVal )
{
  UInt uiCode;
  UInt uiSymbol = 0;

 

⌨️ 快捷键说明

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