h264avcdecoder.cpp

来自「JMVM MPEG MVC/3DAV 测试平台 国际通用标准」· C++ 代码 · 共 1,794 行 · 第 1/5 页

CPP
1,794
字号
  m_pcSliceHeader_backup  = NULL; // JVT-Q054 Red. Pic

  m_pcSliceReader         = NULL;
  m_pcSliceDecoder        = NULL;
  m_pcFrameMng            = NULL;
  m_pcNalUnitParser       = NULL;
  m_pcControlMng          = NULL;
  m_pcLoopFilter          = NULL;
  m_pcHeaderSymbolReadIf  = NULL;
  m_pcParameterSetMng     = NULL;
  m_pcPocCalculator       = NULL;

	m_bNewSPS               = false;
	if( m_pcVeryFirstSliceHeader )
  delete m_pcVeryFirstSliceHeader;
  m_pcVeryFirstSliceHeader = NULL;

  for( UInt uiLayer = 0; uiLayer < MAX_LAYERS; uiLayer++ )
  {
    //m_apcMCTFDecoder[uiLayer] = NULL;
  }

  m_bInitDone = false;
  
  return Err::m_nOK;
}



ErrVal H264AVCDecoder::create( H264AVCDecoder*& rpcH264AVCDecoder )
{
  rpcH264AVCDecoder = new H264AVCDecoder;
  ROT( NULL == rpcH264AVCDecoder );
  return Err::m_nOK;
}


ErrVal
H264AVCDecoder::calculatePoc( NalUnitType   eNalUnitType,
                              SliceHeader&  rcSliceHeader,
                              Int&          slicePoc )
{
  PocCalculator *pcLocalPocCalculator;

  if( eNalUnitType == NAL_UNIT_CODED_SLICE ||  eNalUnitType == NAL_UNIT_CODED_SLICE_IDR )
  {
    m_pcPocCalculator->copy( pcLocalPocCalculator );
  }
  else
  {
    //m_apcMCTFDecoder[m_iFirstLayerIdx]->getPocCalculator()->copy( pcLocalPocCalculator );
  }

  pcLocalPocCalculator->calculatePoc( rcSliceHeader );

  slicePoc = rcSliceHeader.getPoc();

  pcLocalPocCalculator->destroy();

  return Err::m_nOK;
}


// not tested with multiple slices
ErrVal
H264AVCDecoder::checkSliceLayerDependency( BinDataAccessor*  pcBinDataAccessor,
                                           Bool&             bFinishChecking
										    ,Bool&		     UnitAVCFlag     ///JVT-S036  lsj
										 )
{
  Bool bEos;
  NalUnitType eNalUnitType;
  SliceHeader* pcSliceHeader = NULL;
  Int slicePoc;

  bFinishChecking = false;
  ROT( NULL == pcBinDataAccessor );

  bEos = ( NULL == pcBinDataAccessor->data() ) || ( 0 == pcBinDataAccessor->size() );
  slicePoc = 0;

  if(bEos)
  {
	if (-1 == m_iNextNalSpatialLayer)
		m_bCurNalIsEndOfPic = true;
    m_bDependencyInitialized = true; //JVT-T054
    bFinishChecking = true;
    return Err::m_nOK;
  }

  if (m_bDependencyInitialized)
  {
	  UInt uiNumBytesTemp; 

	  RNOK( m_pcNalUnitParser->initNalUnit( pcBinDataAccessor, NULL, uiNumBytesTemp ) );

	  eNalUnitType = m_pcNalUnitParser->getNalUnitType();

	  // if SLICE
	  if( eNalUnitType == NAL_UNIT_CODED_SLICE        ||
        eNalUnitType == NAL_UNIT_CODED_SLICE_IDR      || 
        eNalUnitType == NAL_UNIT_CODED_SLICE_SCALABLE || 
        eNalUnitType == NAL_UNIT_CODED_SLICE_IDR_SCALABLE )
	  {
		  // if checked first and second Spatial Layer
		if (-1 != m_iCurNalSpatialLayer && -1 != m_iNextNalSpatialLayer)
		{
			bFinishChecking = true;
			return Err::m_nOK;		
		}
	  }

	  else	// not SLICE
	  {
			//bFinishChecking = true;
			return Err::m_nOK;	
	  }
  }	// end 

  if( ! bEos )
  {
    //m_uiNumOfNALInAU++;//JVT-P031
    m_pcNalUnitParser->setCheckAllNALUs(true);//JVT-P031
    UInt uiNumBytesRemoved; //FIX_FRAG_CAVLC
    RNOK( m_pcNalUnitParser->initNalUnit( pcBinDataAccessor, NULL, uiNumBytesRemoved ) ); //FIX_FRAG_CAVLC
    m_pcNalUnitParser->setCheckAllNALUs(false);//JVT-P031

    eNalUnitType = m_pcNalUnitParser->getNalUnitType();
//JVT-T054{
    if((m_uiNumOfNALInAU == 0 && eNalUnitType != NAL_UNIT_SEI) || 
      eNalUnitType == NAL_UNIT_CODED_SLICE        ||
        eNalUnitType == NAL_UNIT_CODED_SLICE_IDR      || 
        eNalUnitType == NAL_UNIT_CODED_SLICE_SCALABLE || 
        eNalUnitType == NAL_UNIT_CODED_SLICE_IDR_SCALABLE)
    {
      if(!m_bDependencyInitialized)
      m_uiNumOfNALInAU++;//JVT-P031
    }
//JVT-T054}

	if( eNalUnitType == NAL_UNIT_CODED_SLICE || eNalUnitType == NAL_UNIT_CODED_SLICE_IDR )
	{//JVT-S036 
		UnitAVCFlag = true;
	}

    if( eNalUnitType != NAL_UNIT_CODED_SLICE        &&
        eNalUnitType != NAL_UNIT_CODED_SLICE_IDR      && 
        eNalUnitType != NAL_UNIT_CODED_SLICE_SCALABLE && 
        eNalUnitType != NAL_UNIT_CODED_SLICE_IDR_SCALABLE )
    {
      // NAL units other than slices are ignored
      if(! m_bCheckNextSlice )
        // skipped, without looking further
        bFinishChecking = true;

      return Err::m_nOK;
    }
    else
    {
      // read the slice header
      //JVT-P031								  
      RNOK( m_pcSliceReader->readSliceHeader( m_pcNalUnitParser->getNalUnitType   (),
                                              m_pcNalUnitParser->getSvcMvcFlag(),
                                              m_pcNalUnitParser->getIDRFlag(), //JVT-W035
                                              m_pcNalUnitParser->getAnchorPicFlag(),
                                              m_pcNalUnitParser->getViewId(),											
  											  m_pcNalUnitParser->getInterViewFlag(),  //JVT-W056  Samsung
											  m_pcNalUnitParser->getNalRefIdc     (),
                                              m_pcNalUnitParser->getLayerId       (),
 											  m_pcNalUnitParser->getTemporalLevel (),
                                              m_pcNalUnitParser->getQualityLevel  (),
                                              pcSliceHeader,
                                              m_uiFirstFragmentPPSId,
                                              m_uiFirstFragmentNumMbsInSlice,
                                              m_bFirstFragmentFGSCompSep
											  ,UnitAVCFlag                //JVT-S036 
                                              ) );
		if (pcSliceHeader==NULL)
		{
			bFinishChecking = true;
			return Err::m_nOK;    
		}


      
      //To detect if fragments have been lost or previously extracted
      if(pcSliceHeader->getFragmentedFlag())
      {
          m_uiNumberOfFragment[pcSliceHeader->getLayerId()]++;
      }
      if(pcSliceHeader->getFragmentOrder() == 0)
      {
          m_uiFirstFragmentPPSId = pcSliceHeader->getPicParameterSetId();
          m_uiFirstFragmentNumMbsInSlice = pcSliceHeader->getNumMbsInSlice();
          m_bFirstFragmentFGSCompSep = pcSliceHeader->getFgsComponentSep();
          //activate corresponding SPS
          PictureParameterSet * rcPPS;
          m_pcParameterSetMng->get(rcPPS,m_uiFirstFragmentPPSId);
          UInt uiSPSId = rcPPS->getSeqParameterSetId();
          Bool bFound = false;
          for(UInt ui = 0; ui < m_uiNumberOfSPS; ui++)
          {
              if(m_uiSPSId[ui] == uiSPSId)
              {
                  bFound = true;
                  break;
              }
          } 
          if(!bFound)
          {
              m_uiSPSId[m_uiNumberOfSPS] = uiSPSId;
              m_uiNumberOfSPS++;
//JVT-T054{
              SequenceParameterSet * rcSPS;
              m_pcParameterSetMng->get(rcSPS,uiSPSId);
              rcSPS->setLayerId(pcSliceHeader->getLayerId());
//JVT-T054}
          }          
      }
      else
      {
        if( pcSliceHeader != NULL )
            delete pcSliceHeader;
          
        return Err::m_nOK;      
      }
      //~JVT-P031

      calculatePoc( eNalUnitType, *pcSliceHeader, slicePoc );

	  // <-- ROI DECODE ICU/ETRI
	  // first NAL check
	  if (-1 == m_iCurNalSpatialLayer)
	  {
		  m_iCurNalSpatialLayer 	= m_pcNalUnitParser->getLayerId();
		  m_iCurNalPOC  			= slicePoc;
		  m_iCurNalFirstMb			= pcSliceHeader->getFirstMbInSlice();
		  
	  }
	  
	  // second NAL check
	  else if (-1 == m_iNextNalSpatialLayer)
	  {
		  m_iNextNalSpatialLayer	= m_pcNalUnitParser->getLayerId();
		  m_iNextNalPOC			= slicePoc;
		  
		  if (m_iCurNalSpatialLayer != m_iNextNalSpatialLayer)
			  m_bCurNalIsEndOfPic = true;
		  
		  if (m_iCurNalPOC != m_iNextNalPOC)
			  m_bCurNalIsEndOfPic = true;
		  
		  if( pcSliceHeader->getSliceType() == F_SLICE )
			  m_bCurNalIsEndOfPic = true;

		  Bool bNewFrame =false;
		  RNOK( pcSliceHeader->compareRedPic ( m_pcSliceHeader_backup, bNewFrame ) );
		  if(m_iCurNalFirstMb ==pcSliceHeader->getFirstMbInSlice())
			  m_bCurNalIsEndOfPic = true;	  
	  }
	  // --> ROI DECODE ICU/ETRI

      // F slices are also ignored
      if( pcSliceHeader->getSliceType() == F_SLICE )
      {
//JVT-T054{
        m_bFGSRefInAU = true;
//JVT-T054}
        if(! m_bCheckNextSlice )
          // skipped, without looking further
          bFinishChecking = true;

        //manu.mathew@samsung : memory leak fix
        if( pcSliceHeader )
          delete pcSliceHeader;
        //--
        return Err::m_nOK;
      }
//JVT-T054{
      if( pcSliceHeader->getQualityLevel() != 0)
      {
        m_bCGSSNRInAU = true;
      }
//JVT-T054}
      if( slicePoc == m_iLastPocChecked)
      {
		// ROI DECODE ICU/ETRI
		if (-1 != m_iCurNalSpatialLayer && -1 != m_iNextNalSpatialLayer)
		  bFinishChecking = true;

        // for the same picture with all its layers, we only check the dependency once		
        if( pcSliceHeader != NULL )
          delete pcSliceHeader;

        return Err::m_nOK;
      }

      if( ! m_bCheckNextSlice )
      {
        m_iFirstLayerIdx = m_pcNalUnitParser->getLayerId();

        m_iFirstSlicePoc = slicePoc;

        if( eNalUnitType == NAL_UNIT_CODED_SLICE ||  eNalUnitType == NAL_UNIT_CODED_SLICE_IDR )
          m_bBaseLayerAvcCompliant = true;
        else
          m_bBaseLayerAvcCompliant = false;
      }

      if( slicePoc == m_iFirstSlicePoc )
      {
        m_iLastLayerIdx = m_pcNalUnitParser->getLayerId();

        if (m_iLastLayerIdx == 0)
        {
          m_auiBaseLayerId[m_iLastLayerIdx]      = MSYS_UINT_MAX;
          m_auiBaseQualityLevel[m_iLastLayerIdx] = 0;
        }
        else
        {
          m_auiBaseLayerId[m_iLastLayerIdx]      = pcSliceHeader->getBaseLayerId();
          m_auiBaseQualityLevel[m_iLastLayerIdx] = pcSliceHeader->getBaseQualityLevel();
        }
      }

      m_bCheckNextSlice = true;
    }
  }

  if( bEos || ( m_bCheckNextSlice && slicePoc != m_iPrevPoc ) ) //JVT-T054
  {
	// ROI DECODE ICU/ETRI
	if (-1 != m_iCurNalSpatialLayer && -1 != m_iNextNalSpatialLayer)
		bFinishChecking   = true;
    // setup the state information for the previous slices	
    m_iPrevPoc = slicePoc; //JVT-P031
   // if(bEos) //JVT-P031
    m_bCheckNextSlice = false;
    m_iLastPocChecked = m_iFirstSlicePoc;
//JVT-T054{
    if(!bEos)
      decreaseNumOfNALInAU();
//JVT-T054}
    //m_apcMCTFDecoder[m_iLastLayerIdx]->setQualityLevelForPrediction( 3 );
    if( m_iFirstLayerIdx < m_iLastLayerIdx )
    {
      // set the base layer dependency
      if( m_iFirstLayerIdx == 0 )
      {
        if( m_bBaseLayerAvcCompliant )
        {
          setQualityLevelForPrediction( m_auiBaseQualityLevel[1] );
        }
        else
        {
          //m_apcMCTFDecoder[0]->setQualityLevelForPrediction( m_auiBaseQualityLevel[1] );
        }
      }

⌨️ 快捷键说明

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