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

📄 mp4_parser_stbl.c

📁 最新MTK手机软件源码
💻 C
📖 第 1 页 / 共 5 页
字号:
   pCurTrack = &(pstMp4Parser->stMp4Track[bTrackNo]);

   pCurTrack->uDecodeTimeDelta_SampleNo++;
   uSampleNo = pCurTrack->uDecodeTimeDelta_SampleNo;

   if (uSampleNo < pCurTrack->uDecodeTimeDelta_CurSampleCount) {
      *puDecodeTimeDelta = pCurTrack->uDecodeTimeDelta_ThisSampleDelta;
      return MP4_PARSER_OK;
   }

   pCurTrack->uDecodeTimeDelta_TableIndex++;

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

   uDecodeTimeToSampleTableSize = pCurTrack->uTimeToSampleTableEntryCount;

   if (pCurTrack->uDecodeTimeDelta_TableIndex >= uDecodeTimeToSampleTableSize)
      return MP4_PARSER_READ_EOF;

   if ((ret=MP4_GetSampleCountAndDelta(pstMp4Parser, pCurTrack->uDecodeTimeDelta_TableIndex, &uThisSampleCount, &uThisSampleDelta, eTrackType))!=MP4_PARSER_OK)
      return ret;

   *puDecodeTimeDelta = uThisSampleDelta;
   pCurTrack->uDecodeTimeDelta_CurSampleCount += uThisSampleCount;
   pCurTrack->uDecodeTimeDelta_ThisSampleDelta = uThisSampleDelta;

   return MP4_PARSER_OK;
}

/*******************************************************************************
   Get the decode time delta of certain number of consecutive samples in the
   specified track.
*******************************************************************************/
MP4_Parser_Status MP4_GetDecodeTimeDelta_Array(STMp4Parser *pstMp4Parser, kal_uint32 uSampleNo,
                                               kal_uint64 *puDecodeTimeDeltaArray, kal_uint32 *pArraySize,
                                               MP4_Track_Type eTrackType)
{
   kal_uint32 uIndex;
   MP4_Parser_Status ret;

   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
   MP4_PARSER_CHECK_ARG(puDecodeTimeDeltaArray!=NULL);
   MP4_PARSER_CHECK_ARG(pArraySize!=0);

   if ((ret=MP4_GetDecodeTimeDelta(pstMp4Parser, uSampleNo, &(puDecodeTimeDeltaArray[0]) , eTrackType))!=MP4_PARSER_OK)
      return ret;

   for (uIndex=1; uIndex<*pArraySize; uIndex++) {
      if ((ret=MP4_GetDecodeTimeDelta_Next(pstMp4Parser, &(puDecodeTimeDeltaArray[uIndex]) , eTrackType))!=MP4_PARSER_OK)
      {
         *pArraySize = uIndex;
         return ret;
      }
   }

   return MP4_PARSER_OK;
}

/*******************************************************************************
   Get the sample number with respect to the specified decoding time in the
   specified track.
*******************************************************************************/
MP4_Parser_Status MP4_GetSampleNumber(STMp4Parser *pstMp4Parser, kal_uint32 *puSampleNo,
                                      kal_uint64 uDecodeTime, MP4_Track_Type eTrackType)
{
   kal_uint64 uCurDecodeTime = 0;
   kal_uint32 uDecodeTimeToSampleTableSize;
   kal_uint32 uThisSampleCount;
   kal_uint32 uThisSampleDelta;
   kal_uint32 uCurSampleCount = 0;
   kal_uint32 uIndex = 0;
   kal_uint8  bTrackNo;
   MP4_Parser_Status ret;
   STMp4Track *pCurTrack;

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

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

   if (pCurTrack->uSTTSCacheTableEntryCount > 0) {
      /// STTS cache is enabled. Perform bunary search.
      kal_uint16 start_index, end_index;
      STTS_Cache_Entry *stts_cache_table;

      stts_cache_table = pCurTrack->pSTTSCacheTable;

      do { /// Initial Cache
         MP4_STTS_ProcCacheTableByTrack(pstMp4Parser, eTrackType, 64 );
      }
      while (pCurTrack->uSTTSCacheIndex != pCurTrack->uSTTSCacheTableEntryCount &&
          uDecodeTime > stts_cache_table[pCurTrack->uSTTSCacheIndex-1].accumulated_decode_time);

      start_index = 0;
      end_index = pCurTrack->uSTTSCacheIndex-1;
      while ((end_index-start_index)>1) {
         kal_uint16 middle_index = (start_index+end_index)>>1;
         if (uDecodeTime > stts_cache_table[middle_index].accumulated_decode_time)
            start_index = middle_index;
         else
            end_index = middle_index;
      }

      if (start_index) {
         uIndex = end_index * pCurTrack->uSTTSCacheTableStepSize;
         uCurSampleCount = stts_cache_table[start_index].accumulated_sample_count;
         uCurDecodeTime = stts_cache_table[start_index].accumulated_decode_time;
      }
   }

   uDecodeTimeToSampleTableSize = pCurTrack->uTimeToSampleTableEntryCount;

   for (; uIndex<uDecodeTimeToSampleTableSize; uIndex++) {
      if ((ret=MP4_GetSampleCountAndDelta(pstMp4Parser, uIndex, &uThisSampleCount, &uThisSampleDelta, eTrackType))!=MP4_PARSER_OK)
         return ret;
      uCurDecodeTime += (kal_uint64)uThisSampleCount * (kal_uint64)uThisSampleDelta;
      uCurSampleCount += uThisSampleCount;
      if (uCurDecodeTime >= uDecodeTime) {
         *puSampleNo = uCurSampleCount - (uCurDecodeTime-uDecodeTime+uThisSampleDelta-1)/uThisSampleDelta;
         return MP4_PARSER_OK;
      }
   }

   return MP4_PARSER_NO_SUCH_SAMPLE;
}

/*******************************************************************************
   Get the decode time with respect to the specified sample number in the
   specified track.
*******************************************************************************/
MP4_Parser_Status MP4_GetDecodeTime(STMp4Parser *pstMp4Parser, kal_uint32 uSampleNo,
                                    kal_uint64 *puDecodeTime, MP4_Track_Type eTrackType )
{
   kal_uint32 uDecodeTimeToSampleTableSize;
   kal_uint32 uThisSampleCount;
   kal_uint32 uThisSampleDelta = 0;
   kal_uint32 uCurSampleCount = 0;
   kal_uint32 uIndex = 0;
   kal_uint8 bTrackNo;
   MP4_Parser_Status ret;
   STMp4Track *pCurTrack;

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

   *puDecodeTime = 0;

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

   pCurTrack = &(pstMp4Parser->stMp4Track[bTrackNo]);

   if (pCurTrack->uSTTSCacheTableEntryCount > 0) {
      /// STTS cache is enabled. Perform binary search.
      kal_uint16 start_index, end_index;
      STTS_Cache_Entry *stts_cache_table;

      stts_cache_table = pCurTrack->pSTTSCacheTable;

      do { /// Initial Cache
         MP4_STTS_ProcCacheTableByTrack(pstMp4Parser, eTrackType, 32 );
      }
      while (pCurTrack->uSTTSCacheIndex != pCurTrack->uSTTSCacheTableEntryCount &&
          uSampleNo > stts_cache_table[pCurTrack->uSTTSCacheIndex-1].accumulated_sample_count);

      start_index = 0;
      end_index = pCurTrack->uSTTSCacheIndex-1;
      while ((end_index-start_index)>1) {
         kal_uint16 middle_index = (start_index+end_index)>>1;
         if (uSampleNo > stts_cache_table[middle_index].accumulated_sample_count)
            start_index = middle_index;
         else
            end_index = middle_index;
      }

      if (start_index) {
         uIndex = end_index * pCurTrack->uSTTSCacheTableStepSize;
         uCurSampleCount = stts_cache_table[start_index].accumulated_sample_count;
         *puDecodeTime = stts_cache_table[start_index].accumulated_decode_time;
      }
   }

   uDecodeTimeToSampleTableSize = pCurTrack->uTimeToSampleTableEntryCount;

   for (; uIndex<uDecodeTimeToSampleTableSize; uIndex++) {
      if ((ret=MP4_GetSampleCountAndDelta(pstMp4Parser, uIndex, &uThisSampleCount, &uThisSampleDelta, eTrackType))!=MP4_PARSER_OK)
         return ret;
      uCurSampleCount += uThisSampleCount;
      if (uCurSampleCount > uSampleNo) {
         *puDecodeTime += (kal_uint64)uThisSampleDelta * (kal_uint64)(uSampleNo - uCurSampleCount + uThisSampleCount );
         break;
      } else {
         *puDecodeTime += (kal_uint64)uThisSampleDelta * (kal_uint64)uThisSampleCount;
      }
   }

   /// if the decode time of the specified sample is 0, it is an error case.
   if (uSampleNo != 0 && *puDecodeTime == pCurTrack->uDecodeTime_PrevDecodeTime
       && uSampleNo != pCurTrack->uDecodeTime_SampleNo)
      return MP4_PARSER_PARSE_ERROR;

   pCurTrack->uDecodeTime_SampleNo        = uSampleNo;
   pCurTrack->uDecodeTime_TableIndex      = uIndex;
   pCurTrack->uDecodeTime_PrevDecodeTime  = *puDecodeTime;
   pCurTrack->uDecodeTime_ThisSampleDelta = uThisSampleDelta;
   pCurTrack->uDecodeTime_CurSampleCount  = uCurSampleCount;
   return MP4_PARSER_OK;
}

/*******************************************************************************
   Get the decode time of the "NEXT" sample in the specified track.
*******************************************************************************/
MP4_Parser_Status MP4_GetDecodeTime_Next(STMp4Parser *pstMp4Parser, kal_uint64 *puDecodeTime,
                                         MP4_Track_Type eTrackType)
{
   MP4_Parser_Status ret;
   kal_uint32 uSampleNo;
   kal_uint32 uDecodeTimeToSampleTableSize;
   kal_uint32 uThisSampleCount;
   kal_uint32 uThisSampleDelta;
   kal_uint8  bTrackNo;
   STMp4Track *pCurTrack;

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

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

   uSampleNo = pCurTrack->uDecodeTime_SampleNo;
   pCurTrack->uDecodeTime_SampleNo++;

   if (uSampleNo < pCurTrack->uDecodeTime_CurSampleCount) {
      pCurTrack->uDecodeTime_PrevDecodeTime += pCurTrack->uDecodeTime_ThisSampleDelta;
      *puDecodeTime = pCurTrack->uDecodeTime_PrevDecodeTime;
      return MP4_PARSER_OK;
   }

   pCurTrack->uDecodeTime_TableIndex++;
   
   uDecodeTimeToSampleTableSize = pCurTrack->uTimeToSampleTableEntryCount;

   if (pCurTrack->uDecodeTime_TableIndex >= uDecodeTimeToSampleTableSize)
      return MP4_PARSER_READ_EOF;

   if ((ret=MP4_GetSampleCountAndDelta(pstMp4Parser, pCurTrack->uDecodeTime_TableIndex, &uThisSampleCount, &uThisSampleDelta, eTrackType))!=MP4_PARSER_OK)
      return ret;

   pCurTrack->uDecodeTime_PrevDecodeTime += uThisSampleDelta;
   pCurTrack->uDecodeTime_CurSampleCount += uThisSampleCount;
   pCurTrack->uDecodeTime_ThisSampleDelta = uThisSampleDelta;
   *puDecodeTime = pCurTrack->uDecodeTime_PrevDecodeTime;

   return MP4_PARSER_OK;
}

/*******************************************************************************
   Get the decode time of certain number of consecutive samples in the
   specified track.
*******************************************************************************/
MP4_Parser_Status MP4_GetDecodeTime_Array(STMp4Parser *pstMp4Parser, kal_uint32 uSampleNo,
                                          kal_uint64 *puDecodeTimeArray, kal_uint32 *pArraySize,
                                          MP4_Track_Type eTrackType)
{
   kal_uint32 uIndex;
   MP4_Parser_Status ret;

   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
   MP4_PARSER_CHECK_ARG(puDecodeTimeArray!=NULL);
   MP4_PARSER_CHECK_ARG(pArraySize!=0);

   if ((ret=MP4_GetDecodeTime(pstMp4Parser, uSampleNo, &(puDecodeTimeArray[0]) , eTrackType))!=MP4_PARSER_OK)
      return ret;

   for (uIndex=1; uIndex<*pArraySize; uIndex++) {
      if ((ret=MP4_GetDecodeTime_Next(pstMp4Parser, &(puDecodeTimeArray[uIndex]) , eTrackType))!=MP4_PARSER_OK)
      {
         *pArraySize = uIndex;
         return ret;
      }
   }

   return MP4_PARSER_OK;
}



/* --------------------- Sync Sample Box related functions --------------------- */

/*******************************************************************************
   Get the sync sample number with respect to the given index in the sync
   sample table of the specified track.
*******************************************************************************/
static MP4_Parser_Status MP4_GetSyncSampleNo(STMp4Parser *pstMp4Parser, kal_uint32 uIndex,
                                             kal_uint32 *puSyncSampleNo, MP4_Track_Type type)
{
   MP4_Parser_Status ret;
   kal_uint32 uOffset;
   kal_uint8 bTrackNo;

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

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

   MP4_PARSER_ASSERT(uIndex < pstMp4Parser->stMp4Track[bTrackNo].uSyncCount);

   uOffset = pstMp4Parser->stMp4Track[bTrackNo].uOffsetSyncSampleTable;
   uOffset += (uIndex * 4);

   if ((pstMp4Parser->eFSALErr=FSAL_Seek(pstMp4Parser->pstFSAL, uOffset))!=FSAL_OK)
      return MP4_PARSER_FILE_SEEK_ERROR;

   if ((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, puSyncSampleNo))!=FSAL_OK)
      return MP4_PARSER_FILE_READ_ERROR;

   /// Change starting number of index from 1 to 0.
   *puSyncSampleNo -= 1;

   return MP4_PARSER_OK;
}

/*******************************************************************************
   Get the sample number of the previous sync sample of the specified track.
*******************************************************************************/
MP4_Parser_Status MP4_GetPrevSyncSampleNo(STMp4Parser *pstMp4Parser, kal_uint32 uCurSampleNo,
                                          kal_uint32 *puPrevSyncSampleNo, MP4_Track_Type eTrackType)
{
   kal_uint32 uSyncSampleNo = 0;
   kal_uint32 uStartIndex, uEndIndex;
   kal_uint8 bTrackNo;
   MP4_Parser_Status ret;
   STMp4Track *pCurTrack;

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

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

⌨️ 快捷键说明

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