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

📄 mp4_parser_audio.c

📁 最新MTK手机软件源码
💻 C
📖 第 1 页 / 共 3 页
字号:
      unsigned int type;

      if((ret=mp4_parse_box(pstMp4Parser, &size, &type))!=MP4_PARSER_OK)
         return ret;
      if(type==BOX_TYPE_ESDS) {
         if((ret=mp4_parse_esds(pstMp4Parser, size))!=MP4_PARSER_OK)
            return ret;
      } else
         return MP4_PARSER_PARSE_ERROR;
   }

   return MP4_PARSER_OK;
}



/*
DESCRIPTION
   Parse AMR Specific Box.
INPUT
   size: The size of AMR Specific Box excluding Box
RETURN
   MP4_PARSER_OK: Successful
   other values: Error
*/

static MP4_Parser_Status mp4_parse_damr(STMp4Parser *pstMp4Parser, long damr_size)
{
   kal_uint16 mode_set;
   kal_uint8 mode_change_period;
   kal_uint8 bFramesPerSample;

   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);

   /* AMR Decoder Specific Structure */
   if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, 5))!=FSAL_OK)
      return MP4_PARSER_FILE_SEEK_ERROR;
   if((pstMp4Parser->eFSALErr=FSAL_Read_UINT16(pstMp4Parser->pstFSAL, &mode_set))!=FSAL_OK)
      return MP4_PARSER_PARSE_ERROR;
   if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, &mode_change_period, 1))!=FSAL_OK)
      return MP4_PARSER_FILE_READ_ERROR;
   if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, &bFramesPerSample, 1))!=FSAL_OK)
      return MP4_PARSER_FILE_READ_ERROR;
   damr_size-=9;
#if MP4_PARSER_VERBOSE
   printf("mode_set=%0X, mode_change_period=%0X, frames_per_sample=%0X\n",
      mode_set, mode_change_period, bFramesPerSample);
#endif
   pstMp4Parser->bFramesPerSample = bFramesPerSample;

   if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, damr_size))!=FSAL_OK)
      return MP4_PARSER_PARSE_ERROR;

   return MP4_PARSER_OK;
}



kal_uint8 mp4_audio_amr_get_frame_per_sample(STMp4Parser *pstMp4Parser)
{
   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
   
   return pstMp4Parser->bFramesPerSample;
}



/*
DESCRIPTION
   Parse Sample Entry SAMR or SAWB.
INPUT
   size: The size of Sample Entry SAMR or SAWB excluding Box
RETURN
   MP4_PARSER_OK: Successful
   other values: Error
*/

MP4_Parser_Status mp4_parse_samr(STMp4Parser *pstMp4Parser, long samr_size)
{
   /* Sample Entry SAMR or SAWB is a leaf node. */
   MP4_Parser_Status ret;

   /* Audio Sample Entry */
   kal_uint16 channelcount;
   kal_uint16 samplesize;
   kal_uint32 uSampleRate;

   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);

   /* Sample Entry */
   if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, 8))!=FSAL_OK)
      return MP4_PARSER_PARSE_ERROR;
   samr_size-=8;

   /* Audio Sample Entry */
   if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, 8))!=FSAL_OK)
      return MP4_PARSER_FILE_SEEK_ERROR;
   if((pstMp4Parser->eFSALErr=FSAL_Read_UINT16(pstMp4Parser->pstFSAL, &channelcount))!=FSAL_OK)
      return MP4_PARSER_PARSE_ERROR;
   if((pstMp4Parser->eFSALErr=FSAL_Read_UINT16(pstMp4Parser->pstFSAL, &samplesize))!=FSAL_OK)
      return MP4_PARSER_PARSE_ERROR;
   if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, 4))!=FSAL_OK)
      return MP4_PARSER_PARSE_ERROR;
   if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &uSampleRate))!=FSAL_OK)
      return MP4_PARSER_FILE_READ_ERROR;

   pstMp4Parser->bAudioSamplingFreqIndex = convertSamplingFreqToIndex(uSampleRate>>16);

   samr_size-=20;
   
#if MP4_PARSER_VERBOSE
   printf("channel=%u, samplesize=%u, samplerate=%u\n",
      channelcount, samplesize, uSampleRate>>16);
#endif

   /* AMRSpecificBox */
   {
      kal_uint32 size, type;

      if((ret=mp4_parse_box(pstMp4Parser, &size, &type))!=MP4_PARSER_OK)
         return ret;
      if(type==BOX_TYPE_DAMR) {
         if((ret=mp4_parse_damr(pstMp4Parser, size))!=MP4_PARSER_OK)
            return ret;
      } else
         return MP4_PARSER_DAMR_BOX_EXPECTED;
   }

   return MP4_PARSER_OK;
}



/*
DESCRIPTION
   Parse the AudioSpecificConfig of 14496-3.
INPUT
   size: The size of the decoder specific info.
RETURN
   MP4_PARSER_OK: Successful
   other values: Error
*/

MP4_Parser_Status mp4_parse_decoder_config_14496_3(STMp4Parser *pstMp4Parser, long box_size)
{
   MP4_Parser_Status ret;
   kal_uint32 uBitCnt = 0;

   /* Audio Specific Config */
   kal_uint8 audioObjectType;
   kal_uint8 samplingFreqIndex;
   kal_uint32 samplingFreq;

   /* GA Specific Config */
   kal_uint8 frameLengthFlag;
   kal_uint8 dependsOnCoreCoder;
   kal_uint8 extensionFlag;

   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);

   /* Refer to 14496-3 Subpart 1 */

   /* audio object type */
   if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &audioObjectType, 5))!=FSAL_OK)
      return MP4_PARSER_FILE_READ_ERROR;

   if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &samplingFreqIndex, 4))!=FSAL_OK)
      return MP4_PARSER_FILE_READ_ERROR;
   
   if(samplingFreqIndex==0xf) {
      kal_uint8 freq[3];
      if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &freq[2], 8))!=FSAL_OK)
         return MP4_PARSER_FILE_READ_ERROR;
      if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &freq[1], 8))!=FSAL_OK)
         return MP4_PARSER_FILE_READ_ERROR;
      if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &freq[0], 8))!=FSAL_OK)
         return MP4_PARSER_FILE_READ_ERROR;

      samplingFreq = (freq[2]<<16) + (freq[1]<<8) + (freq[0]);

      /* Refer to 14496-3 Subpart 4 */
      samplingFreqIndex = convertSamplingFreqToIndex(samplingFreq);
   } else if(samplingFreqIndex==0xc) {
      /* Refer to 14496-3 Subpart 4 */
      samplingFreqIndex = 0xb;
   } else if(samplingFreqIndex==0xd || samplingFreqIndex==0xe) {
      return MP4_PARSER_PARSE_ERROR;
   }
   if(samplingFreqIndex<=0x02) {
      return MP4_PARSER_SAMPLING_FREQ_NOT_SUPPORT;
   }

   pstMp4Parser->bAudioSamplingFreqIndex = samplingFreqIndex;

   /* channel configuration */
   if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &(pstMp4Parser->bAudioChannelConfig), 4))!=FSAL_OK)
      return MP4_PARSER_FILE_READ_ERROR;
   if(pstMp4Parser->bAudioChannelConfig>0x02)
      return MP4_PARSER_AUDIO_TOO_MANY_CHANNEL;

   /* GA Specific Config */
   /* Refer to 14496-3 Part 4 */

   /* frame length flag */
   if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &frameLengthFlag, 1))!=FSAL_OK)
      return MP4_PARSER_FILE_READ_ERROR;
   if(frameLengthFlag!=0)
      return MP4_PARSER_960_120_IMDCT_NOT_SUPPORT;

   /* depends on core coder */
   if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &dependsOnCoreCoder, 1))!=FSAL_OK)
      return MP4_PARSER_FILE_READ_ERROR;
   if(dependsOnCoreCoder)
      return MP4_PARSER_SCALABLE_STREAM_NOT_SUPPORT;

   /* extension flag */
   if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &extensionFlag, 1))!=FSAL_OK)
      return MP4_PARSER_FILE_READ_ERROR;

   if(pstMp4Parser->bAudioChannelConfig==0) {
      /* parse program_config_element */
      MP4_PARSER_FILE_GET_CUR_POS(pstMp4Parser->uAudioPCEFileOffset);
      
      if((ret=mp4_parse_decoder_config_14496_3_pce(pstMp4Parser, &uBitCnt))!=MP4_PARSER_OK)
         return ret;
   }

   box_size -= (uBitCnt+7)/8;

   if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, box_size))!=FSAL_OK)
      return MP4_PARSER_PARSE_ERROR;

   return MP4_PARSER_OK;
}



static void putbits(unsigned char *in, unsigned int *bitcnt, int data, int data_length)
{
   int t,count;

   MP4_PARSER_ASSERT_NO_RET_VAL(data_length>0 && data_length<=16);

   t = *bitcnt;

   if( (t & 0x7)== 0)
      in[t>>3] = 0;

   if( (t & 0x7) + data_length  <= 8)
      in[(t>>3)] |= (data << (8-((t&0x7) + data_length)));
   else {
      count = (t&7) + data_length;
      in[(t>>3)] |= (data >> (data_length - 8 + (t&7)));
      count -= 8;

      if(count > 8) {
         in[(t>>3)+1] = (unsigned char)((data >> (count-8))&0xFF);
         in[(t>>3)+2] = (unsigned char)((data << (16-count))&0xFF);
      } else {
         in[(t>>3)+1] = (unsigned char)((data << (8-count))&0xFF);
      }
   }
   *bitcnt += data_length;
}

/*
 * Prepare only once for the whole stream.
 */
MP4_Parser_Status prepareADIFFrameHeader(STMp4Parser *pstMp4Parser)
{
   kal_uint32 uBitCnt;
   kal_uint32 uBitrate;
   kal_uint8 *pbHeader;

   MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);

   pbHeader = pstMp4Parser->pbADIFFrameHeader;
   
   pstMp4Parser->uADIFHeaderReadOffset = 0;

   if(pstMp4Parser->uAudioAvgBitrate) { /* constant bitrate */
      uBitrate = pstMp4Parser->uAudioAvgBitrate;
   } else {
      uBitrate = pstMp4Parser->uAudioMaxBitrate;
   }

   /* adif_header */
   uBitCnt = 0;
   //uHeaderSize = 8 + pstMp4Parser->uAudioPCELength;
   putbits(pbHeader, &uBitCnt, 0x4144, 16); /* adif_id: AD */
   putbits(pbHeader, &uBitCnt, 0x4946, 16); /* adif_id: IF */
   putbits(pbHeader, &uBitCnt, 0, 1);     /* copyright id present */
   putbits(pbHeader, &uBitCnt, 1, 1);     /* original copy */
   putbits(pbHeader, &uBitCnt, 0, 1);     /* home */
   putbits(pbHeader, &uBitCnt, 1, 1);     /* bitstream type */
   putbits(pbHeader, &uBitCnt, (uBitrate>>7) & 0xFFFF, 16); /* bit rate */
   putbits(pbHeader, &uBitCnt, (uBitrate) & 0x7F, 7);    /* bit rate */
   putbits(pbHeader, &uBitCnt, 0x0, 4);      /* number of program config elements */
   MP4_PARSER_ASSERT(uBitCnt==63);

   /* program_config_element */
   {
      kal_int32 iBitLeft;
      kal_uint8 bPCE;

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

      iBitLeft = pstMp4Parser->uAudioPCEBitLength;
      while (iBitLeft > 0) {
         if ((pstMp4Parser->eFSALErr=FSAL_Read(pstMp4Parser->pstFSAL, &bPCE, 1))!=FSAL_OK)
            return MP4_PARSER_FILE_READ_ERROR;
         if (iBitLeft<8)
            putbits(pbHeader, &uBitCnt, bPCE, iBitLeft);
         else
            putbits(pbHeader, &uBitCnt, bPCE, 8);
         iBitLeft -= 8;
      }
   }

   /* byte alignment */
   if (uBitCnt%8 != 0)
      putbits(pbHeader, &uBitCnt, 0, 8-uBitCnt%8);

   /* comment_field_bytes */
   putbits(pbHeader, &uBitCnt, 0, 8);

   MP4_PARSER_ASSERT(uBitCnt%8 == 0);
   MP4_PARSER_ASSERT(uBitCnt<=ADIF_HEADER_SIZE*8);
   
   pstMp4Parser->uADIFFrameHeaderLen = uBitCnt/8;
   

⌨️ 快捷键说明

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