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

📄 mp4_parser_stbl.c

📁 最新MTK手机软件源码
💻 C
📖 第 1 页 / 共 5 页
字号:
   pCurTrack = &(pstMp4Parser->stMp4Track[bTrackNo]);
   uEndIndex = pCurTrack->uSyncCount;
   /// If the Sync Sample Box is not present, every sample is a random access point.
   if (uEndIndex==0) {
      *puPrevSyncSampleNo = uCurSampleNo;
      return MP4_PARSER_OK;
   }

   if (pCurTrack->uSTSSCacheTableEntryCount > 0) {
      /// STSS cache is enabled. Perform binary search.
      kal_uint16 start_index, end_index;
      STSS_Cache_Entry *stss_cache_table;

      stss_cache_table = pCurTrack->pSTSSCacheTable;

      do { /// Initial Cache
         MP4_STSS_ProcCacheTableByTrack(pstMp4Parser, eTrackType, 4 );
      }
      while (pCurTrack->uSTSSCacheIndex != pCurTrack->uSTSSCacheTableEntryCount &&
          uCurSampleNo > stss_cache_table[pCurTrack->uSTSSCacheIndex-1].sample_number);

      start_index = 0;
      end_index = pCurTrack->uSTSSCacheIndex-1;
      while ((end_index-start_index)>1) {
         kal_uint16 middle_index = (start_index+end_index)>>1;
         if (uCurSampleNo > stss_cache_table[middle_index].sample_number)
            start_index = middle_index;
         else
            end_index = middle_index;
      }
      uStartIndex = start_index * pCurTrack->uSTSSCacheTableStepSize;
      uEndIndex = end_index * pCurTrack->uSTSSCacheTableStepSize;
   }
   else {
      uStartIndex = 0;
      uEndIndex --;
   }

   /// Perform binary search
   while ((uEndIndex-uStartIndex)>1) {
      kal_uint32 uMiddleIndex = (uStartIndex+uEndIndex)>>1;
      if ((ret=MP4_GetSyncSampleNo(pstMp4Parser, uMiddleIndex, &uSyncSampleNo, eTrackType))!=MP4_PARSER_OK)
         return ret;
      if (uCurSampleNo > uSyncSampleNo)
         uStartIndex = uMiddleIndex;
      else
         uEndIndex = uMiddleIndex;
   }
   if ((ret=MP4_GetSyncSampleNo(pstMp4Parser, uStartIndex, puPrevSyncSampleNo, eTrackType))!=MP4_PARSER_OK)
      return ret;
   return MP4_PARSER_OK;
}

/*******************************************************************************
   Get the audio type of the MP4 parser.
*******************************************************************************/
MP4_Audio_Type MP4_GetAudioType(STMp4Parser *pstMp4Parser)
{
   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);

   return pstMp4Parser->bAudioType;
}

/*******************************************************************************
   Get the video type of the MP4 parser.
*******************************************************************************/
MP4_Video_Type MP4_GetVideoType(STMp4Parser *pstMp4Parser)
{
   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);

   return pstMp4Parser->bVideoType;
}

/*******************************************************************************
   Get the offset of MOOV box.
*******************************************************************************/
kal_uint32 MP4_GetMovieHeaderOffset(STMp4Parser *pstMp4Parser)
{
   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);

   return pstMp4Parser->uMOOVOffset;
}

/*******************************************************************************
   Get the offset of VOS.
*******************************************************************************/
kal_uint32 MP4_Video_GetVOSOffset(STMp4Parser *pstMp4Parser)
{
   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
   MP4_PARSER_ASSERT(MP4_VIDEO_MPEG4==MP4_GetVideoType(pstMp4Parser));

   return pstMp4Parser->uVOSOffset;
}

/*******************************************************************************
   Get the size of VOS.
*******************************************************************************/
kal_uint32 MP4_Video_GetVOSSize(STMp4Parser *pstMp4Parser)
{
   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
   MP4_PARSER_ASSERT(MP4_VIDEO_MPEG4==MP4_GetVideoType(pstMp4Parser));

   return pstMp4Parser->uVOSSize;
}

/*******************************************************************************
   Set the FSAL interface for STCO box.
*******************************************************************************/
MP4_Parser_Status MP4_SetFSAL_STCO(STMp4Parser *pstMp4Parser, MP4_Track_Type eTrackType, STFSAL *pstFSAL)
{
   MP4_Parser_Status ret;
   kal_uint8 bTrackNo;

   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
   MP4_PARSER_CHECK_ARG(pstFSAL!=NULL);

   if ((ret=MP4_GetTrackNoByType(pstMp4Parser, eTrackType, &bTrackNo))!=MP4_PARSER_OK)
      return ret;

   pstMp4Parser->stMp4Track[bTrackNo].pstFSAL_STCO = pstFSAL;

   return MP4_PARSER_OK;
}

/*******************************************************************************
   Set the FSAL interface for STSZ box.
*******************************************************************************/
MP4_Parser_Status MP4_SetFSAL_STSZ(STMp4Parser *pstMp4Parser, MP4_Track_Type eTrackType, STFSAL *pstFSAL)
{
   MP4_Parser_Status ret;
   kal_uint8 bTrackNo;

   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
   MP4_PARSER_CHECK_ARG(pstFSAL!=NULL);

   if ((ret=MP4_GetTrackNoByType(pstMp4Parser, eTrackType, &bTrackNo))!=MP4_PARSER_OK)
      return ret;

   pstMp4Parser->stMp4Track[bTrackNo].pstFSAL_STSZ = pstFSAL;

   return MP4_PARSER_OK;
}

/*******************************************************************************
   Update the sample count. Compare the sample count calculated from STSC and
   stored in STSZ and make the smaller one to be the real sample count.
*******************************************************************************/
MP4_Parser_Status MP4_UpdateSampleCount(STMp4Parser *pstMp4Parser, MP4_Track_Type eTrackType)
{
   kal_uint32 uSampleToChunkIndex;
   kal_uint32 uFirstChunk, uLastChunk;
   kal_uint32 uSampleToChunkEntryCount;
   kal_uint32 uSampleSum = 0;
   kal_uint32 uSamplePerChunk;
   kal_uint8  bTrackNo;
   STMp4Track *pCurTrack;
   MP4_Parser_Status ret;

   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);

   if ((ret = MP4_GetTrackNoByType(pstMp4Parser, eTrackType, &bTrackNo))!=MP4_PARSER_OK)
      return ret;
   pCurTrack = &(pstMp4Parser->stMp4Track[bTrackNo]);

   if (pCurTrack->bSampleCountUpdated)
      return MP4_PARSER_OK;

   if ((ret = MP4_GetSampleToChunkEntryCount(pstMp4Parser, eTrackType, &uSampleToChunkEntryCount))!=MP4_PARSER_OK)
      return ret;

   pCurTrack->uSampleToChunkEntryCount = uSampleToChunkEntryCount;
   uSampleToChunkEntryCount--;
   for (uSampleToChunkIndex=0; uSampleToChunkIndex<uSampleToChunkEntryCount; uSampleToChunkIndex++) {
      if ((ret = MP4_GetSamplePerChunkInRun(pstMp4Parser, uSampleToChunkIndex, &uSamplePerChunk, eTrackType))!=MP4_PARSER_OK)
         return ret;
      if ((ret = MP4_GetFirstChunkInRun(pstMp4Parser, uSampleToChunkIndex+1, &uLastChunk, eTrackType))!=MP4_PARSER_OK)
         return ret;
      if ((ret = MP4_GetFirstChunkInRun(pstMp4Parser, uSampleToChunkIndex, &uFirstChunk, eTrackType))!=MP4_PARSER_OK)
         return ret;
      uSampleSum += (uLastChunk - uFirstChunk)*uSamplePerChunk;
   }
   // handle the last entry
   if ((ret = MP4_GetSamplePerChunkInRun(pstMp4Parser, uSampleToChunkIndex, &uSamplePerChunk, eTrackType))!=MP4_PARSER_OK)
         return ret;
   if ((ret = MP4_GetChunkCount(pstMp4Parser, eTrackType, &uLastChunk))!=MP4_PARSER_OK)
        return ret;
   if ((ret = MP4_GetFirstChunkInRun(pstMp4Parser, uSampleToChunkIndex, &uFirstChunk, eTrackType))!=MP4_PARSER_OK)
         return ret;
   uSampleSum += (uLastChunk - uFirstChunk)*uSamplePerChunk;

   if( pCurTrack->uSampleCount > uSampleSum )
      pCurTrack->uSampleCount = uSampleSum;
   pCurTrack->bSampleCountUpdated = KAL_TRUE;

   return MP4_PARSER_OK;
}

/*******************************************************************************
   Initialize the STTS cache of the specified track.
*******************************************************************************/
static MP4_Parser_Status MP4_STTS_InitCacheTableByTrack( STMp4Parser *pstMp4Parser, MP4_Track_Type eTrackType,
                                                         STTS_Cache_Entry *pSTTSCacheTable, kal_uint32 uSTTSCacheTableCount,
                                                         kal_uint32 *puSTTSCacheTblCntExist)
{
   kal_uint32 uThisSampleCount;
   kal_uint32 uThisSampleDelta;
   kal_uint32 uIndex = 0;
   kal_uint32 uSTTSEntryCount = 0;
   kal_uint32 uCurSampleCount = 0;
   kal_uint64 uCurDecodeTime = 0;
   kal_uint16 uCacheIndex = 0;
   kal_uint16 uStepSize = 0;
   kal_uint16 uStepCounter = 0;
   kal_uint8  bTrackNo;
   MP4_Parser_Status ret;

   *puSTTSCacheTblCntExist = 0;

   if ((ret=MP4_GetTrackNoByType(pstMp4Parser, eTrackType, &bTrackNo))!=MP4_PARSER_OK)
      return ret;

   uSTTSEntryCount = pstMp4Parser->stMp4Track[bTrackNo].uTimeToSampleTableEntryCount;

   if ((0==uSTTSCacheTableCount) || (0==uSTTSEntryCount))
      return MP4_PARSER_OK;

   uStepSize = (uSTTSEntryCount+uSTTSCacheTableCount-1) / uSTTSCacheTableCount;
   /* avoid divide-by-zero */
   if (0 == uStepSize)
      uStepSize = 1;
   uSTTSCacheTableCount = uSTTSEntryCount / uStepSize;

   /// In the initialization, process at most 2048 STTS entries to prevent the response time
   /// from being too long.
   if (uSTTSEntryCount > 4096)
      uSTTSEntryCount = 4096;
   for (uIndex=0; uIndex<uSTTSEntryCount; uIndex++) {
      if ((ret=MP4_GetSampleCountAndDelta(pstMp4Parser, uIndex, &uThisSampleCount, &uThisSampleDelta, eTrackType))!=MP4_PARSER_OK)
         return ret;
      uCurSampleCount += uThisSampleCount;
      uCurDecodeTime += (kal_uint64)uThisSampleDelta * (kal_uint64)uThisSampleCount;
      uStepCounter++;
      if (uStepCounter == uStepSize) {
         uStepCounter = 0;
         pSTTSCacheTable[uCacheIndex].accumulated_sample_count = uCurSampleCount;
         pSTTSCacheTable[uCacheIndex++].accumulated_decode_time = uCurDecodeTime;
         if( uCacheIndex == uSTTSCacheTableCount )
            break;
      }
   }
   pstMp4Parser->stMp4Track[bTrackNo].uSTTSStepCounter          = uStepCounter;
   pstMp4Parser->stMp4Track[bTrackNo].uSTTSCurSampleCount       = uCurSampleCount;
   pstMp4Parser->stMp4Track[bTrackNo].uSTTSCurDecodeTime        = uCurDecodeTime;
   pstMp4Parser->stMp4Track[bTrackNo].uSTTSCacheIndex           = uCacheIndex;
   pstMp4Parser->stMp4Track[bTrackNo].uSTTSIndex                = uIndex;
   pstMp4Parser->stMp4Track[bTrackNo].pSTTSCacheTable           = pSTTSCacheTable;
   pstMp4Parser->stMp4Track[bTrackNo].uSTTSCacheTableStepSize   = uStepSize;
   pstMp4Parser->stMp4Track[bTrackNo].uSTTSCacheTableEntryCount = uSTTSCacheTableCount;

   *puSTTSCacheTblCntExist = uSTTSCacheTableCount;

   return MP4_PARSER_OK;
}

/*******************************************************************************
   Process certain number of STTS cache of the specified track.
   uCount is the number of STTS entries to be processed.
*******************************************************************************/
static MP4_Parser_Status MP4_STTS_ProcCacheTableByTrack( STMp4Parser *pstMp4Parser, MP4_Track_Type eTrackType, kal_uint16 uCount )
{
   kal_uint32 uIndex, local_counter;
   kal_uint32 uSTTSEntryCount, uSTTSCacheTableCount;
   kal_uint32 uThisSampleCount;
   kal_uint32 uThisSampleDelta;
   kal_uint32 uCurSampleCount;
   kal_uint64 uCurDecodeTime;
   kal_uint16 uCacheIndex;
   kal_uint16 uStepSize;
   kal_uint16 uStepCounter;
   kal_uint8  bTrackNo;
   MP4_Parser_Status ret;
   STTS_Cache_Entry *pSTTSCacheTable;
   STMp4Track *pCurTrack;

   if ((ret=MP4_GetTrackNoByType(pstMp4Parser, eTrackType, &bTrackNo))!=MP4_PARSER_OK)
      return ret;
   pCurTrack = &(pstMp4Parser->stMp4Track[bTrackNo]);
   
   uCacheIndex          = pCurTrack->uSTTSCacheIndex;
   uSTTSCacheTableCount = pCurTrack->uSTTSCacheTableEntryCount;

   if (uSTTSCacheTableCount==0 || uCacheIndex==uSTTSCacheTableCount)
      return MP4_PARSER_OK;

   uSTTSEntryCount      = pCurTrack->uTimeToSampleTableEntryCount;
   uStepCounter         = pCurTrack->uSTTSStepCounter;
   uCurSampleCount      = pCurTrack->uSTTSCurSampleCount;
   uCurDecodeTime       = pCurTrack->uSTTSCurDecodeTime;
   uIndex               = pCurTrack->uSTTSIndex;
   pSTTSCacheTable      = pCurTrack->pSTTSCacheTable;
   uStepSize            = pCurTrack->uSTTSCacheTableStepSize;

   for (local_counter=0; uIndex<uSTTSEntryCount && local_counter<uCount; uIndex++, local_counter++) {
      if ((ret=MP4_GetSampleCountAndDelta(pstMp4Parser, uIndex, &uThisSampleCount, &uThisSampleDelta, eTrackType))!=MP4_PARSER_OK)
         return ret;
      uCurSampleCount += uThisSampleCount;
      uCurDecodeTime += (kal_uint64)uThisSampleDelta * (kal_uint64)uThisSampleCount;
      uStepCounter++;
      if (uStepCounter == uStepSize) {
         uStepCounter = 0;
         pSTTSCacheTable[uCacheIndex].accumulated_sample_count = uCurSampleCount;
         pSTTSCacheTable[uCacheIndex++].accumulated_decode_time = uCurDecodeTime;
         if( uCacheIndex == uSTTSCacheTableCount )
            break;
      }
   }
   pCurTrack->uSTTSStepCounter             = uStepCounter;
   pCurTrack->uSTTSCurSampleCount          = uCurSampleCount;
   pCurTrack->uSTTSCurDecodeTime           = uCurDecodeTime;
   pCurTrack->uSTTSCacheIndex              = uCacheIndex;
   pCurTrack->uSTTSIndex                   = uIndex;

   return MP4_PARSER_OK;
}

/*******************************************************************************
    Initialize the STTS cache.
*******************************************************************************/
static MP4_Parser_Status MP4_STTS_InitCacheTable(STMp4Parser *pstMp4Parser, kal_uint32 *pSTTSCachePool, kal_uint32 uSTTSCachePoolSize, kal_uint32 *puSTTSCachePoolUsed)
{
   MP4_Parser_Status ret;
   kal_uint8 bTrackNo;
   STMp4Track *pAudioTrack, *pVideoTrack;
   const kal_uint16 entry_size = sizeof(STTS_Cache_Entry)/sizeof(kal_uint32);

   *puSTTSCachePoolUsed = 0;

   if ((ret=MP4_GetTrackNoByType(pstMp4Parser, MP4_TRACK_AUDIO, &bTrackNo))!=MP4_PARSER_OK)
      pAudioTrack = NULL;
   else
      pAudioTrack = &(pstMp4Parser->stMp4Track[bTrackNo]);

   if ((ret=MP4_GetTrackNoByType(pstMp4Parser, 

⌨️ 快捷键说明

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