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

📄 extractor.cpp

📁 jsvm开发代码包括抽样,编码,抽取,解码等一系列功能,可以做工具或研究用
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            return Err::m_nOK;
          }
        }
      }
      else
      {
//JVT-T054}
        m_uiTruncateLayer = uiExtLayer;
        m_uiTruncateLevel = uiExtLevel;
        m_uiTruncateFGSLayer = uiFGSLayer;
				Double dFGSLayer = dRemainingBytes / (Double)i64FGSLayerBytes;
				for( uiLevel = 0; uiLevel <= uiExtLevel; uiLevel++ )
				{
					 m_aadTargetSNRLayer[uiExtLayer][uiLevel] += dFGSLayer;
					 m_pcExtractorParameter->setMaxFGSLayerKept(uiFGSLayer);
					 Double dDecBitrate = m_aaadSingleBitrate[m_uiTruncateLayer][uiLevel][m_uiTruncateFGSLayer] * (1-dFGSLayer);
					 RNOK( xResetSLFGSBitrate( m_uiTruncateLayer, uiLevel, m_uiTruncateFGSLayer, dDecBitrate ) );
				}
				return Err::m_nOK;
//JVT-T054{
      }
//JVT-T054}
    }
  }

  //===== set maximum possible bytes for no use frames in included layers, for SIP ======
  for( uiLayer = 0; uiLayer <  uiExtLayer; uiLayer++ )
  {
    for( uiLevel = 0; uiLevel <= uiExtLevel; uiLevel++ )
    {
      for( uiFGSLayer = 0; uiFGSLayer < MAX_QUALITY_LEVELS; uiFGSLayer++ )
      {
        Int64 i64NALUBytes = m_cScalableStreamDescription.getNALUBytesNoUse( uiLayer, uiLevel, uiFGSLayer );
        if( (Double)i64NALUBytes <= dRemainingBytes )
        {
          dRemainingBytes                      -= (Double)i64NALUBytes;
          m_aadTargetSNRLayerNoUse[uiLayer][uiLevel] = (Double)uiFGSLayer;
        }
        else
        {
          //====== set fractional FGS layer and exit =====
          Double  dFGSLayer = dRemainingBytes / (Double)i64NALUBytes;
          m_aadTargetSNRLayerNoUse[uiLayer][uiLevel] += dFGSLayer;
          return Err::m_nOK;
        }
      }
    }
  }

	m_uiTruncateLayer = uiExtLayer;
	m_uiTruncateLevel = uiExtLevel;
	m_uiTruncateFGSLayer = MAX_FGS_LAYERS;
  WARNING( dRemainingBytes>0.0, "Bit-rate overflow for extraction/inclusion point" );

  return Err::m_nOK;
}

ErrVal
Extractor::go()
{
  //JVT-P031
  UInt uiLayer;
  for(uiLayer = 0; uiLayer < MAX_LAYERS; uiLayer++)
  {
      m_bExtractDeadSubstream[uiLayer] = m_pcExtractorParameter->getExtractDeadSubstream(uiLayer);
  }
  //~JVT-P031

  RNOK ( xPrimaryAnalyse());
  // ROI ICU/ETRI DS
  xSetROIParameters();

  AllocateAndInitializeDatas();
	
  if( m_pcExtractorParameter->getMaximumRate() != 0.0 )
  {
    xExtractMaxRate( m_pcExtractorParameter->getMaximumRate(), m_pcExtractorParameter->getDontTruncQLayer() );
    return Err::m_nOK;
  }

  RNOK ( xAnalyse() );
  ROTRS( m_pcExtractorParameter->getAnalysisOnly(), Err::m_nOK );

  if( m_pcExtractionTraceFile ) // HS: packet trace
  {
    RNOK( xExtractTrace() ); // HS: packet trace
  }
  else if( m_pcExtractorParameter->getExtractionList().empty() )
  {
    RNOK( xExtractLayerLevel() );
  }
  else
  {
    //France Telecom R&D-(nathalie.cammas@francetelecom.com)
    //if there is dead substream in the input stream
    // and but no R/D information
    if(m_bInInputStreamDS && !m_bInInputStreamQL)
    {
        go_DS();
      return Err::m_nOK;
    }
    //if there is R/D information in the input stream
    //with or without dead substream
    if(m_bInInputStreamQL)
    {
      go_QL();
      return Err::m_nOK;
    }

    //S051{
    if(m_bUseSIP)
    {
      go_SIP();
      return Err::m_nOK;
    }
    //S051}

    //default case: there is no dead substream, nor R/D information
    //in the input stream
    //}}Quality level estimation and modified truncation- JVTO044 and m12007
    RNOK( xSetParameters() );
    RNOK( xExtractPoints() );
  }

  return Err::m_nOK;
}



ErrVal
Extractor::xExtractMaxRate( Double dMaxRate, Bool bDontTruncQLayer )
{
  ROF( dMaxRate > 0 );

  Bool    bQualityLayerPresent  = false;
  UInt    uiLayer               = MSYS_UINT_MAX;
  Double  dFrameRate            = 0.0;
  UInt    uiDiffRate            = 0;
  UInt    auiQLRate[MAX_QLAYERS+2];

  //----- get layer number -----
  for( Int i = MAX_LAYERS - 1; i >= 0; i--) { if( m_auiNbImages[i] > 0 ) { uiLayer = (UInt)i; break; } }
  ROT( uiLayer == MSYS_UINT_MAX );

  //----- analyze -----
  RNOK( xAnalyse( uiLayer, dFrameRate, bQualityLayerPresent, auiQLRate, bDontTruncQLayer ) );
  ROF ( dFrameRate    >  0 );
  ROF ( auiQLRate[0]  >  0 );

  //----- get parameters -----
  Double  dScale    = 1000.0 / 8.0 * (Double)m_auiNbImages[uiLayer] / dFrameRate;
  UInt    uiTGRate  = (UInt)floor( dScale * dMaxRate );
  Int     iExtPID   = MAX_QLAYERS;
  UInt    uiInLRate = 0;
  if(     uiTGRate  > auiQLRate[MAX_QLAYERS+1] )
  {
    for(  Int iQId  = MAX_QLAYERS; iQId >= 0; iQId-- )
    {
      if( uiTGRate  < auiQLRate[iQId] )
      {
        iExtPID     = iQId;
        uiInLRate   = uiTGRate - auiQLRate[iQId+1];
        break;
      }
      else if( iQId == 0 )
      {
        iExtPID     = -1;
        uiInLRate   = uiTGRate - auiQLRate[0];
      }
    }
  }
  else
  { 
    uiDiffRate  = uiTGRate - auiQLRate[MAX_QLAYERS+1];
  }
  if( bDontTruncQLayer )
  {
    uiDiffRate  = uiInLRate;
    uiInLRate   = 0;
  }

  //---- extraction ----
  RNOK( xExtract( uiLayer, bQualityLayerPresent, iExtPID, uiInLRate, bDontTruncQLayer ) );
  UInt  uiOutRate = uiTGRate - uiInLRate - uiDiffRate;


#if 1
  printf("minimum rate = %8.2lf kbit/s\n", (Double)auiQLRate[MAX_QLAYERS+1] / dScale );
  printf("maximum rate = %8.2lf kbit/s\n", (Double)auiQLRate[            0] / dScale );
  printf("\n");
  if( iExtPID < 0 )
  {
    iExtPID = 0;
  }
  printf("   low limit = %8.2lf kbit/s\n", (Double)auiQLRate[    iExtPID+1] / dScale );
  printf("  high limit = %8.2lf kbit/s\n", (Double)auiQLRate[    iExtPID  ] / dScale );
  printf("\n");
  printf(" target rate = %8.2lf kbit/s\n", (Double) uiTGRate                / dScale );
  printf(" output rate = %8.2lf kbit/s\n", (Double)uiOutRate                / dScale );
  printf("\n");
#endif

  return Err::m_nOK;
}


ErrVal
Extractor::xAnalyse( UInt    uiTargetLayer,
                    Double& rdFrameRate,
                    Bool&   rbQualityLayerPresent,
                    UInt    auiQLRate[],
                    Bool    bNoSpecialFirstFrame
                    )
{
  Bool                    bEOS          = false;
  Bool                    bNextIsSuffix = false;
  BinData*                pcBinData     = 0;
  UInt                    uiDId         = 0;
  UInt                    uiTId         = 0;
  UInt                    uiQId         = 0;
  UInt                    uiPId         = 0;
  UInt                    uiPacketSize  = 0;
  UInt                    uiNumAVCPics  = 0;
  UInt&                   ruiBLRate     = auiQLRate[MAX_QLAYERS+1];
  UInt&                   ruiFGSAU0Rate = auiQLRate[MAX_QLAYERS  ];
  h264::SEI::SEIMessage*  pcScalableSei = 0;
  h264::PacketDescription cPacketDescription;
  UInt                    aauiTLRate[MAX_TLAYERS][MAX_QUALITY_LEVELS];

  //===== clear arrays =====
  ::memset( auiQLRate,  0x00, sizeof( UInt ) * ( MAX_QLAYERS + 2 ) );
  ::memset( aauiTLRate, 0x00, sizeof( UInt ) * ( MAX_TLAYERS * MAX_QUALITY_LEVELS ) );


  //===== initialize and read scalable SEI message =====
  {
    //----- init -----
    RNOK( m_pcH264AVCPacketAnalyzer ->init          () );
    //----- read first packet, which must contain the scalable SEI -----
    RNOK( m_pcReadBitstream         ->extractPacket ( pcBinData, bEOS ) );
    ROT ( bEOS );
    RNOK( m_pcH264AVCPacketAnalyzer ->process       ( pcBinData, cPacketDescription, pcScalableSei ) );
    ROF ( pcScalableSei );
    //----- get SEI parameters and delete SEI -----
    h264::SEI::ScalableSei* pcSSEI  = static_cast<h264::SEI::ScalableSei*>( pcScalableSei );
    rdFrameRate     = (Double)pcSSEI->getAvgFrmRate( pcSSEI->getNumLayersMinus1() ) / 256.0;
    delete pcScalableSei;
    pcScalableSei   = 0;
    //----- get packet size -----
    while( pcBinData->data()[ pcBinData->size() - 1 ] == 0x00 )
    {
      RNOK( pcBinData->decreaseEndPos( 1 ) ); // remove zero at end
    }
    ruiBLRate       = 4 + pcBinData ->size();
    //----- release packet -----
    RNOK( m_pcReadBitstream         ->releasePacket ( pcBinData ) );
    pcBinData       = 0;
  }


  //===== MAIN LOOP OVER PACKETS =====
  while( ! bEOS )
  {
    //===== get packet =====
    RNOK  ( m_pcReadBitstream->extractPacket( pcBinData, bEOS ) );
    if    ( bEOS )
    {
      RNOK( m_pcReadBitstream->releasePacket( pcBinData ) );
      pcBinData = NULL;
      continue;
    }

    //===== get packet description =====
    RNOK( m_pcH264AVCPacketAnalyzer->process( pcBinData, cPacketDescription, pcScalableSei ) );
    ROT ( pcScalableSei );
    ROT ( cPacketDescription.ApplyToNext );


    //===== get packet size =====
    while( pcBinData->data()[ pcBinData->size() - 1 ] == 0x00 )
    {
      RNOK( pcBinData->decreaseEndPos( 1 ) ); // remove zero at end
    }


    //==== get parameters =====
    {
      uiPacketSize  = 4 + pcBinData->size();
      uiDId         = cPacketDescription.Layer;
//prefix unit{{
			if(cPacketDescription.NalUnitType != NAL_UNIT_CODED_SLICE && cPacketDescription.NalUnitType != NAL_UNIT_CODED_SLICE_IDR)
				uiTId         = cPacketDescription.Level;
//prefix unit}}
			uiQId         = cPacketDescription.FGSLayer;
      uiPId         = cPacketDescription.uiPId;

      //----- check whether next NAL unit is a suffix NAL unit -----
      if( cPacketDescription.NalUnitType == NAL_UNIT_CODED_SLICE ||
        cPacketDescription.NalUnitType == NAL_UNIT_CODED_SLICE_IDR )
      {
				Int                     iStreamPos        = 0;
				h264::SEI::SEIMessage*  pcScalableSeiTemp = 0;
				BinData*                pcBinDataTemp     = 0;
				h264::PacketDescription cPacketDescriptionTemp;
				RNOK( m_pcReadBitstream         ->getPosition   ( iStreamPos ) );
				RNOK( m_pcReadBitstream         ->extractPacket ( pcBinDataTemp, bEOS ) );
				ROT ( bEOS );
				RNOK( m_pcH264AVCPacketAnalyzer ->process       ( pcBinDataTemp, cPacketDescriptionTemp, pcScalableSeiTemp ) );
				ROT ( pcScalableSeiTemp );
				if  ((cPacketDescriptionTemp.NalUnitType == NAL_UNIT_CODED_SLICE_SCALABLE  ||
					cPacketDescriptionTemp.NalUnitType == NAL_UNIT_CODED_SLICE_IDR_SCALABLE ) &&
					cPacketDescriptionTemp.Layer       == 0 &&
					cPacketDescriptionTemp.FGSLayer    == 0 )
				{
					bNextIsSuffix = true;
					uiTId         = cPacketDescriptionTemp.Level;
				}
		//----- increment number of AVC slices -----
				if( cPacketDescription.uiFirstMb == 0 )
				{
					uiNumAVCPics++;
				}
				//----- release packet and reset stream -----
				if( pcBinDataTemp )
				{
					RNOK( m_pcReadBitstream->releasePacket( pcBinDataTemp ) );
					pcBinDataTemp = 0;
				}
				RNOK  ( m_pcReadBitstream->setPosition  ( iStreamPos ) );
      }
      else if( bNextIsSuffix )
      {
        bNextIsSuffix = false;
      }
    }
    ROT( uiDId > uiTargetLayer );
    ROF( uiPId < MAX_QLAYERS   );

    //===== store data =====
    if( uiDId < uiTargetLayer || uiQId == 0 )
    {
      ruiBLRate                 += uiPacketSize;
    }
    else if( uiQId == 1 && uiNumAVCPics == 1 && ! bNoSpecialFirstFrame )
    {
      ruiFGSAU0Rate             += uiPacketSize;
    }
    else
    {
      aauiTLRate[uiTId][uiQId]  += uiPacketSize;
      auiQLRate [uiPId]         += uiPacketSize;
      rbQualityLayerPresent      = rbQualityLayerPresent || uiPId != 0; 
    }

    //===== release packet =====
    if( pcBinData )
    {
      RNOK( m_pcReadBitstream->releasePacket( pcBinData ) );
      pcBinData = NULL;
    }
  } // end of while( ! bEOS )


  //===== get quality level automatically =====
  if( ! rbQualityLayerPresent )
  {
    auiQLRate[0] = 0;
    for( uiTId = 0; uiTId < MAX_TLAYERS;        uiTId++ )
      for( uiQId = 1; uiQId < MAX_QUALITY_LEVELS; uiQId++ )
      {

⌨️ 快捷键说明

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