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

📄 h264avcdecoder.cpp

📁 jsvm开发代码包括抽样,编码,抽取,解码等一系列功能,可以做工具或研究用
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  for( uiLayer = 0; uiLayer < MAX_LAYERS; uiLayer ++ )
  for( uiQualityLevel = 0; uiQualityLevel < MAX_QUALITY_LEVELS; uiQualityLevel ++)
  {
      m_uiNumberOfFragment[uiLayer][uiQualityLevel] = 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;
	}
	return	ret;
}

ErrVal
H264AVCDecoder::checkSliceGap( BinDataAccessor*  pcBinDataAccessor,
                               MyList<BinData*>& cVirtualSliceList )
{
  static  Bool  bFinished=false;//TMM_EC
  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;


//TMM_EC {{
  if ( bEos && !bFinished)
  {
    bFinished = true;
    goto bEOS;
  }
//TMM_EC }}

  if( ! bEos )
  {
    UInt uiNumBytesRemoved; //FIX_FRAG_CAVLC
//bug-fix suffix shenqiu{{
  //RNOK( m_pcNalUnitParser->initNalUnit( pcBinDataAccessor, NULL, uiNumBytesRemoved, true, false, true ) );
  RNOK( m_pcNalUnitParser->initNalUnit( pcBinDataAccessor, uiNumBytesRemoved, true, false, true ) );
//bug-fix suffix shenqiu}}
//prefix unit{{
	if(m_pcNalUnitParser->getNalUnitType() == NAL_UNIT_PREFIX)
	{
		return Err::m_nOK;
	}
//prefix unit}}
    if ( m_pcNalUnitParser->getQualityLevel() != 0)
		{

			BinData	*pcBinData = new BinData;
			pcBinData->set( new UChar[pcBinDataAccessor->size()], pcBinDataAccessor->size());
			memcpy( pcBinData->data(), pcBinDataAccessor->data(), pcBinDataAccessor->size());
			cVirtualSliceList.pushBack( pcBinData);
//*///xk
			return  Err::m_nERR;
		}

    if ( ( m_pcNalUnitParser->getNalUnitType() == NAL_UNIT_CODED_SLICE_SCALABLE
          || m_pcNalUnitParser->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_SCALABLE )
          && m_pcNalUnitParser->getLayerId() == 0)
		{
			return  Err::m_nERR;
		}

		if ( !checkSEIForErrorConceal())
		{
			return	Err::m_nInvalidParameter;
		}
    eNalUnitType = m_pcNalUnitParser->getNalUnitType();

    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_END_OF_STREAM &&
		1)
    {
			if(eNalUnitType==NAL_UNIT_CODED_SLICE_IDR||eNalUnitType==NAL_UNIT_CODED_SLICE_IDR_SCALABLE)
      {
        RNOK( m_pcSliceReader->readSliceHeader( m_pcNalUnitParser,
                                                pcSliceHeader,
                                                m_uiFirstFragmentNumMbsInSlice,
                                                m_bFirstFragmentFGSCompSep
		        ) );
        if(pcSliceHeader->getFrameNum()==0)
					m_uiMaxLayerId=pcSliceHeader->getLayerId()>m_uiMaxLayerId ? pcSliceHeader->getLayerId(): m_uiMaxLayerId;
      }
      return Err::m_nOK;
    }
    else
    {
      if ( eNalUnitType != NAL_UNIT_END_OF_STREAM)
			{
				// read the slice header
	      RNOK( m_pcSliceReader->readSliceHeader( m_pcNalUnitParser,
                                              pcSliceHeader,
                                              m_uiFirstFragmentNumMbsInSlice,
                                              m_bFirstFragmentFGSCompSep
											                         ) );
				if(pcSliceHeader->getFrameNum()==0)
					m_uiMaxLayerId=pcSliceHeader->getLayerId()>m_uiMaxLayerId ? pcSliceHeader->getLayerId(): m_uiMaxLayerId;

	      calculatePoc( eNalUnitType, *pcSliceHeader, slicePoc );
//        if(pcSliceHeader->getFrameNum()==1&&m_uiMaxLayerId!=(m_uiNumLayers-1))
//					m_bNotSupport=true;
       	if ( pcSliceHeader->getFrameNum() == 1 && pcSliceHeader->getLayerId() == m_uiNumLayers-1)
				{
					if ( pcSliceHeader->getPicOrderCntLsb() != m_uiMaxGopSize)
					{
						m_bNotSupport	=	true;
					}
					if ( pcSliceHeader->getFirstMbInSlice() != 0)
					{
						m_bNotSupport	=	true;
					}
					if ( pcSliceHeader->getFrameNum() == 1)
					{
						UInt	i=pcSliceHeader->getPicOrderCntLsb();
						while ( i % 2 == 0)
						{
							i /=	2;
						}
						if ( i!= 1)
						{
							m_bNotSupport	=	true;
						}
					}
				}
				// F slices are also ignored
				if( pcSliceHeader->getSliceType() == F_SLICE || pcSliceHeader->getFrameNum() == 1 && pcSliceHeader->getLayerId() < m_uiMaxLayerId)
//				if( pcSliceHeader->getSliceType() == F_SLICE)
				{
					if( pcSliceHeader != NULL )
						delete pcSliceHeader;

					return Err::m_nOK;
				}
//	detection the gap of slice
				frame_num	=	pcSliceHeader->getFrameNum();
				uiLayerId	=	pcSliceHeader->getLayerId();
				uiPocLsb	=	pcSliceHeader->getPicOrderCntLsb();
//				uiGopSize	=	pcSliceHeader->getSPS().getNumRefFrames() + 1;	//??
				UInt uiGopSize	=	m_uiGopSize[uiLayerId];
				if ( frame_num == 1 &&m_uiMaxLayerId==uiLayerId&& uiPocLsb > uiGopSize)
				{
					m_bNotSupport = true;
					if( pcSliceHeader != NULL )
						delete pcSliceHeader;
					return	Err::m_nOK;
				}
				uiMaxFrameNum	=	1 << pcSliceHeader->getSPS().getLog2MaxFrameNum();
				uiMaxPocLsb		=	1 << pcSliceHeader->getSPS().getLog2MaxPicOrderCntLsb();
			}
			else
			{
        bEOS://xk
        SliceHeader *pcSH;
        if ( m_pcVeryFirstSliceHeader == NULL)
        {
          pcSH  = m_apcMCTFDecoder[m_uiNextLayerId]->m_pcVeryFirstSliceHeader;
        }
        else
        {
          pcSH  = m_pcVeryFirstSliceHeader;
        }
				uiMaxFrameNum	=	1 << pcSH->getSPS().getLog2MaxFrameNum();
				uiMaxPocLsb		=	1 << pcSH->getSPS().getLog2MaxPicOrderCntLsb();
				uiLayerId	=	m_uiNextLayerId;
				UInt uiGopSize	=	1 << m_uiDecompositionStages[uiLayerId];
//				uiGopSize	=	m_uiGopSize[uiLayerId];
				if ( m_uiFrameIdx[uiLayerId] % uiGopSize != 1)
				{
					frame_num	=	m_pauiFrameNumInGOP[uiLayerId][m_uiGopSize[uiLayerId]-1] % uiMaxFrameNum;
					uiPocLsb	=	m_pauiPocInGOP[uiLayerId][m_uiGopSize[uiLayerId]-1] % uiMaxPocLsb;
				}
				else
				{
					frame_num	=	m_pauiFrameNumInGOP[uiLayerId][0] % uiMaxFrameNum;
					uiPocLsb	=	m_pauiPocInGOP[uiLayerId][0] % uiMaxPocLsb;
				}
//				if ( m_uiFrameIdx[uiLayerId] % uiGopSize == 1)
				{
					frame_num	-=	(uiGopSize >> 1);
//xk
          if ( uiGopSize == 1)
            frame_num -=  1;
					uiPocLsb	-=	m_uiMaxGopSize;
				}
			}
		}

		if ( frame_num != m_uiNextFrameNum || uiLayerId != m_uiNextLayerId || uiPocLsb != (m_uiNextPoc % uiMaxPocLsb))
		{
//	judge if the uncompleted GOP
			UInt	uiFrameIdx	=	0;
			UInt	uiGopSize	=	1 << m_uiDecompositionStages[uiLayerId];
//			UInt	uiGopSize	=	m_uiGopSize[uiLayerId];

			for ( ;uiFrameIdx < uiGopSize; uiFrameIdx++)
			{
				if ( m_pauiPocInGOP[uiLayerId][uiFrameIdx]	% uiMaxPocLsb ==	uiPocLsb)
					break;
			}
			if ( ( m_pauiFrameNumInGOP[uiLayerId][uiFrameIdx] % uiMaxFrameNum ) == frame_num || (uiPocLsb-1) / m_uiMaxGopSize != ((m_uiNextPoc-1) % uiMaxPocLsb) / m_uiMaxGopSize)
			{
				if ( m_uiNextLayerId == 0 && m_baseMode == 1)
				{
					BinData	*pcBinData = new BinData;
					pcBinData->set( new UChar[11], 11);
//					*(pcBinData->data()+0)	=	NAL_UNIT_VIRTUAL_BASELAYER;
					*(pcBinData->data()+0)	=	NAL_UNIT_CODED_SLICE;
					*(Int*)(pcBinData->data()+1)	=	0xdeadface;
					*(Short*)(pcBinData->data()+5)	=	(Short) m_uiNextFrameNum;
					*(Short*)(pcBinData->data()+7)	=	(Short) m_uiNextPoc;
					*(pcBinData->data()+9)	=	(UChar) m_uiNextTempLevel;
					*(pcBinData->data()+pcBinData->size()-1)	=	0;
					cVirtualSliceList.pushFront( pcBinData);

				}
				else
				{
					BinData	*pcBinData = new BinData;
					pcBinData->set( new UChar[11], 11);
//					*(pcBinData->data()+0)	=	NAL_UNIT_VIRTUAL_ENHANCELAYER;
					*(pcBinData->data()+0)	=	NAL_UNIT_CODED_SLICE_SCALABLE;
					*(Int*)(pcBinData->data()+1)	=	0xdeadface;
					*(Short*)(pcBinData->data()+5)	=	(Short)m_uiNextFrameNum;
					*(Short*)(pcBinData->data()+7)	=	(Short)m_uiNextPoc;
					*(pcBinData->data()+9)	=	(UChar) m_uiNextTempLevel;
					*(pcBinData->data()+pcBinData->size()-1)	=	0;
					cVirtualSliceList.pushFront( pcBinData);

          m_uiNumOfNALInAU++;  //TMM_EC
				}
			}
			else
			{
//	uncomplete GOP structure
//	calculate the gop size of the layer current packet belongs to
				if ( uiPocLsb % ( 2<<(m_uiMaxDecompositionStages-m_uiDecompositionStages[uiLayerId])) != 0)
				{
					m_uiGopSize[uiLayerId]	=	(((frame_num-1) % (uiGopSize>>1))<< 1) + 1;
				}
				else
				{
					UInt	uiFrameDiff	=	( m_pauiFrameNumInGOP[uiLayerId][uiFrameIdx] % uiMaxFrameNum)  - frame_num;
					UInt	uiTL	=	m_uiDecompositionStages[uiLayerId];
					UInt	uiTmp	=	uiPocLsb >> (m_uiMaxDecompositionStages - m_uiDecompositionStages[uiLayerId]);
					while( uiTmp % 2 == 0)
					{
						uiTmp	>>=1;
						uiTL--;
					}
          UInt ui = 0;
					for ( ui=m_uiGopSize[uiLayerId]&(-2); ui>0; ui-=2)
					{
						UInt	uiTempLevel	=	m_uiDecompositionStages[uiLayerId];
						uiTmp	=	ui;
						while( uiTmp % 2 == 0)
						{
							uiTmp	>>=1;
							uiTempLevel--;
						}
						if ( uiTL <= uiTempLevel)
						{
							continue;
						}
						uiFrameDiff--;
						if ( uiFrameDiff == 0)
						{
							break;
						}
					}
					m_uiGopSize[uiLayerId]	=	ui - 1;
				}
        //	calculate the gop size of other layers
        UInt  ui=0;
				for ( ui=0; ui<uiLayerId; ui++)
				{
					m_uiGopSize[ui]	=	m_uiGopSize[uiLayerId] >> (m_uiDecompositionStages[uiLayerId] - m_uiDecompositionStages[ui]);
				}
				for ( ui=uiLayerId+1; ui<m_uiNumLayers; ui++)
				{
					m_uiGopSize[ui]	=	( m_uiGopSize[uiLayerId] << (m_uiDecompositionStages[ui] - m_uiDecompositionStages[uiLayerId])) + ((1<<(m_uiDecompositionStages[ui] - m_uiDecompositionStages[uiLayerId])) -1);
				}
//	calculate the correct frame_num and poc of every packet in this uncompleted gop each layer
				m_uiFrameIdx[m_uiNextLayerId]--;
				for ( ui=0; ui<m_uiNumLayers; ui++)
				{
					uiFrameIdx      	=	0;
					UInt	uiFrameNum	=	m_pauiFrameNumInGOP[ui][0];
					UInt	uiPoc	=	( m_uiNextPoc - 1 ) & -(1<<m_uiMaxDecompositionStages);
					if ( ui == 0 || m_uiFrameIdx[ui] % (1<<m_uiDecompositionStages[ui]) != 0)
						uiFrameNum	-=	( 1 << ( m_uiDecompositionStages[ui] - 1 ) );
					UInt	uiDecompositionStagesSub	=	m_uiMaxDecompositionStages - m_uiDecompositionStages[ui];
					for( UInt uiTemporalLevel = 0; uiTemporalLevel <= m_uiDecompositionStages[ui]; uiTemporalLevel++ )
					{
						UInt      uiStep    = ( 1 << ( m_uiDecompositionStages[ui] - uiTemporalLevel ) );
						for( UInt uiFrameId = uiStep; uiFrameId <= m_uiGopSize[ui]; uiFrameId += ( uiStep << 1 ) )
						{
							m_pauiPocInGOP[ui][uiFrameIdx]	=	(uiFrameId << uiDecompositionStagesSub ) + uiPoc;
							m_pauiFrameNumInGOP[ui][uiFrameIdx]	=	uiFrameNum;
							m_pauiTempLevelInGOP[ui][uiFrameIdx]	=	uiTemporalLevel;
							uiFrameIdx++;
							if ( uiFrameId % 2 == 0)
								uiFrameNum++;
						}
					}
					for ( uiFrameIdx=0; uiFrameIdx<m_uiFrameIdx[ui] % (1<<m_uiDecompositionStages[ui]); uiFrameIdx++)
					{
						m_pauiPocInGOP[ui][uiFrameIdx]	+=	m_uiMaxGopSize;
						m_pauiFrameNumInGOP[ui][uiFrameIdx]	+=	(1<<(m_uiDecompositionStages[ui]-1));
					}
				}
			  do
			  {
				  if (m_uiFrameIdx[m_uiNextLayerId] % m_uiMaxGopSize < m_uiGopSize[m_uiNextLayerId])
					  break;
				  m_uiNextLayerId		=	(m_uiNextLayerId + 1) % m_uiNumLayers;
			  }
				while( true);
				if (m_uiFrameIdx[m_uiNextLayerId] % m_uiMaxGopSize < m_uiGopSize[m_uiNextLayerId])
				{
					uiMaxFrameNum				=	1 << pcSliceHeader->getSPS().getLog2MaxFrameNum();
					m_uiNextFrameNum		=	m_pauiFrameNumInGOP[m_uiNextLayerId][m_uiFrameIdx[m_uiNextLayerId] % uiGopSize] % uiMaxFrameNum;
					m_uiNextPoc					=	m_pauiPocInGOP[m_uiNextLayerId][m_uiFrameIdx[m_uiNextLayerId] % uiGopSize];
					m_uiNextTempLevel		=	m_pauiTempLevelInGOP[m_uiNextLayerId][m_uiFrameIdx[m_uiNextLayerId] % uiGopSize];
          // TMM_EC
          if ( uiGopSize == 1)
					  m_pauiFrameNumInGOP[m_uiNextLayerId][m_uiFrameIdx[m_uiNextLayerId] % uiGopSize]	+=	1 ;
          else
            m_pauiFrameNumInGOP[m_uiNextLayerId][m_uiFrameIdx[m_uiNextLayerId] % uiGopSize]	+=	1 << ( m_uiDecompositionStages[m_uiNextLayerId] - 1);

⌨️ 快捷键说明

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