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

📄 uvlcwriter.cpp

📁 jsvm开发代码包括抽样,编码,抽取,解码等一系列功能,可以做工具或研究用
💻 CPP
📖 第 1 页 / 共 5 页
字号:
      UInt uiLastPos = 1;
      for( ui = uiStart; ui < uiStop; ui+=uiStride )
      {
        if ( ! piCoeffBase[pucScan[ui]] )
          uiLastPos++;
        if( piCoeff[pucScan[ui]] && ! piCoeffBase[pucScan[ui]])
        {
          uiLastPos = 0;
        }
      }
      RNOK( xRQencodeSigMagGreater1( piCoeff, piCoeffBase, uiLastPos, uiStart, uiStop, uiCycle, pucScan, uiCountMag2, uiStride ) );

      if ( uiCountMag2 == 0 )
      {
        RNOK( xWriteSigRunCode( min(pauiEobShift[uiCycle], uiLastPos), m_auiBestCodeTabMap[uiCycle] ) );
      }
    }
    ROTRS(rbLast, Err::m_nOK);
  } else
    rbLast = false;

  //===== SIGNIFICANCE BIT ======
  UInt uiSig;
  do
  {
    ruiNumCoefWritten++;

    UInt uiLastScanPosition = uiScanIndex + uiStride;
    while (uiLastScanPosition < uiStop && piCoeffBase[pucScan[uiLastScanPosition]])
      uiLastScanPosition += uiStride;

    if (uiLastScanPosition < uiStop)
    {
      uiSig = piCoeff[pucScan[uiScanIndex] ] ? 1 : 0;
    } else {
      uiSig = 1;
    }

    if( uiSig )
    {
      break;
    }

    uiScanIndex+=uiStride;
    while (uiScanIndex < uiStop && piCoeffBase[pucScan[uiScanIndex]])
      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 ? -1*piCoeff[pucScan[ui]].getCoeff() : (Short)piCoeff[pucScan[ui]].getCoeff() );
      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 ? -1*piCoeff[pucScan[ui]].getCoeff() : (Short)piCoeff[pucScan[ui]].getCoeff() );

      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 ? -1*piCoeff[pucScan[ui]].getCoeff() : piCoeff[pucScan[ui]].getCoeff() );
      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,
                                   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;

  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,
                                     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;

  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,
                                       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) );


  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 )
  {
    ETRACE_T("num_end_vals");
    ETRACE_V(uiNumEnd-1);
    RNOK( xWriteGolomb( uiNumEnd-1, 1 ) );
  } else {
    ETRACE_T("num_end_vals");
    ETRACE_V(3);
    RNOK( xWriteCode( 0x7, 3 ) );
    ETRACE_N;
  }
  ETRACE_T("eobShiftXXX[ num_end_vals ]");
  RNOK( xWriteGolomb( auiSeq[uiNumEnd], 2 ) );
  RNOK( xEncodeMonSeq( auiSeq+uiNumEnd+1, auiSeq[uiNumEnd], uiMax-uiNumEnd-1 ) );

  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;
  DTRACE_T("num_sig_vlc_selectors");
  RNOK(xWriteCode(uiW, 4));
  ETRACE_TY("u(4) ");
  ETRACE_V(uiW);
  ETRACE_N;

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

  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 {
      ETRACE_T("eob_run");
      RNOK( xWriteGolomb( uiRun, 1 ) );
      uiRun = 1;
      uiLevel--;
      while ( uiLevel > auiSeq[uiPos] )
      {
        ETRACE_T("eob_run");
        RNOK( xWriteGolomb( 0, 1 ) );
        uiLevel--;
      }
    }
  }
  if (uiLevel > 0)
  {
    ETRACE_T("eob_run");
    RNOK( xWriteGolomb( uiRun, 1 ) );
  }
  return Err::m_nOK;
}

ErrVal
UvlcWriter::xWriteSigRunCode ( UInt uiSymbol, UInt uiTabl

⌨️ 快捷键说明

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