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

📄 nalunitparser.cpp

📁 jsvm开发代码包括抽样,编码,抽取,解码等一系列功能,可以做工具或研究用
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  DTRACE_TH   ( "NALU HEADER: tl0_pic_idx_present_flag" );
  DTRACE_TY   ( " u(1)" );
  DTRACE_POS;
  DTRACE_CODE ( m_bTl0PicIdxPresentFlag );
  DTRACE_BITS ( m_bTl0PicIdxPresentFlag, 1 );
  DTRACE_COUNT( 1 );
  DTRACE_N;
  
  // JVT-U116 LMI }
  // JVT-V088 LMI }
  
}


//JVT-P031
UInt
NalUnitParser::getNalHeaderSize( BinDataAccessor* pcBinDataAccessor )
{
  ROF( pcBinDataAccessor->size() );
  ROF( pcBinDataAccessor->data() );

  NalUnitType   eNalUnitType;
  NalRefIdc     eNalRefIdc;

  UInt  uiHeaderLength  = 1;
  UChar ucByte          = pcBinDataAccessor->data()[0];


  //===== NAL unit header =====
  ROT( ucByte & 0x80 );                                     // forbidden_zero_bit ( &10000000b)
  eNalRefIdc          = NalRefIdc   ( ucByte >> 5     );  // nal_ref_idc        ( &01100000b)
  eNalUnitType        = NalUnitType ( ucByte &  0x1F  );  // nal_unit_type      ( &00011111b)


  if( eNalUnitType == NAL_UNIT_CODED_SLICE_SCALABLE ||
      eNalUnitType == NAL_UNIT_CODED_SLICE_IDR_SCALABLE )
  {
    uiHeaderLength      += NAL_UNIT_HEADER_SVC_EXTENSION_BYTES;
    // JVT-U116 LMI {
    ucByte = pcBinDataAccessor->data()[3];
    if ( ucByte & 1 )
      uiHeaderLength ++;
    // JVT-U116 LMI }
  }

  return uiHeaderLength;
}
ErrVal
NalUnitParser::initSODBNalUnit( BinDataAccessor* pcBinDataAccessor )
{
  m_pucBuffer = pcBinDataAccessor->data();
  UInt uiPacketLength = pcBinDataAccessor->size();

  UInt uiBits;
  xConvertRBSPToSODB(uiPacketLength, uiBits);

  RNOK( m_pcBitReadBuffer->initPacket( (ULong*)(m_pucBuffer), uiBits) );
  return Err::m_nOK;
}

UInt
NalUnitParser::getBytesLeft()
{
  return(m_pcBitReadBuffer->getBytesLeft());
}

UInt
NalUnitParser::getBitsLeft()
{
  return(m_pcBitReadBuffer->getBitsLeft());
}
//~JVT-P031

ErrVal
NalUnitParser::initNalUnit( BinDataAccessor*  pcBinDataAccessor, 
                            UInt&             uiNumBytesRemoved,  //FIX_FRAG_CAVLC
                            Bool              bPreParseHeader, 
                            Bool              bConcatenated,      //FRAG_FIX
													  Bool	            bCheckGap,          //TMM_EC
                            UInt*             puiNumFragments,
                            UChar**           ppucFragBuffers ) 
{
  ROF( pcBinDataAccessor->size() );
  ROF( pcBinDataAccessor->data() );


  UInt  uiHeaderLength  = 1;
  UChar ucByte          = pcBinDataAccessor->data()[0];


  //===== NAL unit header =====
  ROT( ucByte & 0x80 );                                     // forbidden_zero_bit ( &10000000b)
  m_eNalRefIdc          = NalRefIdc   ( ucByte >> 5     );  // nal_ref_idc        ( &01100000b)
  m_eNalUnitType        = NalUnitType ( ucByte &  0x1F  );  // nal_unit_type      ( &00011111b)


//  TMM_EC {{
  if ( *(int*)(pcBinDataAccessor->data()+1) != 0xdeadface)
  { 
    if( m_eNalUnitType == NAL_UNIT_CODED_SLICE_SCALABLE ||
        m_eNalUnitType == NAL_UNIT_CODED_SLICE_IDR_SCALABLE ||
		m_eNalUnitType == NAL_UNIT_PREFIX)//prefix unit
    {
      ROF( pcBinDataAccessor->size() > 3 );

      ucByte              = pcBinDataAccessor->data()[1];
      ROT( ucByte & 0xC0 );                                 // reserved_zero_two_bitst ( &11000000b)
      m_uiPriorityId        = ( ucByte >> 2);               // priority_id             ( &00111111b)

      ucByte              = pcBinDataAccessor->data()[2];
      m_uiTemporalLevel   = ( ucByte >> 5 );               // temporal_level           ( &11100000b)
      m_uiLayerId         = ( ucByte >> 2 ) & 7;           // dependency_id            ( &00011100b)
      m_uiQualityLevel    = ( ucByte      ) & 3;           // quality_level            ( &00000011b)

      ucByte              = pcBinDataAccessor->data()[3];
      // JVT-U116 LMI {
      //ROT( ucByte & 0x80 );                              // reserved_zero_one_bit    ( &10000000b)
      m_bLayerBaseFlag      = ( ucByte >> 7) & 1;          // layer_base_flag          ( &10000000b)
      m_bUseBasePredFlag    = ( ucByte >> 6) & 1;          // use_base_prediction_flag ( &01000000b)
      m_bDiscardableFlag    = ( ucByte >> 5) & 1;          // discardable_flag         ( &00100000b)

      m_bFGSFragFlag        = ( ucByte >> 4) & 1;          // fgs_frag_flag            ( &00010000b)
      m_bFGSLastFragFlag    = ( ucByte >> 3) & 1;          // fgs_last_frag_flag       ( &00001000b)
      m_uiFGSFragOrder      = ( ucByte >> 1) & 3;          // fgs_frag_order           ( &00000110b)
      // JVT-V088 LMI {
      m_bTl0PicIdxPresentFlag      = ( ucByte >> 0) & 1;          // tl0_pic_idx_present_flag           ( &00000001b)
      uiHeaderLength    +=  NAL_UNIT_HEADER_SVC_EXTENSION_BYTES;
      // JVT-V088 LMI }
      // JVT-U116 LMI }
      }
    else
    {
      m_uiPriorityId    = 0;

      m_uiTemporalLevel = 0;
      m_uiLayerId       = 0;
      m_uiQualityLevel  = 0;

      m_bLayerBaseFlag  = 1; // m_bLayerBaseFlag indicate that the content of the NAL is compatible with NAL_UNIT_CODED_SLICE
      m_bUseBasePredFlag= 0;
      m_bDiscardableFlag= 0;
      m_bFGSFragFlag    = 0;
      m_bFGSLastFragFlag= 0;
      m_uiFGSFragOrder  = 0;
    }
  }
  else //TMM_EC
  {
    uiNumBytesRemoved  =  0;
    m_pucBuffer         = pcBinDataAccessor->data() + uiHeaderLength;
    return Err::m_nOK;
  }


  //===== TRACE output =====
  xTrace( uiHeaderLength > 1 );

  //===== NAL unit payload =====
  m_pucBuffer         = pcBinDataAccessor->data() + uiHeaderLength;
  UInt uiPacketLength = pcBinDataAccessor->size() - uiHeaderLength;

  //JVT-P031
  if(m_bDiscardableFlag == true && m_uiDecodedLayer > m_uiLayerId && !m_bCheckAllNALUs)
  {
    //Nal unit or fragment must be discarded
        uiPacketLength = 0;
  }
  //~JVT-P031

  // nothing more to do
  ROTRS( NAL_UNIT_END_OF_STREAM   == m_eNalUnitType ||
         NAL_UNIT_END_OF_SEQUENCE == m_eNalUnitType,    Err::m_nOK );

  uiNumBytesRemoved = uiPacketLength;//FIX_FRAG_CAVLC
  if ( !bCheckGap)
  {
    // Unit->RBSP
    if(bPreParseHeader) //FRAG_FIX
    {//FIX_FRAG_CAVLC
        RNOK( xConvertPayloadToRBSP ( uiPacketLength ) );
        uiNumBytesRemoved -= uiPacketLength; //FIX_FRAG_CAVLC
    }//FIX_FRAG_CAVLC
  }
  else //TMM_EC
  {
    uiNumBytesRemoved  =  0;
  }
  UInt uiBitsInPacket;
  // RBSP->SODB
  RNOK( xConvertRBSPToSODB    ( uiPacketLength, uiBitsInPacket ) );

  //FRAG_FIX
  if(!(m_bDiscardableFlag && m_uiDecodedLayer > m_uiLayerId)) //FRAG_FIX_3
  {
  if(bPreParseHeader)
      m_uiBitsInPacketSaved = uiBitsInPacket;
  if(!bPreParseHeader && !bConcatenated) //FRAG_FIX_3
      uiBitsInPacket = m_uiBitsInPacketSaved;
  } //FRAG_FIX_3

  if(!m_bDiscardableFlag || (m_bDiscardableFlag && m_uiDecodedLayer == m_uiLayerId) || m_bCheckAllNALUs) //JVT-P031
  {
      RNOK( m_pcBitReadBuffer->initPacket( (ULong*)(m_pucBuffer), uiBitsInPacket, puiNumFragments, ppucFragBuffers ) );
  }
  return Err::m_nOK;
}



ErrVal
NalUnitParser::closeNalUnit()
{
  m_pucBuffer         = NULL;
  m_eNalUnitType      = NAL_UNIT_EXTERNAL;
  m_eNalRefIdc        = NAL_REF_IDC_PRIORITY_LOWEST;
  m_uiLayerId         = 0;
  m_uiTemporalLevel   = 0;
  m_uiQualityLevel    = 0;

  return Err::m_nOK;
}



ErrVal
NalUnitParser::xConvertPayloadToRBSP( UInt& ruiPacketLength )
{
  UInt uiZeroCount    = 0;
  UInt uiWriteOffset  = 0;
  UInt uiReadOffset   = 0;

  for( ; uiReadOffset < ruiPacketLength; uiReadOffset++, uiWriteOffset++ )
  {
    if( 2 == uiZeroCount && 0x03 == m_pucBuffer[uiReadOffset] )
    {
      uiReadOffset++;
      uiZeroCount = 0;
    }

    m_pucBuffer[uiWriteOffset] = m_pucBuffer[uiReadOffset];

    if( 0x00 == m_pucBuffer[uiReadOffset] )
    {
      uiZeroCount++;
    }
    else
    {
      uiZeroCount = 0;
    }
  }

  ruiPacketLength = uiWriteOffset;

  return Err::m_nOK;
}


ErrVal
NalUnitParser::xConvertRBSPToSODB( UInt  uiPacketLength,
                                   UInt& ruiBitsInPacket )
{
  uiPacketLength--;
  UChar *puc = m_pucBuffer;

  //remove zero bytes at the end of the stream
  while (puc[uiPacketLength] == 0x00)
  {
    uiPacketLength-=1;
  }

  // find the first non-zero bit
  UChar ucLastByte=puc[uiPacketLength];
  Int   i;
  for(  i = 0; (ucLastByte & 1 ) == 0; i++ )
  {
    ucLastByte >>= 1;
    AOT_DBG( i > 7 );
  }

  ruiBitsInPacket = (uiPacketLength << 3) + 8 - i;
  return Err::m_nOK;
}

ErrVal NalUnitParser::readAUDelimiter()
{
  DTRACE_HEADER("Access Unit Delimiter");

  UInt uiPicDelimiterType;
  m_pcBitReadBuffer->get(uiPicDelimiterType, 3);

  DTRACE_TH( "AUD: primary_pic_type"  );
  DTRACE_TY( " u(3)" );
  DTRACE_BITS(uiPicDelimiterType, 3);
  DTRACE_POS;
  DTRACE_CODE(uiPicDelimiterType);
  DTRACE_COUNT(3);
  DTRACE_N;

  return Err::m_nOK;
}

ErrVal NalUnitParser::readEndOfSeqence()
{
  DTRACE_HEADER("End of Sequence");
  return Err::m_nOK;
}

ErrVal NalUnitParser::readEndOfStream()
{
  DTRACE_HEADER("End of Stream");
  return Err::m_nOK;
}

H264AVC_NAMESPACE_END

⌨️ 快捷键说明

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