h264avcdecoder.cpp

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

CPP
1,899
字号

// 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;

    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();
	
	if( eNalUnitType == NAL_UNIT_CODED_SLICE || eNalUnitType == NAL_UNIT_CODED_SLICE_IDR )
	{//JVT-S036 lsj
		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->getNalRefIdc     (),
                                              m_pcNalUnitParser->getLayerId       (),
                                              m_pcNalUnitParser->getTemporalLevel (),
                                              m_pcNalUnitParser->getQualityLevel  (),
                                              pcSliceHeader,
                                              m_uiFirstFragmentPPSId,
                                              m_uiFirstFragmentNumMbsInSlice,
                                              m_bFirstFragmentFGSCompSep
											  ,UnitAVCFlag                //JVT-S036 lsj
                                              ) );
      //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++;
          }          
      }
      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 )
      {
        if(! m_bCheckNextSlice )
          // skipped, without looking further
          bFinishChecking = true;

        //manu.mathew@samsung : memory leak fix
        if( pcSliceHeader )
          delete pcSliceHeader;
        //--
        return Err::m_nOK;
      }

      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;

        printf("   >> same frame.\n");

        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;
#if MULTIPLE_LOOP_DECODING
          m_abCompletlyDecodeBaseLayer[m_iLastLayerIdx] = false;
#endif
        }
        else
        {
          m_auiBaseLayerId[m_iLastLayerIdx]      = pcSliceHeader->getBaseLayerId();
          m_auiBaseQualityLevel[m_iLastLayerIdx] = pcSliceHeader->getBaseQualityLevel();
#if MULTIPLE_LOOP_DECODING
          m_abCompletlyDecodeBaseLayer[m_iLastLayerIdx] = pcSliceHeader->getSPS().getAlwaysDecodeBaseLayer();
#endif
        }
      }

      m_bCheckNextSlice = true;
    }
  }
  
  if( bEos || ( m_bCheckNextSlice && (m_iFirstLayerIdx == (Int)m_pcNalUnitParser->getLayerId() ||
      ((Int)m_pcNalUnitParser->getLayerId() > m_iFirstLayerIdx && m_iPrevPoc != slicePoc) ) 
      && slicePoc != m_iFirstSlicePoc )) //JVT-P031
  {
	// 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;

    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] );
#if MULTIPLE_LOOP_DECODING
          setCompletelyDecodeLayer( m_abCompletlyDecodeBaseLayer[1] );
#endif
        }
        else
        {
          m_apcMCTFDecoder[0]->setQualityLevelForPrediction( m_auiBaseQualityLevel[1] );
#if MULTIPLE_LOOP_DECODING
          m_apcMCTFDecoder[0]->setCompletelyDecodeLayer( m_abCompletlyDecodeBaseLayer[1] );
#endif
        }
      }

      for( Int iLayer = (m_iFirstLayerIdx == 0) ? 1 : m_iFirstLayerIdx; 
        iLayer <= m_iLastLayerIdx - 1; iLayer ++ )
      {
        m_apcMCTFDecoder[iLayer]->setQualityLevelForPrediction( m_auiBaseQualityLevel[iLayer + 1] );
#if MULTIPLE_LOOP_DECODING
        m_apcMCTFDecoder[iLayer]->setCompletelyDecodeLayer( m_abCompletlyDecodeBaseLayer[iLayer + 1] );
#endif
      }
    }

    m_bDependencyInitialized = true;
  }

  if( pcSliceHeader != NULL )
    delete pcSliceHeader;

  return Err::m_nOK;
}

//JVT-P031
Void H264AVCDecoder::initNumberOfFragment()
{
    UInt uiLayer;
    for(uiLayer = 0; uiLayer < MAX_LAYERS; uiLayer++)
    {
        m_uiNumberOfFragment[uiLayer] = 0;
    }
}
Void H264AVCDecoder::getDecodedResolution(UInt &uiLayerId)
{
 UInt uiSPSId = 0;
 UInt uiX     = 0;
 UInt uiY     = 0;
 UInt uiMBX   = 0;
 UInt uiMBY   = 0;
 SequenceParameterSet *rcSPS;

 uiSPSId = 0;
 uiMBX = 0;
 uiMBY = 0;
 UInt uiSPS = 0;
 while(uiSPS < m_uiNumberOfSPS)
 {
   if(m_pcParameterSetMng->isValidSPS(uiSPSId))
   {
    m_pcParameterSetMng->get(rcSPS,uiSPSId);
    uiX = rcSPS->getFrameWidthInMbs();
    uiY = rcSPS->getFrameHeightInMbs();
    if(uiX >= uiMBX && uiY >= uiMBY) //FIX_FRAG_CAVLC
    {
       uiMBX = uiX;
       uiMBY = uiY;
       uiLayerId = rcSPS->getLayerId();
    }
    uiSPS++;
   }
   uiSPSId++;
 }

}
//~JVT-P031
//TMM_EC{{
Bool
H264AVCDecoder::checkSEIForErrorConceal()
{
	Bool	ret	=	true;
	UInt	i	=	0;
	if ( m_bNotSupport)
	{
		return	false;
	}
	if ( m_uiNumLayers > 2 || m_uiNumLayers == 0 )
	{
		return	false;
	}
	for ( i=0; i<m_uiNumLayers; i++)
	{
		if ( m_uiDecompositionStages[i] == 0)
		{
			return	false;
		}
	}
	return	ret;
}

ErrVal
H264AVCDecoder::checkSliceGap( BinDataAccessor*  pcBinDataAccessor,
                               MyList<BinData*>& cVirtualSliceList 
							   ,Bool&			 UnitAVCFlag	//JVT-S036 lsj 
							 )
{
  Bool bEos;
  NalUnitType eNalUnitType;
  SliceHeader* pcSliceHeader = NULL;
  Int slicePoc;

  ROT( NULL == pcBinDataAccessor );

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

	UInt	frame_num;
	UInt	uiLayerId;
	UInt	uiPocLsb;
	UInt	uiMaxFrameNum;
	UInt	uiMaxPocLsb;

  if( ! bEos )

⌨️ 快捷键说明

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