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

📄 mp4_parser_audio.c

📁 最新MTK手机软件源码
💻 C
📖 第 1 页 / 共 3 页
字号:
   MP4_PARSER_ASSERT(pstMp4Parser->uADIFFrameHeaderLen ==
      (63 + pstMp4Parser->uAudioPCEBitLength + 7) / 8 + 1);
   
   return MP4_PARSER_OK;
}
/*
 * Prepare for every audio sample of the whole stream.
 */
void prepareADTSFrameHeader(STMp4Parser *pstMp4Parser, kal_uint8* pbFrameHeader, kal_uint32 uSampleSize)
{
   kal_uint32 uBitCnt;

   MP4_PARSER_ASSERT_NO_RET_VAL(pstMp4Parser!=NULL);
   MP4_PARSER_ASSERT_NO_RET_VAL(pbFrameHeader!=NULL);

   /* adts_fixed_header */
   uBitCnt = 0;
   putbits(pbFrameHeader, &uBitCnt, 0xFFF, 12); // syncword
   putbits(pbFrameHeader, &uBitCnt, 0, 1);      // ID
   putbits(pbFrameHeader, &uBitCnt, 0, 2);      // Layer
   putbits(pbFrameHeader, &uBitCnt, 1, 1);      // Protection absent
   putbits(pbFrameHeader, &uBitCnt, 1, 2);      // Profile
   putbits(pbFrameHeader, &uBitCnt, MP4_Audio_GetFreqIndex(pstMp4Parser), 4); // sample_frequency_index
   putbits(pbFrameHeader, &uBitCnt, 0, 1);      // private_bit
   putbits(pbFrameHeader, &uBitCnt, pstMp4Parser->bAudioChannelConfig, 3); // Channel_configuration
   putbits(pbFrameHeader, &uBitCnt, 1, 1);      // original_copy
   putbits(pbFrameHeader, &uBitCnt, 0, 1);      // Home

   /* adts_variable_header */
   putbits(pbFrameHeader, &uBitCnt, 0, 1);      // copy_identification_bit
   putbits(pbFrameHeader, &uBitCnt, 0, 1);      // copy_identification_byte
   putbits(pbFrameHeader, &uBitCnt, uSampleSize + ADTS_HEADER_SIZE, 13); // length
   putbits(pbFrameHeader, &uBitCnt, 0x7FF, 11); // buffer_fullness
   putbits(pbFrameHeader, &uBitCnt, 0, 2);      // no_raw_data_blocks_in_frame
   MP4_PARSER_ASSERT_NO_RET_VAL(uBitCnt==56);
}

MP4_Parser_Status prepareAACFrameHeader(STMp4Parser *pstMp4Parser)
{
   MP4_Parser_Status ret;
   MP4_Audio_Type eAudioType;

   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);

   eAudioType = MP4_GetAudioType(pstMp4Parser);
   if (eAudioType != MP4_AUDIO_AAC)
      return MP4_PARSER_OK;

   if (pstMp4Parser->bAudioChannelConfig==0) {
      /* Generate ADIF stream */
      pstMp4Parser->bAddADIFFrameHeader = KAL_TRUE;
      if ((ret=prepareADIFFrameHeader(pstMp4Parser))!=MP4_PARSER_OK)
         return ret;
   } else {
      /* Generate ADTS stream */
      pstMp4Parser->bAddADTSFrameHeader = KAL_TRUE;
   }
   
   return MP4_PARSER_OK;
}



kal_uint8 MP4_Audio_GetFreqIndex(STMp4Parser *pstMp4Parser)
{
   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);

   return pstMp4Parser->bAudioSamplingFreqIndex;
}



MP4_Parser_Status MP4_Audio_SetFSAL(STMp4Parser *pstMp4Parser, STFSAL *pstFSALAudio)
{
   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
   MP4_PARSER_CHECK_ARG(pstFSALAudio!=NULL);
   
   pstMp4Parser->pstFSALAudio = pstFSALAudio;

   return MP4_PARSER_OK;
}



MP4_Parser_Status MP4_Audio_Seek_To_Video(STMp4Parser *pstMp4Parser, kal_uint64 uVideoDecodeTime, kal_uint32 *puAudioSampleNo)
{
   MP4_Parser_Status ret;
   kal_uint64 uAudioDecodeTime;
   kal_uint32 uVideoTimeScale;
   kal_uint32 uAudioTimeScale;
   
   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
   MP4_PARSER_CHECK_ARG(puAudioSampleNo!=NULL);

   if ((ret=MP4_GetMediaTimeScale(pstMp4Parser, &uVideoTimeScale, MP4_TRACK_VIDEO))!=MP4_PARSER_OK)
      return ret;

   if ((ret=MP4_GetMediaTimeScale(pstMp4Parser, &uAudioTimeScale, MP4_TRACK_AUDIO))!=MP4_PARSER_OK)
      return ret;

   uAudioDecodeTime = uVideoDecodeTime * uAudioTimeScale / uVideoTimeScale;   
   if ((ret=MP4_GetSampleNumber(pstMp4Parser, puAudioSampleNo, uAudioDecodeTime, MP4_TRACK_AUDIO ))!=MP4_PARSER_OK)
      return ret;
   
   return MP4_PARSER_OK;
}



MP4_Parser_Status MP4_Audio_Seek(STMp4Parser *pstMp4Parser, kal_uint32 uAudioSampleNo)
{
   MP4_Parser_Status ret;
   kal_uint32 uAudioSampleCount;
   kal_uint32 uAudioTimeScale;
   kal_uint64 uAudioDecodeTime;

   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);

   pstMp4Parser->uAudioReadSampleNo = uAudioSampleNo;
   pstMp4Parser->uAudioReadSampleOffset = 0;
   pstMp4Parser->uADTSHeaderReadOffset = 0;

   if ((ret=MP4_GetMediaTimeScale(pstMp4Parser, &uAudioTimeScale, MP4_TRACK_AUDIO))!=MP4_PARSER_OK)
      return ret;

   if ((ret=MP4_GetSampleCount(pstMp4Parser, MP4_TRACK_AUDIO, &uAudioSampleCount))!=MP4_PARSER_OK)
      return ret;

   if ((ret=MP4_GetDecodeTime(pstMp4Parser, uAudioSampleNo, &uAudioDecodeTime, MP4_TRACK_AUDIO))!=MP4_PARSER_OK)
      return ret;
   
   pstMp4Parser->uAudioSeekPointTime = uAudioDecodeTime * 1000 / uAudioTimeScale;

   if (uAudioSampleNo < uAudioSampleCount) { 
      if ((ret=MP4_GetSampleOffset(pstMp4Parser, uAudioSampleNo, &(pstMp4Parser->uAudioReadSampleFileOffset), MP4_TRACK_AUDIO))!=MP4_PARSER_OK)
         return ret;
   }
   
   return MP4_PARSER_OK;
}



/*
 * Invoke MP4_GetSampleOffset_Next for optimization
 */
MP4_Parser_Status MP4_Audio_Seek_Internal(STMp4Parser *pstMp4Parser, kal_uint32 uAudioSampleNo)
{
   MP4_Parser_Status ret;
   kal_uint32 uAudioSampleCount;

   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);

   pstMp4Parser->uAudioReadSampleNo = uAudioSampleNo;
   pstMp4Parser->uAudioReadSampleOffset = 0;
   pstMp4Parser->uADTSHeaderReadOffset = 0;

   if ((ret=MP4_GetSampleCount(pstMp4Parser, MP4_TRACK_AUDIO, &uAudioSampleCount))!=MP4_PARSER_OK)
      return ret;

   if (uAudioSampleNo<uAudioSampleCount) { 
      if ((ret=MP4_GetSampleOffset_Next(pstMp4Parser, &(pstMp4Parser->uAudioReadSampleFileOffset), MP4_TRACK_AUDIO))!=MP4_PARSER_OK)
         return ret;
   }

   return MP4_PARSER_OK;
}

/* Update some variables after reading some data */
#define MP4_AUDIO_READ_UPDATE(uLen) \
   *uReadSize += (uLen); \
   pBuf += (uLen); \
   uSizeLeft -= (uLen)

/**
 * Read audio samples as a contiguous stream.
 * Note that fsal_direct_seek must be done immediately before fsal_direct_read,
 * to avoid the situation
 * that when accessing sample tables, file position has been changed.
 */
MP4_Parser_Status MP4_Audio_Read(STMp4Parser *pstMp4Parser, kal_uint8* pBuf, kal_uint32 uSize, kal_uint32 *uReadSize)
{
   MP4_Parser_Status ret;
   kal_uint32 uSizeLeft = uSize;
   kal_uint32 uCurSampleSize;
   kal_uint32 uCurSampleOffset;
   kal_uint32 uSampleCount;
   kal_uint32 uFileOffset;
   kal_uint8 *pbADTSFrameHeader;
   kal_uint8 *pbADIFFrameHeader;

   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
   MP4_PARSER_CHECK_ARG(pstMp4Parser->pstFSALAudio!=NULL);
   MP4_PARSER_CHECK_ARG(pBuf!=NULL);
   MP4_PARSER_CHECK_ARG(uReadSize!=NULL);

   /* Initialize some local variables */
   *uReadSize = 0;
   pbADTSFrameHeader = pstMp4Parser->pbADTSFrameHeader;
   pbADIFFrameHeader = pstMp4Parser->pbADIFFrameHeader;

   /* consider when there is no audio track or audio sample number is 0 */
   if ((ret=MP4_GetSampleCount(pstMp4Parser, MP4_TRACK_AUDIO, &uSampleCount))!=MP4_PARSER_OK)
      return ret;
   if (pstMp4Parser->uAudioReadSampleNo >= uSampleCount)
      return MP4_PARSER_READ_EOF;

   if ((ret=MP4_GetSampleSize(pstMp4Parser, pstMp4Parser->uAudioReadSampleNo, &uCurSampleSize, MP4_TRACK_AUDIO))!=MP4_PARSER_OK)
      return ret;
   uCurSampleOffset = pstMp4Parser->uAudioReadSampleOffset;
   uFileOffset = pstMp4Parser->uAudioReadSampleFileOffset;
   if (KAL_TRUE == pstMp4Parser->bAddADIFFrameHeader) {
      /* handle the case if the ADTS frame header has not been read out completely */
      if (pstMp4Parser->uADIFHeaderReadOffset < pstMp4Parser->uADIFFrameHeaderLen) {
         kal_uint32 uADIFFrameSizeLeft = pstMp4Parser->uADIFFrameHeaderLen - pstMp4Parser->uADIFHeaderReadOffset;
         if (uADIFFrameSizeLeft >= uSizeLeft) {
            kal_mem_cpy(pBuf, pbADIFFrameHeader + pstMp4Parser->uADIFHeaderReadOffset, uSizeLeft);
            pstMp4Parser->uADIFHeaderReadOffset += uSizeLeft;
            MP4_AUDIO_READ_UPDATE(uSizeLeft);
            return MP4_PARSER_OK;
         } else {
            kal_mem_cpy(pBuf, pbADIFFrameHeader + pstMp4Parser->uADIFHeaderReadOffset, uADIFFrameSizeLeft);
            pstMp4Parser->uADIFHeaderReadOffset = pstMp4Parser->uADIFFrameHeaderLen;
            MP4_AUDIO_READ_UPDATE(uADIFFrameSizeLeft);
         }
      }
   }

   if (KAL_TRUE == pstMp4Parser->bAddADTSFrameHeader) {
      /* handle the case if the ADTS frame header has been read partially */
      if (pstMp4Parser->uADTSHeaderReadOffset < ADTS_HEADER_SIZE) {
         kal_uint32 uADTSFrameSizeLeft = ADTS_HEADER_SIZE - pstMp4Parser->uADTSHeaderReadOffset;
         prepareADTSFrameHeader(pstMp4Parser, pbADTSFrameHeader, uCurSampleSize);
         if (uADTSFrameSizeLeft >= uSizeLeft) {
            kal_mem_cpy(pBuf, pbADTSFrameHeader + pstMp4Parser->uADTSHeaderReadOffset, uSizeLeft);
            pstMp4Parser->uADTSHeaderReadOffset += uSizeLeft;
            MP4_AUDIO_READ_UPDATE(uSizeLeft);
            return MP4_PARSER_OK;
         } else {
            kal_mem_cpy(pBuf, pbADTSFrameHeader + pstMp4Parser->uADTSHeaderReadOffset, uADTSFrameSizeLeft);
            pstMp4Parser->uADTSHeaderReadOffset = ADTS_HEADER_SIZE;
            MP4_AUDIO_READ_UPDATE(uADTSFrameSizeLeft);
         }
      }       
   }

   /* handle the case if the current sample has been read partially */
   if (pstMp4Parser->uAudioReadSampleOffset!=0) {
      kal_uint32 uCurSampleSizeLeft = uCurSampleSize - uCurSampleOffset;
      uFileOffset += pstMp4Parser->uAudioReadSampleOffset;
      if ((pstMp4Parser->eFSALErr=FSAL_Seek(pstMp4Parser->pstFSALAudio, uFileOffset))!=FSAL_OK)
         return MP4_PARSER_FILE_SEEK_ERROR;
      if (uCurSampleSizeLeft > uSizeLeft) {
         if ((pstMp4Parser->eFSALErr=FSAL_Read(pstMp4Parser->pstFSALAudio, pBuf, uSizeLeft))!=FSAL_OK)
            return MP4_PARSER_FILE_READ_ERROR;
         pstMp4Parser->uAudioReadSampleOffset += uSizeLeft;
         MP4_AUDIO_READ_UPDATE(uSizeLeft);
         return MP4_PARSER_OK;
      } else {
         if ((pstMp4Parser->eFSALErr=FSAL_Read(pstMp4Parser->pstFSALAudio, pBuf, uCurSampleSizeLeft))!=FSAL_OK)
            return MP4_PARSER_FILE_READ_ERROR;
         MP4_AUDIO_READ_UPDATE(uCurSampleSizeLeft);
         /* read out the current sample, seek to next sample */
         if ((ret=MP4_Audio_Seek_Internal(pstMp4Parser, pstMp4Parser->uAudioReadSampleNo+1))!=MP4_PARSER_OK)
            return ret;
      }
   }
   
   while(uSizeLeft > 0 && pstMp4Parser->uAudioReadSampleNo < uSampleCount) {
      if ((ret=MP4_GetSampleSize(pstMp4Parser, pstMp4Parser->uAudioReadSampleNo, &uCurSampleSize, MP4_TRACK_AUDIO))!=MP4_PARSER_OK)
         return ret;
      uFileOffset = pstMp4Parser->uAudioReadSampleFileOffset;
      if ((pstMp4Parser->eFSALErr=FSAL_Seek(pstMp4Parser->pstFSALAudio, uFileOffset))!=FSAL_OK)
         return MP4_PARSER_FILE_SEEK_ERROR;
      if (KAL_TRUE == pstMp4Parser->bAddADTSFrameHeader) {
         if (pstMp4Parser->uADTSHeaderReadOffset < ADTS_HEADER_SIZE) {
            kal_uint32 uADTSFrameSizeLeft = ADTS_HEADER_SIZE - pstMp4Parser->uADTSHeaderReadOffset;
            prepareADTSFrameHeader(pstMp4Parser, pbADTSFrameHeader, uCurSampleSize);
            if (uADTSFrameSizeLeft >= uSizeLeft) {
               kal_mem_cpy(pBuf, pbADTSFrameHeader + pstMp4Parser->uADTSHeaderReadOffset, uSizeLeft);
               pstMp4Parser->uADTSHeaderReadOffset += uSizeLeft;
               MP4_AUDIO_READ_UPDATE(uSizeLeft);
               break;
            } else {
               kal_mem_cpy(pBuf, pbADTSFrameHeader + pstMp4Parser->uADTSHeaderReadOffset, uADTSFrameSizeLeft);
               pstMp4Parser->uADTSHeaderReadOffset = ADTS_HEADER_SIZE;
               MP4_AUDIO_READ_UPDATE(uADTSFrameSizeLeft);
            }
         }
      }
      if (uCurSampleSize > uSizeLeft) {
         if((pstMp4Parser->eFSALErr=FSAL_Read(pstMp4Parser->pstFSALAudio, pBuf, uSizeLeft))!=FSAL_OK)
            return MP4_PARSER_FILE_READ_ERROR;
         pstMp4Parser->uAudioReadSampleOffset = uSizeLeft;
         MP4_AUDIO_READ_UPDATE(uSizeLeft);
         break;
      } else {
         if ((pstMp4Parser->eFSALErr=FSAL_Read(pstMp4Parser->pstFSALAudio, pBuf, uCurSampleSize))!=FSAL_OK)
            return MP4_PARSER_FILE_READ_ERROR;
         MP4_AUDIO_READ_UPDATE(uCurSampleSize);
         if ((ret=MP4_Audio_Seek_Internal(pstMp4Parser, pstMp4Parser->uAudioReadSampleNo+1))!=MP4_PARSER_OK)
            return ret;
      }     
   }

   if (pstMp4Parser->uAudioReadSampleNo >= uSampleCount)
      return MP4_PARSER_READ_EOF;
   else
      return MP4_PARSER_OK;
}

MP4_Parser_Status MP4_Audio_TimeToSampleNo(STMp4Parser *pstMp4Parser, kal_uint64 uMiliSecond, kal_uint32 *puAudioSampleNo )
{
   MP4_Parser_Status ret;
   kal_uint64 uAudioDecodeTime;
   kal_uint32 uAudioTimeScale;
   
   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
   MP4_PARSER_CHECK_ARG(puAudioSampleNo!=NULL);

   if ((ret=MP4_GetMediaTimeScale(pstMp4Parser, &uAudioTimeScale, MP4_TRACK_AUDIO))!=MP4_PARSER_OK)
      return ret;

   uAudioDecodeTime = uMiliSecond * uAudioTimeScale / 1000;   
   if ((ret=MP4_GetSampleNumber(pstMp4Parser, puAudioSampleNo, uAudioDecodeTime, MP4_TRACK_AUDIO))!=MP4_PARSER_OK)
      return ret;
      
   return MP4_PARSER_OK;
}

⌨️ 快捷键说明

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