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

📄 qualitylevelassigner.cpp

📁 JMVM MPEG MVC/3DAV 测试平台 国际通用标准
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  fclose( pFile );

  printf("\n");
  return Err::m_nOK;
}



ErrVal
QualityLevelAssigner::xDetermineQualityIDs()
{
  printf( "determine quality levels ..." );

  //===== determine minimum and maximum quality level id's =====
  UInt  auiMinQualityLevel[MAX_LAYERS];
  UInt  auiMaxQualityLevel[MAX_LAYERS];
  {
    for( Int iLayer = (Int)m_uiNumLayers-1; iLayer >= 0; iLayer-- )
    {
      UInt  uiMinQLLayer          = ( iLayer == (Int)m_uiNumLayers-1 ? 0 : auiMaxQualityLevel[iLayer+1]+1 );
      UInt  uiNumQLInLayer        = ( 63 - uiMinQLLayer ) / ( iLayer + 1 );
      auiMinQualityLevel[iLayer]  = uiMinQLLayer;
      auiMaxQualityLevel[iLayer]  = uiMinQLLayer + uiNumQLInLayer - 1;
    }
  }

  //===== determine optimized quality levels per layer =====
  for( UInt uiLayer = 0; uiLayer < m_uiNumLayers; uiLayer++ )
  {
    //----- create quality estimation object -----
    QualityLevelEstimation  cQualityLevelEstimation;
    RNOK( cQualityLevelEstimation.init( m_uiNumLayers, m_auiNumFGSLayers, m_auiNumFrames ) );

    //----- initialize with packets -----
    {
      for( UInt uiFGSLayer = 1; uiFGSLayer <= m_auiNumFGSLayers[uiLayer]; uiFGSLayer++ )
      for( UInt uiFrame    = 0; uiFrame    <  m_auiNumFrames   [uiLayer]; uiFrame   ++ )
      {
        RNOK( cQualityLevelEstimation.addPacket( uiLayer, uiFGSLayer, uiFrame,
                                                 m_aaauiPacketSize [uiLayer][uiFGSLayer][uiFrame],
                                                 m_aaadDeltaDist   [uiLayer][uiFGSLayer][uiFrame] ) );
      }
    }

    //----- determine quality levels -----
    RNOK( cQualityLevelEstimation.optimizeQualityLevel( uiLayer, uiLayer, auiMinQualityLevel[uiLayer], auiMaxQualityLevel[uiLayer] ) );

    //----- assign quality levels -----
    {
      for( UInt uiFGSLayer = 0; uiFGSLayer <= m_auiNumFGSLayers[uiLayer]; uiFGSLayer++ )
      for( UInt uiFrame    = 0; uiFrame    <  m_auiNumFrames   [uiLayer]; uiFrame   ++ )
      {
        m_aaauiQualityID[uiLayer][uiFGSLayer][uiFrame] = ( uiFGSLayer ? cQualityLevelEstimation.getQualityLevel( uiLayer, uiFGSLayer, uiFrame ) : 63 );
      }
    }
  }

  printf("\n");
  return Err::m_nOK;
}

//JVT-S043
ErrVal
QualityLevelAssigner::xDetermineMultiLayerQualityIDs()
{
  printf( "determine ML quality levels ..." );

  //===== determine minimum and maximum quality level id's =====
  UInt  uiMinQualityLevel = 0;
  UInt  uiMaxQualityLevel = 62;
  
  UInt uiLayer;

 //----- create quality estimation object -----
  QualityLevelEstimation  cQualityLevelEstimation;
  RNOK( cQualityLevelEstimation.init( m_uiNumLayers, m_auiNumFGSLayers, m_auiNumFrames ) );

  //===== determine optimized quality levels per layer =====
  for( uiLayer = 0; uiLayer < m_uiNumLayers; uiLayer++ )
  {
    //----- initialize with packets -----
    {
      for( UInt uiFGSLayer = 1; uiFGSLayer <= m_auiNumFGSLayers[uiLayer]; uiFGSLayer++ )
      for( UInt uiFrame    = 0; uiFrame    <  m_auiNumFrames   [uiLayer]; uiFrame   ++ )
      {
        RNOK( cQualityLevelEstimation.addPacket( uiLayer, uiFGSLayer, uiFrame,
                                                 m_aaauiPacketSize [uiLayer][uiFGSLayer][uiFrame],
                                                 m_aaadDeltaDist   [uiLayer][uiFGSLayer][uiFrame] ) );
      }
    }
  }


  //----- determine quality levels -----
  RNOK( cQualityLevelEstimation.optimizeQualityLevel( m_uiNumLayers-1, 0, uiMinQualityLevel, uiMaxQualityLevel ) );

  for( uiLayer = 0; uiLayer < m_uiNumLayers; uiLayer++ )
  {
    //----- assign quality levels -----
    {
      for( UInt uiFGSLayer = 0; uiFGSLayer <= m_auiNumFGSLayers[uiLayer]; uiFGSLayer++ )
      for( UInt uiFrame    = 0; uiFrame    <  m_auiNumFrames   [uiLayer]; uiFrame   ++ )
      {
        m_aaauiQualityID[uiLayer][uiFGSLayer][uiFrame] = ( uiFGSLayer ? cQualityLevelEstimation.getQualityLevel( uiLayer, uiFGSLayer, uiFrame ) : 63 );
      }
    }
  }

  printf("\n");
  return Err::m_nOK;
}

ErrVal
QualityLevelAssigner::xWriteQualityLayerStreamPID()
{
  printf( "write stream with quality layer (PID) \"%s\" ...", m_pcParameter->getOutputBitStreamName().c_str() );

  BinData*          pcBinData     = 0;
  SEI::SEIMessage*  pcScalableSEI = 0;
  PacketDescription cPacketDescription;
  UInt              auiFrameNum[MAX_LAYERS] = { MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX };

  //===== init =====
  RNOK( m_pcH264AVCPacketAnalyzer->init() );
  ReadBitstreamFile*    pcReadBitStream   = 0;
  WriteBitstreamToFile* pcWriteBitStream  = 0;
  RNOK( ReadBitstreamFile   ::create( pcReadBitStream  ) );
  RNOK( WriteBitstreamToFile::create( pcWriteBitStream ) );
  RNOK( pcReadBitStream ->init( m_pcParameter->getInputBitStreamName  () ) );
  RNOK( pcWriteBitStream->init( m_pcParameter->getOutputBitStreamName () ) );


  //===== loop over packets =====
  while( true )
  {
    //----- read packet -----
    Bool bEOS = false;
    RNOK( pcReadBitStream->extractPacket( pcBinData, bEOS ) );
    if( bEOS )
    {
      //manu.mathew@samsung : memory leak fix
      RNOK( pcReadBitStream ->releasePacket ( pcBinData ) );
      pcBinData = NULL;
      //--
      break;
    }

    //----- get packet description -----
    RNOK( m_pcH264AVCPacketAnalyzer->process( pcBinData, cPacketDescription, pcScalableSEI ) );
    delete pcScalableSEI; pcScalableSEI = 0;

    //----- set packet size -----
    while( pcBinData->data()[ pcBinData->size() - 1 ] == 0x00 )
    {
      RNOK( pcBinData->decreaseEndPos( 1 ) ); // remove trailing zeros
    }

    //----- analyse packets -----
    if( cPacketDescription.FGSLayer )
    {
      pcBinData->data()[1] |= ( m_aaauiQualityID[cPacketDescription.Layer][cPacketDescription.FGSLayer][auiFrameNum[cPacketDescription.Layer]] << 2 );
    }
    else
    {
      if( ! cPacketDescription.ParameterSet && cPacketDescription.NalUnitType != NAL_UNIT_SEI &&
          ! cPacketDescription.FGSLayer )
      {
        auiFrameNum[cPacketDescription.Layer]++;
      }
    }

    //----- write and delete bin data -----
    RNOK( pcWriteBitStream->writePacket   ( &m_cBinDataStartCode ) );
    RNOK( pcWriteBitStream->writePacket   ( pcBinData ) );
    RNOK( pcReadBitStream ->releasePacket ( pcBinData ) );
  }

  
  //===== uninit =====
  RNOK( m_pcH264AVCPacketAnalyzer->uninit() );
  RNOK( pcReadBitStream ->uninit  () );
  RNOK( pcWriteBitStream->uninit  () );
  RNOK( pcReadBitStream ->destroy () );
  RNOK( pcWriteBitStream->destroy () );

  printf("\n");
  return Err::m_nOK;
}



ErrVal
QualityLevelAssigner::xWriteQualityLayerStreamSEI()
{
  printf( "write stream with quality layer (SEI) \"%s\" ...", m_pcParameter->getOutputBitStreamName().c_str() );

  UInt              uiNumAccessUnits  = 0;
  UInt              uiPrevLayer       = 0;
  UInt              uiPrevLevel       = 0;
  BinData*          pcBinData         = 0;
  SEI::SEIMessage*  pcScalableSEI     = 0;
  PacketDescription cPacketDescription;
  UInt              auiFrameNum[MAX_LAYERS] = { MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX };

  //===== init =====
  RNOK( m_pcH264AVCPacketAnalyzer->init() );
  ReadBitstreamFile*    pcReadBitStream   = 0;
  WriteBitstreamToFile* pcWriteBitStream  = 0;
  RNOK( ReadBitstreamFile   ::create( pcReadBitStream  ) );
  RNOK( WriteBitstreamToFile::create( pcWriteBitStream ) );
  RNOK( pcReadBitStream ->init( m_pcParameter->getInputBitStreamName  () ) );
  RNOK( pcWriteBitStream->init( m_pcParameter->getOutputBitStreamName () ) );


  //===== loop over packets =====
  while( true )
  {
    //----- read packet -----
    Bool bEOS = false;
    RNOK( pcReadBitStream->extractPacket( pcBinData, bEOS ) );
    if( bEOS )
    {
      //manu.mathew@samsung : memory leak fix
      RNOK( pcReadBitStream ->releasePacket ( pcBinData ) );
      pcBinData = NULL;
      //--
      break;
    }

    //----- get packet description -----
    RNOK( m_pcH264AVCPacketAnalyzer->process( pcBinData, cPacketDescription, pcScalableSEI ) );
    delete pcScalableSEI; pcScalableSEI = 0;

    //----- set packet size -----
    while( pcBinData->data()[ pcBinData->size() - 1 ] == 0x00 )
    {
      RNOK( pcBinData->decreaseEndPos( 1 ) ); // remove trailing zeros
    }

    //----- detect first slice data of access unit -----
    Bool bNewAccessUnit = ( !cPacketDescription.ParameterSet                &&
                            !cPacketDescription.ApplyToNext                 &&
                             cPacketDescription.NalUnitType != NAL_UNIT_SEI &&
                             cPacketDescription.FGSLayer    == 0U );
    if(  bNewAccessUnit )
    {
      bNewAccessUnit  =                   ( cPacketDescription.Layer == 0 );
      bNewAccessUnit  = bNewAccessUnit || ( cPacketDescription.Layer >= uiPrevLayer && cPacketDescription.Level >  uiPrevLevel );
      bNewAccessUnit  = bNewAccessUnit || ( cPacketDescription.Layer == uiPrevLayer && cPacketDescription.Level == uiPrevLevel );
      bNewAccessUnit  = bNewAccessUnit || ( cPacketDescription.Layer <  uiPrevLayer );
    }

    //----- insert quality layer SEI and increase frame number -----
    if( bNewAccessUnit )
    {
      for( UInt uiLayer = cPacketDescription.Layer; uiLayer < m_uiNumLayers; uiLayer++ )
      {
        auiFrameNum[uiLayer]++;
        xInsertQualityLayerSEI( pcWriteBitStream, uiLayer, auiFrameNum[uiLayer] );
      }
      uiNumAccessUnits++;
    }

    //----- write and delete bin data -----
    RNOK( pcWriteBitStream->writePacket   ( &m_cBinDataStartCode ) );
    RNOK( pcWriteBitStream->writePacket   ( pcBinData ) );
    RNOK( pcReadBitStream ->releasePacket ( pcBinData ) );

    //----- update previous layer information -----
    uiPrevLayer = cPacketDescription.Layer;
    uiPrevLevel = cPacketDescription.Level;
  }

  
  //===== uninit =====
  RNOK( m_pcH264AVCPacketAnalyzer->uninit() );
  RNOK( pcReadBitStream ->uninit  () );
  RNOK( pcWriteBitStream->uninit  () );
  RNOK( pcReadBitStream ->destroy () );
  RNOK( pcWriteBitStream->destroy () );


  printf(" (%d AU's)\n", uiNumAccessUnits );
  return Err::m_nOK;
}



ErrVal
QualityLevelAssigner::xInsertQualityLayerSEI( WriteBitstreamToFile* pcWriteBitStream,
                                              UInt                  uiLayer,
                                              UInt                  uiFrameNum )
{
  //===== init binary data =====
  const UInt          uiQLSEIMessageBufferSize = 1024;
  UChar               aucQLSEIMessageBuffer[uiQLSEIMessageBufferSize];
  BinData             cBinData;
  ExtBinDataAccessor  cExtBinDataAccessor;
  cBinData.reset          ();
  cBinData.set            ( aucQLSEIMessageBuffer, uiQLSEIMessageBufferSize );
  cBinData.setMemAccessor ( cExtBinDataAccessor );

  //===== create SEI message =====
  SEI::QualityLevelSEI* pcQualityLevelSEI;
  SEI::MessageList      cSEIMessageList;
  RNOK( SEI::QualityLevelSEI::create( pcQualityLevelSEI ) );
  cSEIMessageList.push_back( pcQualityLevelSEI );

  //===== set content of SEI message =====
  UInt uiNumLayers;
  for( uiNumLayers = 0; uiNumLayers <= m_auiNumFGSLayers[uiLayer] && m_aaauiQualityID  [uiLayer][uiNumLayers][uiFrameNum] != MSYS_UINT_MAX; uiNumLayers++ )
  {
    pcQualityLevelSEI->setQualityLevel          ( uiNumLayers,       m_aaauiQualityID  [uiLayer][uiNumLayers][uiFrameNum] );
    pcQualityLevelSEI->setDeltaBytesRateOfLevel ( uiNumLayers,       m_aaauiPacketSize [uiLayer][uiNumLayers][uiFrameNum] );
  }
  pcQualityLevelSEI->setDependencyId            ( uiLayer );
  pcQualityLevelSEI->setNumLevel                ( uiNumLayers );

  //===== encode SEI message =====
  UInt uiBits = 0;
  RNOK( m_pcNalUnitEncoder->initNalUnit ( &cExtBinDataAccessor ) );
  RNOK( m_pcNalUnitEncoder->write       ( cSEIMessageList ) );
  RNOK( m_pcNalUnitEncoder->closeNalUnit( uiBits ) );

  //===== write SEI message =====
  RNOK( pcWriteBitStream->writePacket( &m_cBinDataStartCode ) );
  RNOK( pcWriteBitStream->writePacket( &cExtBinDataAccessor ) );

  //===== reset =====
  cBinData.reset();

  return Err::m_nOK;
}

⌨️ 快捷键说明

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