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

📄 uvlcwriter.cpp

📁 JVT-Z203_jsvm.rar
💻 CPP
📖 第 1 页 / 共 4 页
字号:

  Int   iLevel;
  Int   iRun      = 0;

  UInt uiPos    = uiStart;
  UInt uiMaxPos = uiStop;

  switch( eResidualMode )
  {
  case LUMA_I16_DC:
    {
      pucScan = (bFrame) ? g_aucLumaFrameDCScan : g_aucLumaFieldDCScan;
      ROF( uiStart == 0 && uiStop == 16 );
      break;
    }
  case LUMA_I16_AC:
    {
      pucScan = (bFrame) ? g_aucFrameScan : g_aucFieldScan;
      ROF( uiStart == 0 && uiStop == 16 );
      uiPos=1;
      break;
    }
  case LUMA_SCAN:
    {
      pucScan = (bFrame) ? g_aucFrameScan : g_aucFieldScan;
      break;
    }
  default:
    return Err::m_nERR;
  }

  Int   aiLevelRun[32];
  UInt  uiTrailingOnes = 0;
  UInt  uiTotalRun     = 0;
  UInt  uiCoeffCnt     = 0;

  while( uiPos < uiMaxPos )
  {
    if( ( iLevel = piCoeff[ pucScan [ uiPos++ ] ]) )
    {
      if( abs(iLevel) == 1 )
      {
        m_uiCoeffCost += COEFF_COST[iRun];
        uiTrailingOnes++;
      }
      else
      {
        m_uiCoeffCost += MAX_VALUE;                // set high cost, shall not be discarded
        uiTrailingOnes = 0;
      }

      aiLevelRun[uiCoeffCnt]      = iLevel;
      aiLevelRun[uiCoeffCnt+0x10] = iRun;
      uiTotalRun += iRun;
      uiCoeffCnt++;
      iRun = 0;
    }
    else
    {
      iRun++;
    }
  }

  if( uiTrailingOnes > 3 )
  {
    uiTrailingOnes = 3;
  }

  Bool bDefaultScanIdx = ( uiStart == 0 && uiStop == 16 );

  switch( eResidualMode )
  {
  case LUMA_I16_DC:
    {
      ETRACE_T( "Luma:" );
      ETRACE_V( cIdx );
      ETRACE_N;
      RNOK( xPredictNonZeroCnt( rcMbDataAccess, cIdx, uiCoeffCnt, uiTrailingOnes, uiStart, uiStop ) );
      RNOK( xWriteRunLevel( aiLevelRun, uiCoeffCnt, uiTrailingOnes, 16, uiTotalRun, rcMbDataAccess, bDefaultScanIdx ) );
      break;
    }
  case LUMA_I16_AC:
    {
      ETRACE_T( "Luma:" );
      ETRACE_V( cIdx );
      ETRACE_N;
      RNOK( xPredictNonZeroCnt( rcMbDataAccess, cIdx, uiCoeffCnt, uiTrailingOnes, uiStart, uiStop ) );
      RNOK( xWriteRunLevel( aiLevelRun, uiCoeffCnt, uiTrailingOnes, uiStop-max(1,uiStart), uiTotalRun, rcMbDataAccess, bDefaultScanIdx ) );
      break;
    }
  case LUMA_SCAN:
    {
      ETRACE_T( "Luma:" );
      ETRACE_V( cIdx );
      ETRACE_N;
      RNOK( xPredictNonZeroCnt( rcMbDataAccess, cIdx, uiCoeffCnt, uiTrailingOnes, uiStart, uiStop ) );
      RNOK( xWriteRunLevel( aiLevelRun, uiCoeffCnt, uiTrailingOnes, uiStop-uiStart, uiTotalRun, rcMbDataAccess, bDefaultScanIdx ) );
      // this is useful only in AR_FGS
      rcMbDataAccess.getMbData().setBCBP( cIdx, uiCoeffCnt != 0, true);
      break;
    }
  default:
    {
      AF();
    }
  }

  return Err::m_nOK;
}


ErrVal UvlcWriter::residualBlock( MbDataAccess& rcMbDataAccess,
                                  ChromaIdx     cIdx,
                                  ResidualMode  eResidualMode,
                                  UInt          uiStart,
                                  UInt          uiStop )
{

  TCoeff* piCoeff = rcMbDataAccess.getMbTCoeffs().get( cIdx );
  const Bool    bFrame  = ( FRAME == rcMbDataAccess.getMbPicType());
  const UChar*  pucScan;
  Int           iRun = 0, iLevel;
  UInt          uiPos, uiMaxPos;

  switch( eResidualMode )
  {
  case CHROMA_DC:
    {
      pucScan = g_aucIndexChromaDCScan;
      ROF( uiStart == 0 );
      uiPos=0;  uiMaxPos= 4;
      break;
    }
  case CHROMA_AC:
    {
      pucScan = (bFrame) ? g_aucFrameScan : g_aucFieldScan;
      ROT( uiStop <= 1 );
      uiPos    = max( 1, uiStart);
      uiMaxPos = uiStop;
      break;
    }
  default:
    return Err::m_nERR;
  }

  Int aiLevelRun[32];

  UInt uiTrailingOnes = 0;
  UInt uiTotalRun     = 0;
  UInt uiCoeffCnt     = 0;

  while( uiPos < uiMaxPos )
  {
    if( ( iLevel = piCoeff[ pucScan [ uiPos++ ] ]) )
    {
      if( abs(iLevel) == 1 )
      {
        m_uiCoeffCost += COEFF_COST[iRun];
        uiTrailingOnes++;
      }
      else
      {
        m_uiCoeffCost += MAX_VALUE;                // set high cost, shall not be discarded
        uiTrailingOnes = 0;
      }

      aiLevelRun[uiCoeffCnt]      = iLevel;
      aiLevelRun[uiCoeffCnt+0x10] = iRun;
      uiTotalRun += iRun;
      uiCoeffCnt++;
      iRun = 0;
    }
    else
    {
      iRun++;
    }
  }

  if( uiTrailingOnes > 3 )
  {
    uiTrailingOnes = 3;
  }

  Bool bDefaultScanIdx = ( uiStart == 0 && uiStop == 16 );

  switch( eResidualMode )
  {
  case CHROMA_AC:
    {
      ETRACE_T( "CHROMA_AC:" );
      ETRACE_V( cIdx );
      ETRACE_N;
      RNOK( xPredictNonZeroCnt( rcMbDataAccess, cIdx, uiCoeffCnt, uiTrailingOnes, uiStart, uiStop ) );
      RNOK( xWriteRunLevel( aiLevelRun, uiCoeffCnt, uiTrailingOnes, uiStop - max( 1, uiStart), uiTotalRun, rcMbDataAccess, bDefaultScanIdx ) );
      // this is useful only in AR_FGS
      rcMbDataAccess.getMbData().setBCBP( 16 + cIdx, uiCoeffCnt != 0, true);
      break;
    }
  case CHROMA_DC:
    {
      ETRACE_T( "CHROMA_DC:" );
      ETRACE_V( cIdx );
      ETRACE_N;
      RNOK( xWriteTrailingOnes4( uiCoeffCnt, uiTrailingOnes ) );
      RNOK( xWriteRunLevel( aiLevelRun, uiCoeffCnt, uiTrailingOnes, 4, uiTotalRun, rcMbDataAccess, bDefaultScanIdx ) );
      // this is useful only in AR_FGS
      rcMbDataAccess.getMbData().setBCBP( 24 + cIdx.plane(), uiCoeffCnt != 0, true);
      break;
    }
  default:
    {
      AF();
    }
  }

  return Err::m_nOK;
}


ErrVal UvlcWriter::deltaQp( MbDataAccess& rcMbDataAccess )
{
  ETRACE_T ("DQp");

  RNOK( xWriteSvlcCode( rcMbDataAccess.getDeltaQp() ) );

  ETRACE_TY ("se(v)");
  ETRACE_N;
  return Err::m_nOK;
}


ErrVal UvlcWriter::finishSlice()
{
  if( m_bRunLengthCoding && m_uiRun )
  {
    ETRACE_T( "Run" );
    RNOK( xWriteUvlcCode( m_uiRun ) );
    ETRACE_N;
  }

  return Err::m_nOK;
}


ErrVal UvlcWriter::xPredictNonZeroCnt( MbDataAccess& rcMbDataAccess, ChromaIdx cIdx, UInt uiCoeffCount, UInt uiTrailingOnes, UInt uiStart, UInt uiStop )
{
  UInt uiCoeffCountCtx = rcMbDataAccess.getCtxCoeffCount( cIdx, uiStart, uiStop );

  if( uiStart != 0 || uiStop != 16 )
  {
    // Re-pack VLC matrix
    // NB: This only needs to be done once at the start of the slice.
    
    UInt uiMapIdx, ui, uj;
    UChar aucCwMapTO16[4][17];
    UInt uiBw     = uiStop-uiStart;
    UInt uiXdim   = min(16,uiBw)+1;
    UInt uiYdim   = min(3, uiBw)+1;
    UInt uiZ[5]   = {0,1,2,4,7};
    UInt uiMaxVal = uiXdim*uiYdim - uiZ[uiYdim];

    UInt uiCoeffCountCtxMap = min(uiCoeffCountCtx, 2);
    memcpy(aucCwMapTO16, g_aucCwMapTO16[uiCoeffCountCtxMap], sizeof(UChar)*4*17);
    for( uiMapIdx=1; uiMapIdx<=uiMaxVal; uiMapIdx++ )
    {
      Bool bFound = false;
      for( ui=0; ui<uiYdim; ui++ )
        for( uj=1; uj<uiXdim; uj++ )
          if( aucCwMapTO16[ui][uj] == uiMapIdx )
          {
            bFound = true;
            break;
          }
      if( !bFound )
      {
        for( ui=0; ui<uiYdim; ui++ )
          for( uj=1; uj<uiXdim; uj++ )
            if( aucCwMapTO16[ui][uj] > uiMapIdx )
              aucCwMapTO16[ui][uj]--;
        uiMapIdx--;
      }
    }
    xWriteCode(g_aucCwCodeVectTO16[uiCoeffCountCtx][aucCwMapTO16[uiTrailingOnes][uiCoeffCount]], g_aucCwLenVectTO16[uiCoeffCountCtx][aucCwMapTO16[uiTrailingOnes][uiCoeffCount]]);
  }
  else
  {
    xWriteTrailingOnes16( uiCoeffCountCtx, uiCoeffCount, uiTrailingOnes );
  }

  rcMbDataAccess.getMbTCoeffs().setCoeffCount( cIdx, uiCoeffCount );

  return Err::m_nOK;
}


ErrVal UvlcWriter::xPredictNonZeroCnt( MbDataAccess& rcMbDataAccess, LumaIdx cIdx, UInt uiCoeffCount, UInt uiTrailingOnes, UInt uiStart, UInt uiStop )
{
  UInt uiCoeffCountCtx = rcMbDataAccess.getCtxCoeffCount( cIdx, uiStart, uiStop );

  if( uiStart != 0 || uiStop != 16 )
  {
    // Re-pack VLC matrix
    // NB: This only needs to be done once at the start of the slice.
    
    UInt uiMapIdx, ui, uj;
    UChar aucCwMapTO16[4][17];
    UInt uiBw     = uiStop-uiStart;
    UInt uiXdim   = min(16,uiBw)+1;
    UInt uiYdim   = min(3, uiBw)+1;
    UInt uiZ[5]   = {0,1,2,4,7};
    UInt uiMaxVal = uiXdim*uiYdim - uiZ[uiYdim];
    
    UInt uiCoeffCountCtxMap = min(uiCoeffCountCtx, 2);
    memcpy(aucCwMapTO16, g_aucCwMapTO16[uiCoeffCountCtxMap], sizeof(UChar)*4*17);
    for( uiMapIdx=1; uiMapIdx<=uiMaxVal; uiMapIdx++ )
    {
      Bool bFound = false;
      for( ui=0; ui<uiYdim; ui++ )
        for( uj=1; uj<uiXdim; uj++ )
          if( aucCwMapTO16[ui][uj] == uiMapIdx )
          {
            bFound = true;
            break;
          }
      if( !bFound )
      {
        for( ui=0; ui<uiYdim; ui++ )
          for( uj=1; uj<uiXdim; uj++ )
            if( aucCwMapTO16[ui][uj] > uiMapIdx )
              aucCwMapTO16[ui][uj]--;
        uiMapIdx--;
      }
    }

    xWriteCode(g_aucCwCodeVectTO16[uiCoeffCountCtx][aucCwMapTO16[uiTrailingOnes][uiCoeffCount]], g_aucCwLenVectTO16[uiCoeffCountCtx][aucCwMapTO16[uiTrailingOnes][uiCoeffCount]]);
  }
  else
  {
    xWriteTrailingOnes16( uiCoeffCountCtx, uiCoeffCount, uiTrailingOnes );
  }

  rcMbDataAccess.getMbTCoeffs().setCoeffCount( cIdx, uiCoeffCount );

  return Err::m_nOK;
}

ErrVal UvlcWriter::xWriteRunLevel( Int* aiLevelRun, UInt uiCoeffCnt, UInt uiTrailingOnes, UInt uiMaxCoeffs, UInt uiTotalRun, MbDataAccess &rcMbDataAccess, Bool bDefaultScanIdx )
{

  ROTRS( 0 == uiCoeffCnt, Err::m_nOK );

  if( uiTrailingOnes )
  {
    UInt uiBits = 0;
    Int n = uiTrailingOnes-1;
    for( UInt k = uiCoeffCnt; k > uiCoeffCnt-uiTrailingOnes; k--, n--)
    {
      if( aiLevelRun[k-1] < 0)
      {
        uiBits |= 1<<n;
      }
    }

    RNOK( m_pcBitWriteBufferIf->write( uiBits, uiTrailingOnes ))
    ETRACE_POS;
    ETRACE_T( "  TrailingOnesSigns: " );
    ETRACE_V( uiBits );
    ETRACE_N;
    ETRACE_COUNT(uiTrailingOnes);
  }


  Int iHighLevel = ( uiCoeffCnt > 3 && uiTrailingOnes == 3) ? 0 : 1;
  Int iVlcTable  = ( uiCoeffCnt > 10 && uiTrailingOnes < 3) ? 1 : 0;

  for( Int k = uiCoeffCnt - 1 - uiTrailingOnes; k >= 0; k--)
  {
    Int iLevel;
    iLevel = aiLevelRun[k];

    UInt uiAbsLevel = (UInt)abs(iLevel);

    if( iHighLevel )
    {
      iLevel -= ( iLevel > 0 ) ? 1 : -1;
	    iHighLevel = 0;
    }

    if( iVlcTable == 0 )
    {
	    xWriteLevelVLC0( iLevel );
    }
    else
    {
	    xWriteLevelVLCN( iLevel, iVlcTable );
    }

    // update VLC table
    if( uiAbsLevel > g_auiIncVlc[ iVlcTable ] )
    {
      iVlcTable++;
    }

    if( k == Int(uiCoeffCnt - 1 - uiTrailingOnes) && uiAbsLevel > 3)
    {
      iVlcTable = 2;
    }

  }

  ROFRS( uiCoeffCnt < uiMaxCoeffs, Err::m_nOK );


  iVlcTable = uiCoeffCnt-1;
  if( ! bDefaultScanIdx )
  {
    if( uiMaxCoeffs <= 4 )
    {
      UInt uiTempVlcTable = min(iVlcTable + 4-uiMaxCoeffs, 2);
      xWriteTotalRun4( uiTempVlcTable, uiTotalRun );
    }
    else if( uiMaxCoeffs <= 8 )
    {
      UInt uiTempVlcTable = min(iVlcTable + 8-uiMaxCoeffs, 6);
      xWriteTotalRun8( uiTempVlcTable, uiTotalRun );
    }
    else
    {
      UInt uiTempVlcTable = iVlcTable;
      if( uiMaxCoeffs < 15 )
        uiTempVlcTable = min(iVlcTable + 16-uiMaxCoeffs, 14);
      xWriteTotalRun16( uiTempVlcTable, uiTotalRun );
    }
  }
  else
  {
    if( uiMaxCoeffs <= 4 )
    {
      xWriteTotalRun4( iVlcTable, uiTotalRun );
    }
    else
    {
      xWriteTotalRun16( iVlcTable, uiTotalRun );
    }
  }

  // decode run before each coefficient
  uiCoeffCnt--;
  if( uiTotalRun > 0 && uiCoeffCnt > 0)
  {
    do
    {
      iVlcTable = (( uiTotalRun > RUNBEFORE_NUM) ? RUNBEFORE_NUM : uiTotalRun) - 1;
      UInt uiRun = aiLevelRun[uiCoeffCnt+0x10];

      xWriteRun( iVlcTable, uiRun );

      uiTotalRun -= uiRun;
      uiCoeffCnt--;
    } while( uiTotalRun != 0 && uiCoeffCnt != 0);
  }

  return Err::m_nOK;
}


ErrVal UvlcWriter::xWriteTrailingOnes16( UInt uiLastCoeffCount, UInt uiCoeffCount, UInt uiTrailingOnes )
{
  UInt uiVal;
  UInt uiSize;

  ETRACE_POS;
  if( 3 == uiLastCoeffCount )
  {
    UInt uiBits = 3;
    if( uiCoeffCount )
    {
      uiBits = (uiCoeffCount-1)<<2 | uiTrailingOnes;
    }
    RNOK( m_pcBitWriteBufferIf->write( uiBits, 6) );
    ETRACE_DO( m_uiBitCounter = 6 );

    uiVal = uiBits;
    uiSize = 6;
  }
  else
  {
    RNOK( m_pcBitWriteBufferIf->write( g_aucCodeTableTO16[uiLastCoeffCount][uiTrailingOnes][uiCoeffCount],
                                  g_aucLenTableTO16[uiLastCoeffCount][uiTrailingOnes][uiCoeffCount] ) );
    ETRACE_DO( m_uiBitCounter = g_aucLenTableTO16[uiLastCoeffCount][uiTrailingOnes][uiCoeffCount] );

    uiVal = g_aucCodeTableTO16[uiLastCoeffCount][uiTrailingOnes][uiCoeffCount];
    uiSize = g_aucLenTableTO16[uiLastCoeffCount][uiTrailingOnes][uiCoeffCount];
  }

  ETRACE_T( "  TrailingOnes16: Vlc: " );
  ETRACE_V( uiLastCoeffCount );
  ETRACE_T( " CoeffCnt: " );
  ETRACE_V( uiCoeffCount );
  ETRACE_T( " TraiOnes: " );
  ETRACE_V( uiTrailingOnes );
  ETRACE_N;
  ETRACE_COUNT(m_uiBitCounter);

⌨️ 快捷键说明

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