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

📄 h264avcdecoder.cpp

📁 jsvm开发代码包括抽样,编码,抽取,解码等一系列功能,可以做工具或研究用
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  m_avcRewriteBufsize         = 0;
  m_avcRewriteFlag            = false;
#endif

  m_bInitDone = false;
  //NS leak fix begin
 for ( UInt i=0; i< m_uiNumLayers; i++)
  {
    if (m_pauiPocInGOP[i])       delete	[] m_pauiPocInGOP[i];
    if (m_pauiFrameNumInGOP[i])  delete	[] m_pauiFrameNumInGOP[i];
    if (m_pauiTempLevelInGOP[i]) delete	[] m_pauiTempLevelInGOP[i];
  }
  //NS leak fix end
  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&          riSlicePoc )
{
  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 );
  }

   //EIDR bug-fix {
	if(rcSliceHeader.getLayerId() == 0 )
	{
		rcSliceHeader.setInIDRAccess(rcSliceHeader.isIdrNalUnit());
	}
	else
	{
		rcSliceHeader.setInIDRAccess(m_pcTempSliceHeader?m_pcTempSliceHeader->getInIDRAccess():false);
	}
   //EIDR bug-fix }

 pcLocalPocCalculator->calculatePoc( rcSliceHeader );

	riSlicePoc = rcSliceHeader.getPoc();

  pcLocalPocCalculator->destroy();

  return Err::m_nOK;
}


ErrVal H264AVCDecoder::xInitParameters(SliceHeader* pcSliceHeader)
{
  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++;
    SequenceParameterSet * rcSPS;
    m_pcParameterSetMng->get(rcSPS,uiSPSId);
    rcSPS->setLayerId(pcSliceHeader->getLayerId());
  }
  return Err::m_nOK;
}

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

  ROT( NULL == pcBinDataAccessor );

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

  if(m_uiNumOfNALInAU == 0)
  {
    //new AU: initialization
    m_bDependencyInitialized = false;
    m_bFGSRefInAU = false;
    //if(!bEos)                     MGS fix by Heiko Schwarz
    //  m_bCGSSNRInAU = false;      MSG fix by Heiko Schwarz

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

  if( ! bEos )
  {
    m_pcNalUnitParser->setCheckAllNALUs(true);
    UInt uiNumBytesRemoved;
    RNOK( m_pcNalUnitParser->initNalUnit( pcBinDataAccessor,  uiNumBytesRemoved ) );
    m_pcNalUnitParser->setCheckAllNALUs(false);

    eNalUnitType = m_pcNalUnitParser->getNalUnitType();
    if(!m_bDependencyInitialized)
      m_uiNumOfNALInAU++;//JVT-P031 
    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 &&
				eNalUnitType != NAL_UNIT_PREFIX )//prefix unit
    {
      if(m_uiNumOfNALInAU > 1)
      {
        m_uiNumOfNALInAU--;
        m_bDependencyInitialized = true;
      }
       m_bCheckNextSlice = false;
       bFinishChecking = true;

       return Err::m_nOK;
    }
    else
    {
      // read the slice header
      //JVT-P031
//prefix unit{{
    if( eNalUnitType == NAL_UNIT_PREFIX )
		{
			if(m_bCheckNextSlice)
			{
				if(m_uiNumOfNALInAU > 1)
				{
					m_uiNumOfNALInAU--;
					m_bDependencyInitialized = true;
				} 
				m_bCheckNextSlice = false;
				bFinishChecking = true;

				return Err::m_nOK;
			}
			else
			{
				SequenceParameterSet* pcSPS;
				PictureParameterSet*  pcPPS;
				RNOK( m_pcParameterSetMng ->get    ( pcPPS, 0) );
				RNOK( m_pcParameterSetMng ->get    ( pcSPS, 0) );
				if(m_pcPrefixSliceHeader)
				{
					delete m_pcPrefixSliceHeader;
					m_pcPrefixSliceHeader = NULL;
				}
				m_pcPrefixSliceHeader = new SliceHeader(*pcSPS, *pcPPS);
				RNOK( m_pcSliceReader->readSliceHeaderPrefix( m_pcNalUnitParser->getNalUnitType   (),
																m_pcNalUnitParser->getNalRefIdc     (),
																m_pcNalUnitParser->getLayerId		  (),
																m_pcNalUnitParser->getQualityLevel  (),
																m_pcNalUnitParser->getUseBasePredFlag(),
																m_pcPrefixSliceHeader
																) );

				return Err::m_nOK;
			}

		}
		else
//prefix unit}}
		{
				RNOK( m_pcSliceReader->readSliceHeader( m_pcNalUnitParser,
																								pcSliceHeader,
																								m_uiFirstFragmentNumMbsInSlice,
																								m_bFirstFragmentFGSCompSep
																								) );

//prefix unit{{
					if(m_pcPrefixSliceHeader )
					{
						if(eNalUnitType == NAL_UNIT_CODED_SLICE ||eNalUnitType == NAL_UNIT_CODED_SLICE_IDR)
						{
							pcSliceHeader->copyPrefix(*m_pcPrefixSliceHeader);
						}
						delete m_pcPrefixSliceHeader;
						m_pcPrefixSliceHeader = NULL;
					}
//prefix unit}}

				//To detect if fragments have been lost or previously extracted
				if(pcSliceHeader->getFragmentedFlag())
				{
						m_uiNumberOfFragment[pcSliceHeader->getLayerId()][pcSliceHeader->getQualityLevel()] ++;
				}

				if(pcSliceHeader->getFragmentOrder() == 0)
				{
						xInitParameters(pcSliceHeader);
				}
				else
				{
					//if next fragments, skip
					if( pcSliceHeader != NULL )
							delete pcSliceHeader;

					return Err::m_nOK;
				}
				//~JVT-P031

				// F slices are also ignored
				if( pcSliceHeader->getSliceType() == F_SLICE )
				{
					m_bFGSRefInAU = true;

					//manu.mathew@samsung : memory leak fix
					if( pcSliceHeader )
						delete pcSliceHeader;
					//--
					return Err::m_nOK;
				}
				m_bCGSSNRInAU = (m_bCGSSNRInAU || pcSliceHeader->getQualityLevel() != 0);

			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

				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;
					m_iFirstLayerIdx = m_pcNalUnitParser->getLayerId();
				}
				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();

					if( pcSliceHeader->getBaseLayerId() && pcSliceHeader->getBaseLayerId() != MSYS_UINT_MAX ) //prefix unit
					{
						m_apcMCTFDecoder[pcSliceHeader->getBaseLayerId()]->setQualityLevelForPrediction( pcSliceHeader->getBaseQualityLevel() );
					}
					else 
					{
						setQualityLevelForPrediction( pcSliceHeader->getBaseQualityLevel() );
					}
				}
				}

				m_bCheckNextSlice = true;
			}
    }
  }

  if( bEos || slicePoc != m_iFirstSlicePoc)
  {
	// ROI DECODE ICU/ETRI
	if (-1 != m_iCurNalSpatialLayer && -1 != m_iNextNalSpatialLayer)
		bFinishChecking   = true;
    // setup the state information for the previous slices
    m_bCheckNextSlice = false;
//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] );
        }
      }

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

    m_bDependencyInitialized = true;
  }

  if( pcSliceHeader != NULL )
 {
  delete m_pcTempSliceHeader;  //EIDR bug-fix
	m_pcTempSliceHeader = pcSliceHeader;//EIDR bug-fix
  }

  return Err::m_nOK;
}

//JVT-P031
Void H264AVCDecoder::initNumberOfFragment()
{
  UInt uiLayer, uiQualityLevel;

⌨️ 快捷键说明

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