h264avcdecodertest.cpp

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

CPP
752
字号
        uiFragNb++;
      }
      else
      {
        if(pcBinDataTmp[0]->size() != 0)
        {
                pcBinDataS = new BinData;
                pcBinDataS->set( new UChar[uiTotalLength], uiTotalLength );
          // append fragments
          UInt uiOffset = 0;
          for(UInt uiFrag = 0; uiFrag<uiFragNb+1; uiFrag++)
          {
                  memcpy(pcBinDataS->data()+uiOffset, pcBinDataTmp[uiFrag]->data() + auiStartPos[uiFrag], auiEndPos[uiFrag]-auiStartPos[uiFrag]);
              uiOffset += auiEndPos[uiFrag]-auiStartPos[uiFrag];
              RNOK( m_pcReadBitstream->releasePacket( pcBinDataTmp[uiFrag] ) );
              pcBinDataTmp[uiFrag] = NULL;
              m_pcH264AVCDecoder->decreaseNumOfNALInAU();
						//FRAG_FIX_3
						if(uiFrag > 0) 
							bConcatenated = true; //~FRAG_FIX_3
          }
          
                pcBinDataS->setMemAccessor( lcBinDataAccessor );
          bToDecode = false;
          if((uiTotalLength != 0) && (!bDiscardable || bFragmented))
          {
              //FRAG_FIX
					  if( (uiNalUnitType == 20) || (uiNalUnitType == 21) || (uiNalUnitType == 1) || (uiNalUnitType == 5) )
            {
							uiPreNalUnitType=uiNalUnitType;
							RNOK( m_pcH264AVCDecoder->initPacket( &lcBinDataAccessor, uiNalUnitType, uiMbX, uiMbY, uiSize, 
								//uiNonRequiredPic, //NonRequired JVT-Q066
                false, bConcatenated, //FRAG_FIX_3
								bStart, auiStartPos[uiFragNb+1], auiEndPos[uiFragNb+1], 
                bFragmented, bDiscardable) );
						}
						else
							m_pcH264AVCDecoder->initPacket( &cBinDataAccessor );
						bToDecode = true;
          }
        }
      }

    }
//~JVT-P031

//NonRequired JVT-Q066{
				if(m_pcH264AVCDecoder->isNonRequiredPic())
					continue;
//NonRequired JVT-Q066}
				if(bToDecode)//JVT-P031
				{
					// get new picture buffer if required if coded Slice || coded IDR slice
					pcPicBuffer = NULL;
			    
					if( uiNalUnitType == 1 || uiNalUnitType == 5 || uiNalUnitType == 20 || uiNalUnitType == 21)
					{
						RNOK( xGetNewPicBuffer( pcPicBuffer, uiSize ) );
			      
						if( ! bYuvDimSet )
						{
							UInt uiLumSize  = ((uiMbX<<3)+  YUV_X_MARGIN) * ((uiMbY<<3)    + YUV_Y_MARGIN ) * 4;
							uiLumOffset     = ((uiMbX<<4)+2*YUV_X_MARGIN) * YUV_Y_MARGIN   + YUV_X_MARGIN;  
							uiCbOffset      = ((uiMbX<<3)+  YUV_X_MARGIN) * YUV_Y_MARGIN/2 + YUV_X_MARGIN/2 + uiLumSize; 
							uiCrOffset      = ((uiMbX<<3)+  YUV_X_MARGIN) * YUV_Y_MARGIN/2 + YUV_X_MARGIN/2 + 5*uiLumSize/4;
							bYuvDimSet = true;

							// HS: decoder robustness
							pcLastFrame = new UChar [uiSize];
							ROF( pcLastFrame );
						}
					}

				//JVT-S036 lsj start
					if(uiNalUnitType == 1 || uiNalUnitType == 5)
					{
						SuffixEnable = true;
						RNOK(m_pcH264AVCDecoderSuffix->init());
						RNOK( m_pcReadBitstream->getPosition( iPos ) );
						RNOK( m_pcReadBitstream->extractPacket( pcBinData, bEOS ) );
						pcBinData->setMemAccessor( cBinDataAccessor );
						m_pcH264AVCDecoderSuffix->setAVCFlag( true );
						RNOK( m_pcH264AVCDecoderSuffix->initPacketSuffix( &cBinDataAccessor, uiNalUnitType, true, 
								false, //FRAG_FIX_3
								bStart, m_pcH264AVCDecoder,SuffixEnable
								)
							);

						RNOK( m_pcH264AVCDecoderSuffix->uninit());

						if( !SuffixEnable )
						{
							RNOK( m_pcReadBitstream->setPosition( iPos ) );
						}
					}
				//JVT-S036 lsj end
		    
					// decode the NAL unit
					RNOK( m_pcH264AVCDecoder->process( pcPicBuffer, cPicBufferOutputList, cPicBufferUnusedList, cPicBufferReleaseList ) );

					// ROI DECODE ICU/ETRI
					m_pcH264AVCDecoder->RoiDecodeInit();
			    
					// picture output
					while( ! cPicBufferOutputList.empty() )
					{
              PicBuffer* pcPicBufferTmp = cPicBufferOutputList.front();
						cPicBufferOutputList.pop_front();
              if( pcPicBufferTmp != NULL )
						{
							// HS: decoder robustness
                while( uiLastPoc + uiMaxPocDiff < (UInt)pcPicBufferTmp->getCts() )
							{
								RNOK( m_pcWriteYuv->writeFrame( pcLastFrame + uiLumOffset, 
																								pcLastFrame + uiCbOffset, 
																								pcLastFrame + uiCrOffset,
																								uiMbY << 4,
																								uiMbX << 4,
																								(uiMbX << 4)+ YUV_X_MARGIN*2 ) );
								printf("REPEAT FRAME\n");
								uiFrame   ++;
								uiLastPoc += uiMaxPocDiff;
							}

			        
                RNOK( m_pcWriteYuv->writeFrame( *pcPicBufferTmp + uiLumOffset, 
                  *pcPicBufferTmp + uiCbOffset, 
                  *pcPicBufferTmp + uiCrOffset,
																							uiMbY << 4,
																							uiMbX << 4,
																							(uiMbX << 4)+ YUV_X_MARGIN*2 ) );
							uiFrame++;
			      
			    
							// HS: decoder robustness
                uiLastPoc = (Int) pcPicBufferTmp->getCts();
                ::memcpy( pcLastFrame, *pcPicBufferTmp+0, uiSize*sizeof(UChar) );
						}
					}
			    
					RNOK( xRemovePicBuffer( cPicBufferReleaseList ) );
					RNOK( xRemovePicBuffer( cPicBufferUnusedList ) );
            if(pcBinDataS)
              RNOK( m_pcReadBitstream->releasePacket( pcBinDataS ) );
				}
			}
		}	while( true);

      if( pcBinData)
      { 
        m_pcReadBitstream->releasePacket( pcBinData ) ;
        pcBinData=NULL;
      }
		}
//TMM_EC }}

    //JVT-P031
    Bool bFragmented = false;
    Bool bDiscardable = false;
    Bool bStart = false;
    Bool bFirst = true;
    UInt uiTotalLength = 0;
#define MAX_FRAGMENTS 10 // hard-coded
    BinData* pcBinDataTmp[MAX_FRAGMENTS];
    BinDataAccessor cBinDataAccessorTmp[MAX_FRAGMENTS];
    UInt uiFragNb, auiStartPos[MAX_FRAGMENTS], auiEndPos[MAX_FRAGMENTS];
	Bool bConcatenated = false; //FRAG_FIX_3
    uiFragNb = 0;
    bEOS = false;
    pcBinData = 0;
    while(!bStart && !bEOS)
    {
      if(bFirst)
      {
          RNOK( m_pcReadBitstream->setPosition(iPos) );
          bFirst = false;
      }

      RNOK( m_pcReadBitstream->extractPacket( pcBinDataTmp[uiFragNb], bEOS ) );
//TMM_EC {{
			if( !bEOS && ((pcBinDataTmp[uiFragNb]->data())[0] & 0x1f )== 0x0b)
			{
				printf("end of stream\n");
				bEOS=true;
				uiNalUnitType= uiPreNalUnitType;
        RNOK( m_pcReadBitstream->releasePacket( pcBinDataTmp[uiFragNb] ) );
        pcBinDataTmp[uiFragNb] = new BinData;
				uiTotalLength	=	0;
        pcBinDataTmp[uiFragNb]->set( new UChar[uiTotalLength], uiTotalLength );
			}
//TMM_EC }}

      pcBinDataTmp[uiFragNb]->setMemAccessor( cBinDataAccessorTmp[uiFragNb] );
      // open the NAL Unit, determine the type and if it's a slice get the frame size

      RNOK( m_pcH264AVCDecoder->initPacket( &cBinDataAccessorTmp[uiFragNb], 
                                            uiNalUnitType, uiMbX, uiMbY, uiSize,  true, 
		  false, //FRAG_FIX_3
		  bStart, auiStartPos[uiFragNb], auiEndPos[uiFragNb], bFragmented, bDiscardable ) );

      uiTotalLength += auiEndPos[uiFragNb] - auiStartPos[uiFragNb];

      if(!bStart)
      {
        ROT( bEOS) ; //jerome.vieron@thomson.net
        uiFragNb++;
      }
      else
      {
        if(pcBinDataTmp[0]->size() != 0)
        {
          pcBinData = new BinData;
          pcBinData->set( new UChar[uiTotalLength], uiTotalLength );
          // append fragments
          UInt uiOffset = 0;
          for(UInt uiFrag = 0; uiFrag<uiFragNb+1; uiFrag++)
          {
              memcpy(pcBinData->data()+uiOffset, pcBinDataTmp[uiFrag]->data() + auiStartPos[uiFrag], auiEndPos[uiFrag]-auiStartPos[uiFrag]);
              uiOffset += auiEndPos[uiFrag]-auiStartPos[uiFrag];
              RNOK( m_pcReadBitstream->releasePacket( pcBinDataTmp[uiFrag] ) );
              pcBinDataTmp[uiFrag] = NULL;
              m_pcH264AVCDecoder->decreaseNumOfNALInAU();
			  //FRAG_FIX_3
			  if(uiFrag > 0) 
				  bConcatenated = true; //~FRAG_FIX_3
          }
          
          pcBinData->setMemAccessor( cBinDataAccessor );
          bToDecode = false;
          if((uiTotalLength != 0) && (!bDiscardable || bFragmented))
          {
              //FRAG_FIX
			  if( (uiNalUnitType == 20) || (uiNalUnitType == 21) || (uiNalUnitType == 1) || (uiNalUnitType == 5) )
              {
                uiPreNalUnitType=uiNalUnitType;
                RNOK( m_pcH264AVCDecoder->initPacket( &cBinDataAccessor, uiNalUnitType, uiMbX, uiMbY, uiSize, 
					//uiNonRequiredPic, //NonRequired JVT-Q066
                    false, bConcatenated, //FRAG_FIX_3
					bStart, auiStartPos[uiFragNb+1], auiEndPos[uiFragNb+1], 
                    bFragmented, bDiscardable) );
              }
              else
                  m_pcH264AVCDecoder->initPacket( &cBinDataAccessor );
              bToDecode = true;
          }
        }
      }
    }

    //~JVT-P031
//NonRequired JVT-Q066{
	if(m_pcH264AVCDecoder->isNonRequiredPic())
		continue;
//NonRequired JVT-Q066}
// JVT-Q054 Red. Picture {
  RNOK( m_pcH264AVCDecoder->checkRedundantPic() );
  if ( m_pcH264AVCDecoder->isRedundantPic() )
    continue;
// JVT-Q054 Red. Picture }

  if(bToDecode)//JVT-P031
  {
    // get new picture buffer if required if coded Slice || coded IDR slice
    pcPicBuffer = NULL;
    
    if( uiNalUnitType == 1 || uiNalUnitType == 5 || uiNalUnitType == 20 || uiNalUnitType == 21 )
    {
      RNOK( xGetNewPicBuffer( pcPicBuffer, uiSize ) );

      if( ! bYuvDimSet )
      {
        UInt uiLumSize  = ((uiMbX<<3)+  YUV_X_MARGIN) * ((uiMbY<<3)    + YUV_Y_MARGIN ) * 4;
        uiLumOffset     = ((uiMbX<<4)+2*YUV_X_MARGIN) * YUV_Y_MARGIN   + YUV_X_MARGIN;  
        uiCbOffset      = ((uiMbX<<3)+  YUV_X_MARGIN) * YUV_Y_MARGIN/2 + YUV_X_MARGIN/2 + uiLumSize; 
        uiCrOffset      = ((uiMbX<<3)+  YUV_X_MARGIN) * YUV_Y_MARGIN/2 + YUV_X_MARGIN/2 + 5*uiLumSize/4;
        bYuvDimSet = true;

        // HS: decoder robustness
        pcLastFrame = new UChar [uiSize];
        ROF( pcLastFrame );
      }
    }
    
//JVT-S036 lsj start
	if((uiNalUnitType == 1 || uiNalUnitType == 5) && !bEOS) 
	{
		SuffixEnable = true;
		RNOK(m_pcH264AVCDecoderSuffix->init());
		RNOK( m_pcReadBitstream->getPosition( iPos ) );
		RNOK( m_pcReadBitstream->extractPacket( pcBinData, bEOS ) );
		pcBinData->setMemAccessor( cBinDataAccessor );
		m_pcH264AVCDecoderSuffix->setAVCFlag( true );
		RNOK( m_pcH264AVCDecoderSuffix->initPacketSuffix( &cBinDataAccessor, uiNalUnitType, true, 
				false, //FRAG_FIX_3
				bStart, m_pcH264AVCDecoder,SuffixEnable
				)
			);

		RNOK( m_pcH264AVCDecoderSuffix->uninit());

		if( !SuffixEnable )
		{
			RNOK( m_pcReadBitstream->setPosition( iPos ) );
			bEOS = false; 
		}
	}
//JVT-S036 lsj end

    // decode the NAL unit
    RNOK( m_pcH264AVCDecoder->process( pcPicBuffer, cPicBufferOutputList, cPicBufferUnusedList, cPicBufferReleaseList ) );

	// ROI DECODE ICU/ETRI
	m_pcH264AVCDecoder->RoiDecodeInit();
    
    // picture output
    while( ! cPicBufferOutputList.empty() )
    {
        PicBuffer* pcPicBufferTmp = cPicBufferOutputList.front();
      cPicBufferOutputList.pop_front();
        if( pcPicBufferTmp != NULL )
      {
        // HS: decoder robustness
          while( uiLastPoc + uiMaxPocDiff < (UInt)pcPicBufferTmp->getCts() )
        {
          RNOK( m_pcWriteYuv->writeFrame( pcLastFrame + uiLumOffset, 
                                          pcLastFrame + uiCbOffset, 
                                          pcLastFrame + uiCrOffset,
                                           uiMbY << 4,
                                           uiMbX << 4,
                                          (uiMbX << 4)+ YUV_X_MARGIN*2 ) );
          printf("REPEAT FRAME\n");
          uiFrame   ++;
          uiLastPoc += uiMaxPocDiff;
        }

        RNOK( m_pcWriteYuv->writeFrame( *pcPicBufferTmp + uiLumOffset, 
                                        *pcPicBufferTmp + uiCbOffset, 
                                        *pcPicBufferTmp + uiCrOffset,
                                         uiMbY << 4,
                                         uiMbX << 4,
                                        (uiMbX << 4)+ YUV_X_MARGIN*2 ) );
        uiFrame++;
      
    
        // HS: decoder robustness
        uiLastPoc = (UInt)pcPicBufferTmp->getCts();
        ::memcpy( pcLastFrame, *pcPicBufferTmp+0, uiSize*sizeof(UChar) );
      }
    }
   } 
    RNOK( xRemovePicBuffer( cPicBufferReleaseList ) );
    RNOK( xRemovePicBuffer( cPicBufferUnusedList ) );
    if( pcBinData )
    {
      RNOK( m_pcReadBitstream->releasePacket( pcBinData ) );
      pcBinData = 0;
    }
  }

  printf("\n %d frames decoded\n", uiFrame );

  delete [] pcLastFrame; // HS: decoder robustness
  
  RNOK( m_pcH264AVCDecoder->uninit() );
  
  m_pcParameter->nFrames  = uiFrame;
  m_pcParameter->nResult  = 0;

  return Err::m_nOK;
}





⌨️ 快捷键说明

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