qualitylevelassigner.cpp

来自「SVC最新更新代码」· C++ 代码 · 共 1,704 行 · 第 1/5 页

CPP
1,704
字号
                                                 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.getQualityId( 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;
  UInt              uiLastPrefixTL  = MSYS_UINT_MAX;
  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 )
    {
      // JVT-T083: modify the Position of SimplePriorityId
      // clear previous value
      pcBinData->data()[1] &= 0xC0;
      // write new value of priority ID
      pcBinData->data()[1] |= m_aaauiQualityID[cPacketDescription.Layer][cPacketDescription.FGSLayer][auiFrameNum[cPacketDescription.Layer]];
    }
    else
    {
      if( cPacketDescription.NalUnitType == NAL_UNIT_CODED_SLICE_IDR || cPacketDescription.NalUnitType == NAL_UNIT_CODED_SLICE )
      {
        if( uiLastPrefixTL == MSYS_UINT_MAX )
        {
          fprintf( stderr, "\nMissing prefix NAL unit\n\n" );
          ROT(1);
        }
        cPacketDescription.Level = uiLastPrefixTL;
      }
      if( ! cPacketDescription.ParameterSet && cPacketDescription.NalUnitType != NAL_UNIT_SEI &&
          ! cPacketDescription.FGSLayer  && cPacketDescription.NalUnitType != NAL_UNIT_PREFIX && cPacketDescription.uiFirstMb == 0 )
      {
        auiFrameNum[cPacketDescription.Layer]++;
      }
    }

    if( cPacketDescription.NalUnitType == 14 )
	  {
      uiLastPrefixTL = cPacketDescription.Level;
  	}
    else
    {
      uiLastPrefixTL = MSYS_UINT_MAX;
    }

    //----- 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;
  UInt              uiLastPrefixTL    = MSYS_UINT_MAX;
  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 () ) );

  Bool bPrevNALUnitWasPrefix = false; //JVT-W137

  //===== 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(cPacketDescription.NalUnitType == NAL_UNIT_CODED_SLICE_IDR || cPacketDescription.NalUnitType == NAL_UNIT_CODED_SLICE)
    {
      if( uiLastPrefixTL == MSYS_UINT_MAX )
      {
        fprintf( stderr, "\nMissing prefix NAL unit\n\n" );
        ROT(1);
      }
      cPacketDescription.Level = uiLastPrefixTL;
      bNewAccessUnit = bNewAccessUnit && (!bPrevNALUnitWasPrefix); //JVT-W137
      if(bPrevNALUnitWasPrefix)
        bPrevNALUnitWasPrefix = false; //JVT-W137
    }
    if( cPacketDescription.NalUnitType == 14 )
    {
      uiLastPrefixTL  = cPacketDescription.Level;
      bPrevNALUnitWasPrefix = true;
    }
    else
    {
      uiLastPrefixTL  = MSYS_UINT_MAX;
    }
    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] );//SEI changes update
        xInsertPriorityLevelSEI( pcWriteBitStream, uiLayer, auiFrameNum[uiLayer] );//SEI changes update
      }
      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;
}



//SEI changes update {
//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] ); //JVT-W137
//  }
//  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;
//}
ErrVal
QualityLevelAssigner::xInsertPriorityLevelSEI( WriteBitstreamToFile* pcWriteBitStream,
                                              UInt                  uiLayer,
                                              UInt                  uiFrameNum )
{
  //===== init binary data =====
  const UInt          uiPRSEIMessageBufferSize = 1024;
  UChar               aucPRSEIMessageBuffer[uiPRSEIMessageBufferSize];
  BinData             cBinData;
  ExtBinDataAccessor  cExtBinDataAccessor;
  cBinData.reset          ();
  cBinData.set            ( aucPRSEIMessageBuffer, uiPRSEIMessageBufferSize );
  cBinData.setMemAccessor ( cExtBinDataAccessor );

  //===== create SEI message =====
  SEI::PriorityLevelSEI* pcPriorityLevelSEI;
  SEI::MessageList      cSEIMessageList;
  RNOK( SEI::PriorityLevelSEI::create( pcPriorityLevelSEI ) );
  cSEIMessageList.push_back( pcPriorityLevelSEI );

  //===== set content of SEI message =====
  UInt uiNumLayers;
  for( uiNumLayers = 0; uiNumLayers <= m_auiNumFGSLayers[uiLayer] && m_aaauiQualityID  [uiLayer][uiNumLayers][uiFrameNum] != MSYS_UINT_MAX; uiNumLayers++ )
  {
		pcPriorityLevelSEI->setAltPriorityId          ( uiNumLayers,       m_aaauiQualityID  [uiLayer][uiNumLayers][uiFrameNum] );
  }
	pcPriorityLevelSEI->setPrDependencyId           ( uiLayer );
	pcPriorityLevelSEI->setNumPriorityIds           ( 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;
}
//SEI changes update }

⌨️ 快捷键说明

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