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

📄 uvlcwriter.cpp

📁 JMVM MPEG MVC/3DAV 测试平台 国际通用标准
💻 CPP
📖 第 1 页 / 共 5 页
字号:
      uiScanIndex+=uiStride;
  }
  while ( true );
  UInt uiSymbol = ruiNumCoefWritten - ((bSkipEob || ruiNumCoefWritten <= pauiEobShift[uiCycle]) ? 1 : 0);
  RNOK( xWriteSigRunCode( uiSymbol, m_auiBestCodeTabMap[uiCycle] ) );
  RNOK( xWriteFlag( piCoeff[pucScan[uiScanIndex]] < 0 ? 1 : 0 ) );

  // 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 )
  {
    UInt uiCountMag2;
    RNOK( xRQencodeSigMagGreater1( piCoeff, piCoeffBase, 0, uiStart, uiStop, uiCycle, pucScan, uiCountMag2, uiStride ) );
    if( uiCountMag2 == 0 )
    {
      RNOK( xWriteSigRunCode( 0, m_auiBestCodeTabMap[uiCycle] ) );
    }
  }
  return Err::m_nOK;
}

ErrVal
UvlcWriter::xRQencodeSigMagGreater1( TCoeff* piCoeff,
                                     TCoeff* piCoeffBase,
                                     UInt    uiBaseCode,
                                     UInt    uiStart,
                                     UInt    uiStop,
                                     UInt    uiVlcTable,
                                     const UChar*  pucScan,
                                     UInt&   ruiNumMagG1,
                                     UInt    uiStride )
{
  // Any magnitudes greater than one?
  ruiNumMagG1      = 0;
  UInt uiCountMag1 = 0;
  UInt uiMaxMag    = 0;
  UInt ui;
  for( ui = uiStart; ui < uiStop; ui+=uiStride )
  {
    if( piCoeff[pucScan[ui]] && ! piCoeffBase[pucScan[ui]])
    {
      uiCountMag1++;
      UInt uiAbs = ( piCoeff[pucScan[ui]] < 0 ? -piCoeff[pucScan[ui]] : piCoeff[pucScan[ui]] );
      if ( uiAbs > 1 )
      {
        ruiNumMagG1++;
      }
      if ( uiAbs > uiMaxMag )
      {
        uiMaxMag = uiAbs;
      }
    }
  }

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

  // Find optimal terminating code
  UInt uiTermSym;
  if ( uiMaxMag < 4 )
  {
    uiTermSym = 2*(ruiNumMagG1-1) + uiMaxMag%2;
  } else {
    uiTermSym = uiCountMag1*(uiMaxMag-2) + ruiNumMagG1 - 1;
  }
  RNOK( xWriteSigRunCode( uiBaseCode+uiTermSym+1, m_auiBestCodeTabMap[uiVlcTable] ) );

  UInt uiFlip      = 0;
  UInt uiRemaining = ruiNumMagG1;
  UInt uiBegin     = 0;
  UInt uiEnd       = uiCountMag1;
  UInt uiCount     = 0;
  for( ui = uiStart; ui < uiStop; ui+=uiStride )
  {
    if( piCoeff[pucScan[ui]] && ! piCoeffBase[pucScan[ui]])
    {
      // Coding last value(s) may be unnecessary
      if ( uiRemaining == uiEnd-uiCount )
        break;
      // Range check for interval splitting
      uiCount++;
      if ( uiCount <= uiBegin )
        continue;
      if ( uiCount > uiEnd )
        break;
      UInt uiAbs = ( piCoeff[pucScan[ui]] < 0 ? -piCoeff[pucScan[ui]] : piCoeff[pucScan[ui]] );
      RNOK( xWriteFlag( (uiAbs > 1) ? 1 : 0 ) );
      uiRemaining -= ( uiAbs > 1 ) ? 1-uiFlip : uiFlip;
      if ( uiRemaining == 0 )
        break;
    }
  }
  UInt uiOutstanding = ruiNumMagG1;
  Bool bSeenMaxMag   = false;
  for( ui = uiStart; ui < uiStop; ui+=uiStride )
  {
    if( !bSeenMaxMag && uiOutstanding == 1 )
      break;
    if( piCoeff[pucScan[ui]] && ! piCoeffBase[pucScan[ui]])
    {
      UInt uiAbs = ( piCoeff[pucScan[ui]] < 0 ? -piCoeff[pucScan[ui]] : piCoeff[pucScan[ui]] );
      bSeenMaxMag |= ( uiAbs == uiMaxMag );
      for ( UInt uiCutoff=1; uiAbs>uiCutoff && uiCutoff<uiMaxMag; uiCutoff++ )
      {
        RNOK( xWriteFlag( uiAbs > (uiCutoff+1) ) );
      }
      if( uiAbs > 1 )
        uiOutstanding--;
      if( uiOutstanding == 0 )
        break;
    }
  }
  return Err::m_nOK;
}

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

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

  RNOK( xRQencodeTCoeffsRef( piCoeff, piCoeffBase, pucScan, uiScanIndex ) );
  return Err::m_nOK;
}

ErrVal
UvlcWriter::RQencodeTCoeffRef_Luma ( MbDataAccess&   rcMbDataAccess,
                                      MbDataAccess&   rcMbDataAccessBase,
                                      LumaIdx         cIdx,
                                      UInt            uiScanIndex )
{
  TCoeff*       piCoeff     = rcMbDataAccess    .getMbTCoeffs().get( cIdx );
  TCoeff*       piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( cIdx );
  const UChar*  pucScan     = g_aucFrameScan;

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

  RNOK( xRQencodeTCoeffsRef( piCoeff, piCoeffBase, pucScan, uiScanIndex ) );
  return Err::m_nOK;
}

ErrVal
UvlcWriter::xRQencodeTCoeffsRef( TCoeff*       piCoeff,
                                 TCoeff*       piCoeffBase,
                                 const UChar*  pucScan,
                                 UInt          uiScanIndex )
{
  if (m_uiCodedSymbols % 3 == m_uiFragmentedSymbols) {
    UInt uiCode = 0;
    UInt uiTable = m_pSymGrp->getTable();

    for (UInt ui = 0; ui < 3; ui++) {
      UInt uiSymbol = m_auiPrescannedSymbols[m_uiCodedSymbols + ui];
      m_pSymGrp->incrementCounter(uiSymbol);
      uiCode *= 3;
      uiCode += uiSymbol;
    }

    m_pSymGrp->setCodedFlag(true);
    RNOK(writeCode( g_auiRefSymCode[uiTable][uiCode], g_auiRefSymLen[uiTable][uiCode], "" ) );
  }
  if (m_uiFragmentedSymbols) {
    m_pSymGrp->setCodedFlag(true);
  }
  m_uiCodedSymbols++;

  return Err::m_nOK;
}

ErrVal
UvlcWriter::xRQprescanTCoeffsRef( TCoeff*       piCoeff,
                                  TCoeff*       piCoeffBase,
                                  const UChar*  pucScan,
                                  UInt          uiScanIndex)
{
  UInt  uiSig = ( piCoeff[pucScan[uiScanIndex]] ? 1 : 0 );
  UChar uiSym = 0;

  if(uiSig) 
  {
    UInt uiSignBL = ( piCoeffBase[pucScan[uiScanIndex]] < 0 ? 1 : 0 );
    UInt uiSignEL = ( piCoeff    [pucScan[uiScanIndex]] < 0 ? 1 : 0 );
    UInt uiSign = ( uiSignBL ^ uiSignEL );
    uiSym = (uiSign ? 2:1);
  }

  m_auiPrescannedSymbols[m_uiRefSymbols] = uiSym;
  m_uiRefSymbols++;

  return Err::m_nOK;
}

ErrVal
UvlcWriter::RQencodeTCoeffRef_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 );

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

  RNOK( xRQencodeTCoeffsRef( piCoeff, piCoeffBase, pucScan, uiScanIndex ) );
  return Err::m_nOK;
}

ErrVal
UvlcWriter::RQencodeCycleSymbol( UInt uiCycle )
{
  RNOK( xWriteFlag( uiCycle > 0 ) );
  if ( uiCycle > 0 )
    RNOK( xWriteFlag( uiCycle - 1 ) );
  return Err::m_nOK;
}

ErrVal
UvlcWriter::xWriteGolomb(UInt uiSymbol, UInt uiK)
{
  UInt uiQ = uiSymbol / uiK;
  UInt uiR = uiSymbol - uiQ * uiK;
  UInt uiC = 0;
  UInt uiT = uiK >> 1;

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

  // Unary part
  for ( UInt ui = 0; ui < uiQ; ui++ )
  {
    RNOK( xWriteFlag( 1 ) );
  }
  RNOK( xWriteFlag( 0 ) );

  // Binary part
  if ( uiR < uiC )
  {
    RNOK( xWriteCode( uiR, uiC ) );
  } else if ( uiC > 0 ) {
    RNOK( xWriteFlag( 1 ) );
    RNOK( xWriteCode( uiR - uiC, uiC ) );
  }
  ETRACE_N;

  return Err::m_nOK;
}

UInt
UvlcWriter::peekGolomb(UInt uiSymbol, UInt uiK)
{
  UInt uiQ = uiSymbol / uiK;
  UInt uiR = uiSymbol - uiQ * uiK;
  UInt uiC = 0;
  UInt uiT = uiK >> 1;

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

  // Unary part
  uiT = uiQ + 1 + uiC;
  if ( uiR >= uiC && uiC > 0 )
  {
    uiT++;
  }

  return uiT;
}

ErrVal
UvlcWriter::RQencodeEobOffsets_Luma( UInt* pauiSeq )
{
  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;

  m_uiRefSymbols   = 0;
  m_uiCodedSymbols = 0;
  memset(m_auiPrescannedSymbols, 0, sizeof(UChar) * REFSYM_MB);
  m_uiFragmentedSymbols = 0;

  memcpy( m_auiShiftLuma, pauiSeq, sizeof(UInt)*16 );
  return xRQencodeEobOffsets(pauiSeq, 16);
}

ErrVal
UvlcWriter::RQencodeEobOffsets_Chroma( UInt* auiSeq )
{
  memcpy( m_auiShiftChroma, auiSeq, sizeof(UInt)*16 );
  m_auiShiftChroma[0] = 15;
  return xRQencodeEobOffsets(auiSeq+1, 15);
}

ErrVal
UvlcWriter::xRQencodeEobOffsets( UInt* auiSeq, UInt uiMax )
{
  UInt uiNumEnd = 0;
  for (UInt uiEc=0; uiEc<uiMax && auiSeq[uiEc] == uiMax-1 && uiNumEnd<3; uiEc++)
  {
    uiNumEnd++;
  }

  if ( uiNumEnd )
  {
    RNOK( xWriteGolomb( uiNumEnd-1, 1 ) );
  } else {
    ETRACE_T("Eob");
    RNOK( xWriteCode( 0x7, 3 ) );
    ETRACE_N;
  }
  RNOK( xWriteGolomb( auiSeq[uiNumEnd], 2 ) );
  RNOK( xEncodeMonSeq( auiSeq+uiNumEnd+1, auiSeq[uiNumEnd], uiMax-uiNumEnd-1 ) );
  ETRACE_N;
  return Err::m_nOK;
}

UInt g_auiSigRunTabCode[] = {0x01, 0x01, 0x01, 0x01, 0x00};
UInt g_auiSigRunTabCodeLen[] = {1, 2, 3, 4, 4};

ErrVal
UvlcWriter::RQencodeBestCodeTableMap( UInt* pauiTable, UInt uiMaxH )
{
  memset( m_auiBestCodeTabMap, 0, sizeof(UInt)*uiMaxH );
  Int uiW = uiMaxH-1;

  for(uiW = uiMaxH-1; uiW >= 0; uiW--)
  {
    if(pauiTable[uiW] != 0)
      break;
  }

  if(uiW < 0)
    uiW = 0;
  RNOK(xWriteCode(uiW, 4));

  for(UInt uiH = 0; uiH <= (UInt)uiW; uiH++)
  {
    m_auiBestCodeTabMap[uiH] = pauiTable[uiH];
    RNOK(xWriteCode(g_auiSigRunTabCode[pauiTable[uiH]], g_auiSigRunTabCodeLen[pauiTable[uiH]]));
  }

  return Err::m_nOK;
}

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

ErrVal
UvlcWriter::RQupdateVlcTable()
{
  m_pSymGrp->UpdateVlc();
  m_uiRefSymbols   = 0;
  m_uiCodedSymbols = 0;
  memset(m_auiPrescannedSymbols, 0, sizeof(UChar) * REFSYM_MB);
  return Err::m_nOK;
}

ErrVal 
UvlcWriter::RQcountFragmentedSymbols()
{
  if ((m_uiRefSymbols - m_uiCodedSymbols) > 0) {
    m_pSymGrp->setCodedFlag(false);
    switch (m_uiCodedSymbols%3) {
    case 0: m_uiFragmentedSymbols = 0; break;
    case 1: m_uiFragmentedSymbols = 2; break;
    case 2: m_uiFragmentedSymbols = 1; break;
    }
  }
  return Err::m_nOK;
}

ErrVal
UvlcWriter::xEncodeMonSeq ( UInt* auiSeq, UInt uiStartVal, UInt uiLen )
{
  UInt uiRun   = 0;
  UInt uiLevel = uiStartVal;
  for (UInt uiPos=0; uiPos<uiLen && uiLevel > 0; uiPos++)
  {
    if (auiSeq[uiPos] == uiLevel)
    {
      uiRun++;
    } else {
      RNOK( xWriteGolomb( uiRun, 1 ) );
      uiRun = 1;
      uiLevel--;
      while ( uiLevel > auiSeq[uiPos] )
      {
        RNOK( xWriteGolomb( 0, 1 ) );
        uiLevel--;
      }
    }
  }
  if (uiLevel > 0)
  {
    RNOK( xWriteGolomb( uiRun, 1 ) );
  }
  return Err::m_nOK;
}

ErrVal
UvlcWriter::xWriteSigRunCode ( UInt uiSymbol, UInt uiTableIdx )
{

  assert( uiTableIdx >= 0 && uiTableIdx <= 4 );
  if(uiTableIdx == 0)
  {
    // unary code 
    RNOK ( xWriteUnaryCode (uiSymbol) );
  }
  else if (uiTableIdx == 1)
  {
    RNOK ( xWriteCodeCB1 (uiSymbol) );
  }
  else if (uiTableIdx == 2)
  {
    RNOK ( xWriteCodeCB2 (uiSymbol) );
  }
  else if (uiTableIdx == 3)
  {
    if ( uiSymbol == 0 )
    {
      RNOK( xWriteFlag( 1 ) );
    }
    else
    {
      RNOK( xWriteFlag( 0 ) );
      RNOK( xWriteCodeCB2 (uiSymbol-1) );
    }
  }
  else // uiTableIdx == 4
  {
    if(uiSymbol == 0)
    {
      RNOK (xWriteFlag ( 1 ));
    }
    else
    {  
      RNOK (xWriteCodeCB1(uiSymbol+1));
    }
  }

  return Err::m_nOK;
}

ErrVal 
UvlcWriter::xWriteUnaryCode ( UInt uiSymbol )
{
  UInt uiStart = 0;
  do 
  {
    if(uiSymbol == uiStart)
    {
      RNOK( xWriteFlag (1) );
      break;
    }
    else 
    {
      RNOK( xWriteFlag (0) );
      uiStart++;
    }
  }
  while (true);
  return Err::m_nOK;
}

ErrVal 
UvlcWriter::xWriteCodeCB1 ( UInt uiSymbol )
{
  // this function writes codeword for the input symbol according to the {2, 2, 3, 3, 4, 4...} codebook
  for(UInt ui = 0; ui < uiSymbol/2; ui ++)
  {
    RNOK (xWriteFlag (0));
  }
  
  RNOK (xWriteCode((3-(uiSymbol%2)), 2)) ;

  return Err::m_nOK;
}

ErrVal
UvlcWriter::xWriteCodeCB2 ( UInt uiSymbol )
{
  // this function writes codeword for the input symbol according to the {2, 2

⌨️ 快捷键说明

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