extractor.cpp

来自「JVT-S203 contains the JSVM 6 reference s」· C++ 代码 · 共 1,755 行 · 第 1/5 页

CPP
1,755
字号
    }
	uiExtLayer = uiLayer;
  }
  ERROR( uiExtLayer==MSYS_UINT_MAX, "Spatial resolution of extraction/inclusion point not supported" );
  m_pcExtractorParameter->setLayer(uiExtLayer);
  //--- level ---
  for( uiLevel = 0; uiLevel <= MAX_DSTAGES; uiLevel++ )
  {
    //if( rcExtPoint.dFrameRate == (Double)(1<<uiLevel)*m_cScalableStreamDescription.getFrameRateUnit() )
    if( rcExtPoint.dFrameRate == m_cScalableStreamDescription.getFrameRate(uiExtLayer, uiLevel) )
    {
      uiExtLevel = uiLevel;
      break;
    }
  }
  m_pcExtractorParameter->setLevel(uiExtLevel);
  ERROR( uiExtLevel==MSYS_UINT_MAX, "Temporal resolution of extraction/inclusion point not supported" );
  ERROR( uiExtLevel>m_cScalableStreamDescription.getMaxLevel(uiExtLayer), "Spatio-temporal resolution of extraction/inclusion point not supported" );
  //--- target number of bytes -----
  //Double  dTargetNumExtBytes  = rcExtPoint.dBitRate / 8.0 * 1000.0 / ((Double)(1<<uiExtLevel)*m_cScalableStreamDescription.getFrameRateUnit() ) * (Double)m_cScalableStreamDescription.getNumPictures(uiExtLayer,uiExtLevel);

  // Calculate TartgetNumExtBytes consider ROI ICU/ETRI DS
  Double RoiNum;
  if (m_pcExtractorParameter->getROIFlag())
	  RoiNum = 1.0;
  else
	  RoiNum = m_pcH264AVCPacketAnalyzer->m_uiNumSliceGroupsMinus1 + 1.0;


  Double  dTargetNumExtBytes  = rcExtPoint.dBitRate / 8.0 * 1000.0 / m_cScalableStreamDescription.getFrameRate(uiExtLayer,uiExtLevel)  * (Double)m_cScalableStreamDescription.getNumPictures(uiExtLayer,uiExtLevel);
  dTargetNumExtBytes /= RoiNum;

  m_pcExtractorParameter->setTargetRate(dTargetNumExtBytes);
  //===== get and set required base layer packets ======
  Double  dRemainingBytes     = dTargetNumExtBytes;
  for( uiLayer = 0; uiLayer <= uiExtLayer; uiLayer++ )
  for( uiLevel = 0; uiLevel <= uiExtLevel; uiLevel++ )
  {
     Int64 i64NALUBytes                    = m_cScalableStreamDescription.getNALUBytes( uiLayer, uiLevel, 0 );
	 if (dRemainingBytes<(Double)i64NALUBytes)
	 {
		 // J.Reichel -> CGS and FGS supports (note this will work only if the uiLevel for the framerate doesn't change for the different layer)
		 // not enough bit for a layer, if the previous layer was a CGS, then it should become the new max layer
		 if( uiExtLayer>0 &&
			 rcExtPoint.uiWidth  == m_cScalableStreamDescription.getFrameWidth (uiLayer-1) &&
			 rcExtPoint.uiHeight == m_cScalableStreamDescription.getFrameHeight(uiLayer-1)    )
		 {
			uiExtLayer=uiLayer-1;
			break;
		 }
	 }
     dRemainingBytes                      -= (Double)i64NALUBytes;
     m_aadTargetSNRLayer[uiLayer][uiLevel] = 0;
	 m_pcExtractorParameter->setMaxFGSLayerKept(0);

  }
  if( dRemainingBytes < 0.0 )
  {
    WARNING( true, "Bit-rate overflow for extraction/inclusion point" );
    return Err::m_nOK;
  }


  //===== set maximum possible bytes for included layers ======
  for( uiLayer = 0; uiLayer <  uiExtLayer; uiLayer++ )
  {
    for( uiLevel = 0; uiLevel <= uiExtLevel; uiLevel++ )
    {
      for( uiFGSLayer = 1; uiFGSLayer < MAX_QUALITY_LEVELS; uiFGSLayer++ )
      {
        Int64 i64NALUBytes = m_cScalableStreamDescription.getNALUBytes( uiLayer, uiLevel, uiFGSLayer );
        if( (Double)i64NALUBytes <= dRemainingBytes )
        {
          dRemainingBytes                      -= (Double)i64NALUBytes;
          m_aadTargetSNRLayer[uiLayer][uiLevel] = (Double)uiFGSLayer;
		  m_pcExtractorParameter->setMaxFGSLayerKept(uiFGSLayer);
        }
        else
        {
          //====== set fractional FGS layer and exit =====
          Double  dFGSLayer = dRemainingBytes / (Double)i64NALUBytes;
          m_aadTargetSNRLayer[uiLayer][uiLevel] += dFGSLayer;
		      m_pcExtractorParameter->setMaxFGSLayerKept(uiFGSLayer);
			    m_pcExtractorParameter->setBitrate( rcExtPoint.dBitRate );
          return Err::m_nOK;
        }
      }
    }
  }


  //===== set FGS layer for current layer =====
  for( uiFGSLayer = 1; uiFGSLayer < MAX_QUALITY_LEVELS; uiFGSLayer++ )
  {
    Int64 i64FGSLayerBytes = 0;
    for( uiLevel = 0; uiLevel <= uiExtLevel; uiLevel++ )
    {
      i64FGSLayerBytes += m_cScalableStreamDescription.getNALUBytes( uiExtLayer, uiLevel, uiFGSLayer );
    }
    if( (Double)i64FGSLayerBytes <= dRemainingBytes )
    {
      dRemainingBytes -= (Double)i64FGSLayerBytes;
      for( uiLevel = 0; uiLevel <= uiExtLevel; uiLevel++ )
      {
        m_aadTargetSNRLayer[uiExtLayer][uiLevel] = (Double)uiFGSLayer;
		m_pcExtractorParameter->setMaxFGSLayerKept(uiFGSLayer);
      }
    }
    else
    {
      Double dFGSLayer = dRemainingBytes / (Double)i64FGSLayerBytes;
      for( uiLevel = 0; uiLevel <= uiExtLevel; uiLevel++ )
      {
        m_aadTargetSNRLayer[uiExtLayer][uiLevel] += dFGSLayer;
		m_pcExtractorParameter->setMaxFGSLayerKept(uiFGSLayer);
      }
// BUG_FIX liuhui{
      m_pcExtractorParameter->setBitrate( rcExtPoint.dBitRate );
// BUG_FIX liuhui}
      return Err::m_nOK;
    }
  }
  WARNING( dRemainingBytes>0.0, "Bit-rate underflow for extraction/inclusion point" );


#undef ERROR
#undef WARNING

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


// Keep ROI NAL ICU/ETRI DS
Int Extractor::CurNalKeepingNeed(h264::PacketDescription cPacketDescription
								 , const ExtractorParameter::Point& rcExtPoint)
{	
	Bool bIsDataNal = false;
	if (
		(1 <= cPacketDescription.NalUnitType && cPacketDescription.NalUnitType <= 5)
		|| (cPacketDescription.NalUnitType == 20 || cPacketDescription.NalUnitType == 21)	
		)
	{
		bIsDataNal		= true;		
	}


	Int iExtactionROINum		=   m_pcExtractorParameter->getExtractedNumROI();
	Bool      bROIFlag			=   m_pcExtractorParameter->getROIFlag();

	int keepingNAL = -1;
	if( bROIFlag == true && bIsDataNal == true )
	{				
		for(int i=0; i<iExtactionROINum; i++)
		{				
			Int SG_ID =-1;
			for(int sg_id=0;sg_id<8;sg_id++)
			{
				if(cPacketDescription.uiFirstMb == m_pcH264AVCPacketAnalyzer->uiaAddrFirstMBofROIs[cPacketDescription.PPSid][sg_id])
				{
					SG_ID=sg_id;
					break;
				}
			} // end for check sg (until 8)
			
			Int ROI_ID = getROI_ID(cPacketDescription.Layer,SG_ID);
			if(ROI_ID !=-1 &&rcExtPoint.uiROI[i] ==ROI_ID )
			{
				keepingNAL = 1;				
			}
			if( keepingNAL == 1 )
				break;
		}	// end for 		
	}	// end if (bROIFlag == true.. )

	else 
		return true;
	

	return (keepingNAL == 1);	
}



ErrVal
Extractor::xExtractPoints()
{
  UInt  uiNumInput    = 0;
  UInt  uiNumKept     = 0;
  UInt  uiNumCropped  = 0;
  Bool  bKeep         = false;
  Bool  bApplyToNext  = false;
  Bool  bEOS          = false;
  Bool  bCrop         = false;

  UInt  uiLayer       = 0;
  UInt  uiLevel       = 0;
  UInt  uiFGSLayer    = 0;
  UInt  uiPacketSize  = 0;
  UInt  uiShrinkSize  = 0;
	UInt  uiWantedLayer = m_pcExtractorParameter->getLayer();
	UInt  uiWantedLevel = m_pcExtractorParameter->getLevel();

// BUG_FIX liuhui{
  UInt uiWantedScalableLayer = MSYS_UINT_MAX;
  Double dWantedFGSLayer = (Double)m_pcExtractorParameter->getMaxFGSLayerKept();
  for( Int iDependencyId = (Int)uiWantedLayer; iDependencyId >= 0; iDependencyId--)
  {
    for( Int iTempLevel = (Int)uiWantedLevel; iTempLevel >= 0; iTempLevel-- )
	{
	  UInt uiTmpFGSValue = (UInt) ceil( m_aadTargetSNRLayer[iDependencyId][iTempLevel] );
	  if( uiTmpFGSValue == dWantedFGSLayer )
	  {
	    dWantedFGSLayer = m_aadTargetSNRLayer[iDependencyId][iTempLevel];
		Int iFGSLayer;
    for( iFGSLayer = (Int)uiTmpFGSValue; iFGSLayer >= 0; iFGSLayer-- )
		{  //the FGS layer may not exist
	      if( getScalableLayer(iDependencyId, iTempLevel, (UInt)iFGSLayer ) != MSYS_UINT_MAX )
		    break;
		}
		uiTmpFGSValue = ( iFGSLayer < 0 ) ? 0 : (UInt) iFGSLayer;
		uiWantedScalableLayer = getScalableLayer(iDependencyId, iTempLevel, uiTmpFGSValue );
		if( dWantedFGSLayer > (Double) uiTmpFGSValue )
		  dWantedFGSLayer = (Double) uiTmpFGSValue;
		if( getBaseLayerAVCCompatible() && iDependencyId == 0 && iTempLevel == 0 )
		  uiWantedScalableLayer = getScalableLayer((UInt)iDependencyId, m_cScalableStreamDescription.getStdAVCOffset(), uiTmpFGSValue );
		break;
	  }
	}
	if( uiWantedScalableLayer != MSYS_UINT_MAX )
	  break;
  }
// BUG_FIX liuhui}

  //JVT-P031
  UInt uiNumFrame[MAX_LAYERS];
  UInt* auiBytesPassed[MAX_LAYERS][MAX_FGS_LAYERS];
  UInt uiFrame;
  for(uiLayer=0; uiLayer < MAX_LAYERS; uiLayer++)
  {
      uiNumFrame[uiLayer] = 0;
      for(uiFGSLayer = 0; uiFGSLayer < MAX_FGS_LAYERS; uiFGSLayer++)
      {
              auiBytesPassed[uiLayer][uiFGSLayer] = new UInt[m_auiNbImages[uiLayer]];
              for(uiFrame = 0; uiFrame < m_auiNbImages[uiLayer]; uiFrame++)
              {
                auiBytesPassed[uiLayer][uiFGSLayer][uiFrame] = 0;
              }
      }
  }
  //~JVT-P031

RNOK( m_pcH264AVCPacketAnalyzer->init() );

  // consider ROI ICU/ETRI DS
  const MyList<ExtractorParameter::Point>&          rcExtList   = m_pcExtractorParameter->getExtractionList();
  ROT( rcExtList.size() != 1 );
  MyList<ExtractorParameter::Point>::const_iterator cIter       = rcExtList.begin ();
  MyList<ExtractorParameter::Point>::const_iterator cEnd        = rcExtList.end   ();
  const ExtractorParameter::Point&                  rcExtPoint  = *cIter;

  Int		Count = 0;


  printf("\n\n============Extraction Information======");
  printf("\nExtracted spatail layer  : %dx%d",   rcExtPoint.uiWidth, rcExtPoint.uiHeight);
  printf("\nExtracted temporal rate  : %2.0ff/s",   rcExtPoint.dFrameRate);


  RNOK( m_pcH264AVCPacketAnalyzer->init() );

  while( ! bEOS )
  {
    //=========== get packet ===========
    BinData*  pcBinData;
// JVT-S080 LMI {
    BinData * pcBinDataSEILysNotPreDepChange;
    ROT( NULL == ( pcBinDataSEILysNotPreDepChange = new BinData ) ); 
    Bool bWriteBinDataSEILysNotPreDepChange = false;
	Bool bWriteBinData = true;
// JVT-S080 LMI }

    RNOK( m_pcReadBitstream->extractPacket( pcBinData, bEOS ) );
    if( bEOS )
    {
      RNOK( m_pcReadBitstream->releasePacket( pcBinData ) );
      pcBinData = NULL;
      continue;

⌨️ 快捷键说明

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