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

📄 aacdecode.c

📁 au1200 linux2.6.11 硬件解码mae驱动和maiplayer播放器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* <LIC_AMD_STD> * Copyright (c) 2005 Advanced Micro Devices, Inc. *  * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *  * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *  * The full GNU General Public License is included in this distribution in the * file called COPYING * </LIC_AMD_STD>  *//* <CTL_AMD_STD> * </CTL_AMD_STD>  *//* <DOC_AMD_STD> * </DOC_AMD_STD>  */#if defined(WIN32) || defined(UNDER_CE)  #include <windows.h>#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#ifndef _WIN32  #include <unistd.h>#endif#include "mai_osal.h" /* needed for threads */#include "audio_change_info.h"#include "faad.h"#include "aacdecode.h"   #define INIT_PRINTF(_args_)   /* MAIOSDebugPrint _args_ */#define DPRINTF(_args_)       /* MAIOSDebugPrint _args_ */#define INFO_PRINTF(_args_)   /* MAIOSDebugPrint _args_ */static int frame_number;int mp4file; static int adts_sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350,0,0,0};xheaderinfo_t xheader;static faacDecHandle hDecoder;static int header_type = 0;static int tagsize;faacDecFrameInfo frameInfo;static faacDecConfigurationPtr config;static unsigned int cb_stream_position;static unsigned int cb_stream_size;static unsigned int cb_stream_used;static unsigned char *cb_stream_buffer;static long sampleId;static int gobble_amount;//static void dumpit(unsigned char * buf, int length)//{//  int ii;//  for (ii = 0; ii < length; ii++)//    printf("%02x ", 0xff & *buf++);//  printf("\n");//}//static void dumpitc(unsigned char * buf, int length)//{//  int ii;//  unsigned cc;//  for (ii = 0; ii < length; ii++)//  {//    cc = *buf++;//    if (isprint(cc))//      printf("%c", cc);//    else//      printf(" ");//  }//  printf("\n");//}#if defined(WIN32) || defined(UNDER_CE)  #if _MSC_VER    typedef signed __int64 int64_t;  #else    typedef signed long long int64_t;  #endif#endifstatic int undownmixed_number_of_channels;#define FRAC_ONE    (1 << FRAC_BITS)#define FIX(a)   ((int)((a) * FRAC_ONE))#define FRAC_BITS   23   /* fractional bits for sb_samples and dct */#define MULL(a,b) ((int)(((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS))static short *downmix_buffer;static char *downmix_input_buffer;static int remaining_bytes;short *downmix_to_stereo(short *buf, int *length /* in bytes */) // assumes 16 bits per sample {  int ii, used;  int ch_length = *length / (undownmixed_number_of_channels * sizeof(short));   int input_length = *length;  if (remaining_bytes)  {    memcpy(downmix_input_buffer+remaining_bytes, buf, *length);    *length += remaining_bytes;    remaining_bytes = 0;    ch_length = *length / (undownmixed_number_of_channels * 2);     input_length = *length;    buf = (short *)downmix_input_buffer;  }  ch_length &= 0xfffff8; /* align to block */  switch (undownmixed_number_of_channels)  {    case 3: /* LF, CF, RF */      for (ii = 0; ii < ch_length; ii++)      {        downmix_buffer[2*ii]     = MULL(buf[3*ii],   FIX(.5)) + MULL(buf[3*ii+1], FIX(.5));        downmix_buffer[2*ii + 1] = MULL(buf[3*ii+2], FIX(.5)) + MULL(buf[3*ii+1], FIX(.5));      }      break;    case 4: /* LF, RF, LR, RR */      for (ii = 0; ii < ch_length; ii++)      {        downmix_buffer[2*ii]     = MULL(buf[4*ii],   FIX(.7)) + MULL(buf[4*ii+2], FIX(.4));        downmix_buffer[2*ii + 1] = MULL(buf[4*ii+1], FIX(.7)) + MULL(buf[4*ii+3], FIX(.4));      }      break;    case 5: /* LF, CF, RF, LR, RR */      for (ii = 0; ii < ch_length; ii++)      {        downmix_buffer[2*ii]     = MULL(buf[5*ii],   FIX(.5)) + MULL(buf[5*ii+2], FIX(.4)) + MULL(buf[5*ii+1], FIX(.5));        downmix_buffer[2*ii + 1] = MULL(buf[5*ii+2], FIX(.5)) + MULL(buf[5*ii+4], FIX(.4)) + MULL(buf[5*ii+1], FIX(.5));      }      break;    case 6: /* CF, LF, RF, LR, RR, LFE  Dolby's order is not used by AAC */            /*  0  1   2   3   4   5   */      for (ii = 0; ii < ch_length; ii++)      {        downmix_buffer[2*ii]     = MULL(buf[6*ii+1], FIX(.5)) - MULL(buf[6*ii+3], FIX(.4)) + MULL(buf[6*ii+0], FIX(.5)) + MULL(buf[6*ii+5], FIX(.2));        downmix_buffer[2*ii + 1] = MULL(buf[6*ii+2], FIX(.5)) - MULL(buf[6*ii+4], FIX(.4)) + MULL(buf[6*ii+0], FIX(.5)) + MULL(buf[6*ii+5], FIX(.2));      }      break;    case 7: /* LF, CF, RF, LR, RR, LFE, CR FIXIT this order may not be right */      for (ii = 0; ii < ch_length; ii++)      {        downmix_buffer[2*ii]     = MULL(buf[7*ii],   FIX(.5)) + MULL(buf[7*ii+2], FIX(.4)) + MULL(buf[7*ii+1], FIX(.5)) + MULL(buf[7*ii+5], FIX(.2)) + MULL(buf[7*ii+6], FIX(.3));        downmix_buffer[2*ii + 1] = MULL(buf[7*ii+2], FIX(.5)) + MULL(buf[7*ii+4], FIX(.4)) + MULL(buf[7*ii+1], FIX(.5)) + MULL(buf[7*ii+5], FIX(.2)) + MULL(buf[7*ii+6], FIX(.3));      }      break;    case 8: /* LF, RF, CF, LFE, LR, RR, LS, RS */      /* AVI files do this. See: http://www.microsoft.com/windows/windowsmedia/howto/articles/creating71audio.aspx      0  Front left        1  Front right        2  Front center        3  Low frequency        4  Back left        5  Back right        6  Side left        7  Side right        */      for (ii = 0; ii < ch_length; ii++)      {        downmix_buffer[2*ii]     = MULL(buf[7*ii],   FIX(.5)) + MULL(buf[7*ii+2], FIX(.5)) + MULL(buf[7*ii+3], FIX(.2)) - MULL(buf[7*ii+4], FIX(.2)) + MULL(buf[7*ii+6], FIX(.3));        downmix_buffer[2*ii + 1] = MULL(buf[7*ii+1], FIX(.5)) + MULL(buf[7*ii+2], FIX(.5)) + MULL(buf[7*ii+3], FIX(.2)) - MULL(buf[7*ii+5], FIX(.2)) + MULL(buf[7*ii+7], FIX(.3));      }      break;    default:      remaining_bytes = 0;      return buf;  }  used = (ch_length * undownmixed_number_of_channels * sizeof(short));  remaining_bytes = input_length - used;  memcpy(downmix_input_buffer, ((char *)buf) + input_length - remaining_bytes, remaining_bytes);  *length = (ch_length * 2 /* channels */ * sizeof(short));  return downmix_buffer;}int open_downmix(int buffer_max_size, int number_of_channels){  remaining_bytes = 0;  if (downmix_buffer != NULL)    free(downmix_buffer);  if ((downmix_buffer = (short *)malloc(buffer_max_size * sizeof(short) * number_of_channels)) == NULL)  {    DPRINTF(("Unable to allocate downmix buffer\n"));    return -1;  }  if (downmix_input_buffer != NULL)    free(downmix_input_buffer);  if ((downmix_input_buffer = (char *)malloc(buffer_max_size * sizeof(short) * number_of_channels)) == NULL)  {    DPRINTF(("Unable to allocate downmix input buffer\n"));    return -1;  }  INFO_PRINTF(("Downmix %d to 2\n", undownmixed_number_of_channels));  return 0;}void close_downmix(void){  remaining_bytes = 0;  if (downmix_buffer != NULL)    free(downmix_buffer);  downmix_buffer = NULL;  if (downmix_input_buffer != NULL)    free(downmix_input_buffer);  downmix_input_buffer = NULL;}static int adts_parse(unsigned char *buffer, long *sampling_rate, int *frame_length){  /* check syncword */  if (!((buffer[0] == 0xFF) && ((buffer[1] & 0xF6) == 0xF0)))      return 1; /* bad sync */  *sampling_rate = adts_sample_rates[(buffer[2]&0x3c)>>2];  *frame_length = ((((unsigned int)buffer[3] & 0x3)) << 11)      | (((unsigned int)buffer[4]) << 3) | (buffer[5] >> 5);  return 0;}/* channel definitions */#define SPEAKER_FRONT_LEFT             0x1#define SPEAKER_FRONT_RIGHT            0x2#define SPEAKER_FRONT_CENTER           0x4#define SPEAKER_LOW_FREQUENCY          0x8#define SPEAKER_BACK_LEFT              0x10#define SPEAKER_BACK_RIGHT             0x20#define SPEAKER_FRONT_LEFT_OF_CENTER   0x40#define SPEAKER_FRONT_RIGHT_OF_CENTER  0x80#define SPEAKER_BACK_CENTER            0x100#define SPEAKER_SIDE_LEFT              0x200#define SPEAKER_SIDE_RIGHT             0x400#define SPEAKER_TOP_CENTER             0x800#define SPEAKER_TOP_FRONT_LEFT         0x1000#define SPEAKER_TOP_FRONT_CENTER       0x2000#define SPEAKER_TOP_FRONT_RIGHT        0x4000#define SPEAKER_TOP_BACK_LEFT          0x8000#define SPEAKER_TOP_BACK_CENTER        0x10000#define SPEAKER_TOP_BACK_RIGHT         0x20000#define SPEAKER_RESERVED               0x80000000long aacChannelConfig2wavexChannelMask(faacDecFrameInfo *hInfo){    if (hInfo->channels == 6 && hInfo->num_lfe_channels)    {        return SPEAKER_FRONT_LEFT + SPEAKER_FRONT_RIGHT +            SPEAKER_FRONT_CENTER + SPEAKER_LOW_FREQUENCY +            SPEAKER_BACK_LEFT + SPEAKER_BACK_RIGHT;    } else {        return 0;    }}char *position2string(int position){    switch (position)    {    case FRONT_CHANNEL_CENTER: return "Center front";    case FRONT_CHANNEL_LEFT:   return "Left front";    case FRONT_CHANNEL_RIGHT:  return "Right front";    case SIDE_CHANNEL_LEFT:    return "Left side";    case SIDE_CHANNEL_RIGHT:   return "Right side";    case BACK_CHANNEL_LEFT:    return "Left back";    case BACK_CHANNEL_RIGHT:   return "Right back";    case BACK_CHANNEL_CENTER:  return "Center back";    case LFE_CHANNEL:          return "LFE";    case UNKNOWN_CHANNEL:      return "Unknown";    default: return "";    }    return "";}void print_channel_info(faacDecFrameInfo *frameInfo){    /* print some channel info */    int i;    long channelMask = aacChannelConfig2wavexChannelMask(frameInfo);    INFO_PRINTF((M_TEXT("  ---------------------\n")));    if (frameInfo->num_lfe_channels > 0)    {        INFO_PRINTF((M_TEXT(" | Config: %2d.%d Ch     |"), frameInfo->channels-frameInfo->num_lfe_channels, frameInfo->num_lfe_channels));    } else {        INFO_PRINTF((M_TEXT(" | Config: %2d Ch       |"), frameInfo->channels));    }    if (channelMask)        INFO_PRINTF((M_TEXT(" WARNING: channels are reordered according to\n")));    else        INFO_PRINTF((M_TEXT("\n")));    INFO_PRINTF((M_TEXT("  ---------------------")));    if (channelMask)        INFO_PRINTF((M_TEXT("  MS defaults defined in WAVE_FORMAT_EXTENSIBLE\n")));    else        INFO_PRINTF((M_TEXT("\n")));    INFO_PRINTF((M_TEXT(" | Ch |    Position    |\n")));    INFO_PRINTF((M_TEXT("  ---------------------\n")));    for (i = 0; i < frameInfo->channels; i++)    {        INFO_PRINTF((M_TEXT(" | %.2d | %-14s |\n"), i, position2string((int)frameInfo->channel_position[i])));    }    INFO_PRINTF((M_TEXT("  ---------------------\n")));    INFO_PRINTF((M_TEXT("\n")));}/* return the number of input bytes used */static long save_samplerate;static unsigned char save_channels;static unsigned char demux_stipulated_channels;static int demux_stipulated_samplerate = 0;#ifndef SBR_DEC  static int non_SBR_upsample;  static int non_SBR_ups_save[4];#endifint aacdecode(audiodecChangeInfo *ci, unsigned char **p_outbuf, int *out_size, unsigned char *input_buf, int inbuf_size, unsigned int stream_position){  int def_srate = 0; /* might want to use this later to force the sampling rate */  int bytes_read = 0;  int track = 0;  unsigned int frame_length;  unsigned char *buffer;  unsigned int buffer_size;  cb_stream_position = stream_position;  cb_stream_size = inbuf_size;  cb_stream_buffer = input_buf;  cb_stream_used = 0;    // {  //   static int frame = 0;  //   printf("Frame %d\n", frame);  //   frame++;  // }  DPRINTF((M_TEXT("inputinputinputinputinputinput %02x %02x %02x %02x %02x %02x %02x %02x  %02x %02x %02x %02x %02x %02x %02x %02x\n"), input_buf[0], input_buf[1], input_buf[2], input_buf[3], input_buf[4], input_buf[5], input_buf[6], input_buf[7], input_buf[8], input_buf[9], input_buf[10], input_buf[11], input_buf[12], input_buf[13], input_buf[14], input_buf[15]));  /* gobble up the ID3 tag or other tag as needed */  if (gobble_amount)  {    if (gobble_amount > inbuf_size)    {        DPRINTF((M_TEXT("TAG: still gobbling %d\n"), gobble_amount));        gobble_amount -= inbuf_size;        DPRINTF((M_TEXT("gobble left %d\n"), gobble_amount));       *out_size = 0;       return inbuf_size; /* means we gobbled inbuf_size this time, and we need to gobble more */    }    else    {      *out_size = 0;      tagsize = gobble_amount;      gobble_amount = 0;      return tagsize; /* done gobbling */    }  }  DPRINTF((M_TEXT("check for header, frame %d\n"), frame_number));  /* check for header */  if (frame_number == 0)  {    mp4file = 0;    demux_stipulated_channels = 0;    demux_stipulated_samplerate = 0;    /* This is our own interface for parsing with the demuxer.       First four bytes:  'faac'       Next byte:         object type       Next byte:         channels       Next int32:        sampling rate    */    if (input_buf[0] == 'f' && input_buf[1] == 'a' && input_buf[2] == 'a' && input_buf[3] == 'c')    {      /*           bits      meaning           5         objectTypeIndex           4         samplingFrequencyIndex           4         channelsConfiguration         if objectTypeIndex == 5   SBR           4         samplingFrequencyIndex extension           if samplingFrequencyIndex == 15             24        samplingFrequency             5         objectTypeIndex             11        syncExtensionType             if syncExtensionType == 2b7               5         objectTypeIndex      */      int samplerate;      unsigned int samplerate_code;      unsigned int object_type = input_buf[4];      unsigned int demux_chans = input_buf[5];      unsigned short obj;      const int sample_rates[] =      {        96000, 88200, 64000, 48000, 44100, 32000,        24000, 22050, 16000, 12000, 11025, 8000      };      hDecoder = faacDecOpen();      INIT_PRINTF((M_TEXT("Special FAAC\n")));      samplerate = input_buf[6];      samplerate |= ((unsigned int)input_buf[7]) <<  8;      samplerate |= ((unsigned int)input_buf[8]) << 16;      samplerate |= ((unsigned int)input_buf[9]) << 24;      demux_stipulated_samplerate = samplerate;      for (samplerate_code = 0; samplerate_code < 12; samplerate_code++)      {        if (sample_rates[samplerate_code] == samplerate)

⌨️ 快捷键说明

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