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

📄 uvlcwriter.cpp

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


  switch( eResidualMode )
  {
  case LUMA_I16_DC:
    {
      ETRACE_T( "Luma:" );
      ETRACE_V( cIdx );
      ETRACE_N;
      xPredictNonZeroCnt( rcMbDataAccess, cIdx, uiCoeffCnt, uiTrailingOnes );
      xWriteRunLevel( aiLevelRun, uiCoeffCnt, uiTrailingOnes, 16, uiTotalRun );
      break;
    }
  case LUMA_I16_AC:
    {
      ETRACE_T( "Luma:" );
      ETRACE_V( cIdx );
      ETRACE_N;
      xPredictNonZeroCnt( rcMbDataAccess, cIdx, uiCoeffCnt, uiTrailingOnes );
      xWriteRunLevel( aiLevelRun, uiCoeffCnt, uiTrailingOnes, 15, uiTotalRun );
      break;
    }
  case LUMA_SCAN:
    {
      ETRACE_T( "Luma:" );
      ETRACE_V( cIdx );
      ETRACE_N;
      xPredictNonZeroCnt( rcMbDataAccess, cIdx, uiCoeffCnt, uiTrailingOnes );
      xWriteRunLevel( aiLevelRun, uiCoeffCnt, uiTrailingOnes, 16, uiTotalRun );
      break;
    }
  default:
    {
      AF();
    }
  }

  return Err::m_nOK;
}



ErrVal UvlcWriter::residualBlock( MbDataAccess& rcMbDataAccess,
                                  ChromaIdx     cIdx,
                                  ResidualMode  eResidualMode )
{
  const TCoeff* piCoeff = rcMbDataAccess.getMbTCoeffs().get( cIdx );
  const UChar*  pucScan;
  Int           iRun = 0, iLevel;
  UInt          uiPos, uiMaxPos;

  switch( eResidualMode )
  {
  case CHROMA_DC:
    {
      pucScan = g_aucIndexChromaDCScan;
      uiPos=0;  uiMaxPos= 4;
      break;
    }
  case CHROMA_AC:
    {
      pucScan = g_aucFrameScan;
      uiPos=1;  uiMaxPos=16;
      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;
  }


  switch( eResidualMode )
  {
  case CHROMA_AC:
    {
      ETRACE_T( "CHROMA_AC:" );
      ETRACE_V( cIdx );
      ETRACE_N;
      xPredictNonZeroCnt( rcMbDataAccess, cIdx, uiCoeffCnt, uiTrailingOnes );
      xWriteRunLevel( aiLevelRun, uiCoeffCnt, uiTrailingOnes, 15, uiTotalRun );
      break;
    }
  case CHROMA_DC:
    {
      ETRACE_T( "CHROMA_DC:" );
      ETRACE_V( cIdx );
      ETRACE_N;
      xWriteTrailingOnes4( uiCoeffCnt, uiTrailingOnes );
      xWriteRunLevel( aiLevelRun, uiCoeffCnt, uiTrailingOnes, 4, uiTotalRun );
      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 uiCoeffCountCtx = rcMbDataAccess.getCtxCoeffCount( cIdx );

  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 uiCoeffCountCtx = rcMbDataAccess.getCtxCoeffCount( cIdx );

  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 )
{

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

  return Err::m_nOK;
}



ErrVal UvlcWriter::xWriteTrailingOnes4( UInt uiCoeffCount, UInt uiTrailingOnes )
{
  RNOK( m_pcBitWriteBufferIf->write( g_aucCodeTableTO4[uiTrailingOnes][uiCoeffCount],
                                g_aucLenTableTO4[uiTrailingOnes][uiCoeffCount] ) );

  ETRACE_POS;
  ETRACE_T( "  TrailingOnes4: CoeffCnt: " );
  ETRACE_V( uiCoeffCount );
  ETRACE_T( " TraiOnes: " );
  ETRACE_V( uiTrailingOnes );
  ETRACE_N;
  ETRACE_COUNT(g_aucLenTableTO4[uiTrailingOnes][uiCoeffCount]);

  return Err::m_nOK;
}


ErrVal UvlcWriter::xWriteTotalRun4( UInt uiVlcPos, UInt uiTotalRun )
{
  RNOK( m_pcBitWriteBufferIf->write( g_aucCodeTableTZ4[uiVlcPos][uiTotalRun],
                                g_aucLenTableTZ4[uiVlcPos][uiTotalRun] ) );

  ETRACE_POS;
  ETRACE_T( "  TotalZeros4 vlc: " );
  ETRACE_V( uiVlcPos );
  ETRACE_T( " TotalRun: " );
  ETRACE_V( uiTotalRun );
  ETRACE_N;
  ETRACE_COUNT(g_aucLenTableTZ4[uiVlcPos][uiTotalRun]);

  return Err::m_nOK;
}


ErrVal UvlcWriter::xWriteTotalRun16( UInt uiVlcPos, UInt uiTotalRun )
{
  RNOK( m_pcBitWriteBufferIf->write( g_aucCodeTableTZ16[uiVlcPos][uiTotalRun],
                                g_aucLenTableTZ16[uiVlcPos][uiTotalRun] ) );

  ETRACE_POS;
  ETRACE_T( "  TotalRun16 vlc: " );
  ETRACE_V( uiVlcPos );
  ETRACE_T( " TotalRun: " );
  ETRACE_V( uiTotalRun );
  ETRACE_N;
  ETRACE_COUNT(g_aucLenTableTZ16[uiVlcPos][uiTotalRun]);

  return Err::m_nOK;
}


ErrVal UvlcWriter::xWriteRun( UInt uiVlcPos, UInt uiRun  )
{
  RNOK( m_pcBitWriteBufferIf->write( g_aucCodeTable3[uiVlcPos][uiRun],
                                g_aucLenTable3[uiVlcPos][uiRun] ) );

  ETRACE_POS;
  ETRACE_T( "  Run" );
  ETRACE_CODE( uiRun );
  ETRACE_COUNT (g_aucLenTable3[uiVlcPos][uiRun]);
  ETRACE_N;

  return Err::m_nOK;
}




ErrVal UvlcWriter::xWriteLevelVLC0( Int iLevel )
{

  UInt uiLength;
  UInt uiLevel = abs( iLevel );
  UInt uiSign = ((UInt)iLevel)>>31;

  UInt uiBits;

  if( 8 > uiLevel )
  {
    uiBits   = 1;
    uiLength = 2 * uiLevel - 1 + uiSign;
  }
  else if( 16 > uiLevel )
  {
    uiBits   = 2*uiLevel + uiSign;
    uiLength = 15 + 4;
  }
  else
  {
    uiBits   = 0x1000-32 + (uiLevel<<1) + uiSign;
    uiLength = 16 + 12;
  }


  RNOK( m_pcBitWriteBufferIf->write( uiBits, uiLength ) );

  ETRACE_POS;
  ETRACE_T( "  VLC0 lev " );
  ETRACE_CODE( iLevel );
  ETRACE_N;
  ETRACE_COUNT( uiLength );

  return Err::m_nOK;

}

ErrVal UvlcWriter::xWriteLevelVLCN( Int iLevel, UInt uiVlcLength )
{
  UInt uiLength;
  UInt uiLevel = abs( iLevel );
  UInt uiSign = ((UInt)iLevel)>>31;
  UInt uiBits;

  UInt uiShift = uiVlcLength-1;
  UInt uiEscapeCode = (0xf<<uiShift)+1;

  if( uiLevel < uiEscapeCode )
  {
    uiLevel--;
	  uiLength = (uiLevel>>uiShift) + uiVlcLength + 1;
    uiLevel &= ~((0xffffffff)<<uiShift);
	  uiBits   = (2<<uiShift) | 2*uiLevel | uiSign;
  }
  else
  {
	  uiLength = 28;
	  uiBits   = 0x1000 + 2*(uiLevel-uiEscapeCode) + uiSign;
  }



  RNOK( m_pcBitWriteBufferIf->write( uiBits, uiLength ) );

  ETRACE_POS;
  ETRACE_T( "  VLCN lev: " );
  ETRACE_CODE( iLevel );
  ETRACE_N;
  ETRACE_COUNT( uiLength );

  return Err::m_nOK;
}



ErrVal UvlcWriter::samplesPCM( MbDataAccess& rcMbDataAccess )
{
  ETRACE_POS;

⌨️ 快捷键说明

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