"Fossies" - the Fresh Open Source Software Archive

Member "quicktime4linux-2.3/thirdparty/faad2-2.0/common/faad/aacinfo.c" (31 May 2008, 9969 Bytes) of package /linux/privat/old/quicktime4linux-2.3-src.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
    3 ** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
    4 **  
    5 ** This program is free software; you can redistribute it and/or modify
    6 ** it under the terms of the GNU General Public License as published by
    7 ** the Free Software Foundation; either version 2 of the License, or
    8 ** (at your option) any later version.
    9 ** 
   10 ** This program is distributed in the hope that it will be useful,
   11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
   12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13 ** GNU General Public License for more details.
   14 ** 
   15 ** You should have received a copy of the GNU General Public License
   16 ** along with this program; if not, write to the Free Software 
   17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   18 **
   19 ** Any non-GPL usage of this software or parts of this software is strictly
   20 ** forbidden.
   21 **
   22 ** Commercial non-GPL licensing of this software is possible.
   23 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
   24 **
   25 ** $Id: aacinfo.c,v 1.4 2003/07/29 08:20:11 menno Exp $
   26 **/
   27 
   28 #ifdef _WIN32
   29 #define WIN32_LEAN_AND_MEAN
   30 #include <windows.h>
   31 #endif
   32 #include <malloc.h>
   33 #include "filestream.h"
   34 #include "aacinfo.h"
   35 
   36 #define ADIF_MAX_SIZE 30 /* Should be enough */
   37 #define ADTS_MAX_SIZE 10 /* Should be enough */
   38 
   39 static int sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000};
   40 
   41 static int read_ADIF_header(FILE_STREAM *file, faadAACInfo *info)
   42 {
   43     int bitstream;
   44     unsigned char buffer[ADIF_MAX_SIZE];
   45     int skip_size = 0;
   46     int sf_idx;
   47 
   48     /* Get ADIF header data */
   49     info->headertype = 1;
   50 
   51     if(read_buffer_filestream(file, buffer, ADIF_MAX_SIZE) < 0)
   52         return -1;
   53 
   54     /* copyright string */
   55     if(buffer[0] & 0x80)
   56         skip_size += 9; /* skip 9 bytes */
   57 
   58     bitstream = buffer[0 + skip_size] & 0x10;
   59     info->bitrate = ((unsigned int)(buffer[0 + skip_size] & 0x0F)<<19)|
   60         ((unsigned int)buffer[1 + skip_size]<<11)|
   61         ((unsigned int)buffer[2 + skip_size]<<3)|
   62         ((unsigned int)buffer[3 + skip_size] & 0xE0);
   63 
   64     if (bitstream == 0)
   65     {
   66         info->object_type =  ((buffer[6 + skip_size]&0x01)<<1)|((buffer[7 + skip_size]&0x80)>>7);
   67         sf_idx = (buffer[7 + skip_size]&0x78)>>3;
   68     } else {
   69         info->object_type = (buffer[4 + skip_size] & 0x18)>>3;
   70         sf_idx = ((buffer[4 + skip_size] & 0x07)<<1)|((buffer[5 + skip_size] & 0x80)>>7);
   71     }
   72     info->sampling_rate = sample_rates[sf_idx];
   73 
   74     return 0;
   75 }
   76 
   77 static int read_ADTS_header(FILE_STREAM *file, faadAACInfo *info,
   78                             unsigned long **seek_table, int *seek_table_len,
   79                             int tagsize, int no_seek_table)
   80 {
   81     /* Get ADTS header data */
   82     unsigned char buffer[ADTS_MAX_SIZE];
   83     int frames, framesinsec=0, t_framelength = 0, frame_length, sr_idx, ID;
   84     int second = 0, pos;
   85     int i;
   86     float frames_per_sec = 0;
   87     unsigned long bytes;
   88     unsigned long *tmp_seek_table = NULL;
   89 
   90     info->headertype = 2;
   91 
   92     /* Read all frames to ensure correct time and bitrate */
   93     for(frames=0; /* */; frames++, framesinsec++)
   94     {
   95         /* If streaming, only go until we hit 5 seconds worth */
   96          if(file->http)
   97          {
   98              if(frames >= 43 * 5)
   99              {
  100                 break;
  101              }
  102          }
  103 
  104         pos = tell_filestream(file);
  105 
  106         /* 12 bit SYNCWORD */
  107         bytes = read_buffer_filestream(file, buffer, ADTS_MAX_SIZE);
  108 
  109         if(bytes != ADTS_MAX_SIZE)
  110         {
  111             /* Bail out if no syncword found */
  112             break;
  113         }
  114 
  115         /* check syncword */
  116         if (!((buffer[0] == 0xFF)&&((buffer[1] & 0xF6) == 0xF0)))
  117             break;
  118 
  119         if(!frames)
  120         {
  121             /* fixed ADTS header is the same for every frame, so we read it only once */
  122             /* Syncword found, proceed to read in the fixed ADTS header */
  123             ID = buffer[1] & 0x08;
  124             info->object_type = (buffer[2]&0xC0)>>6;
  125             sr_idx = (buffer[2]&0x3C)>>2;
  126             info->channels = ((buffer[2]&0x01)<<2)|((buffer[3]&0xC0)>>6);
  127 
  128             frames_per_sec = sample_rates[sr_idx] / 1024.f;
  129         }
  130 
  131         /* ...and the variable ADTS header */
  132         if (ID == 0) {
  133             info->version = 4;
  134         } else { /* MPEG-2 */
  135             info->version = 2;
  136         }
  137         frame_length = ((((unsigned int)buffer[3] & 0x3)) << 11)
  138             | (((unsigned int)buffer[4]) << 3) | (buffer[5] >> 5);
  139 
  140         t_framelength += frame_length;
  141 
  142         if(!file->http)
  143         {
  144             if(framesinsec == 43)
  145                 framesinsec = 0;
  146 
  147             if(framesinsec == 0 && seek_table_len)
  148             {
  149                 tmp_seek_table = (unsigned long *) realloc(tmp_seek_table, (second + 1) * sizeof(unsigned long));
  150                 tmp_seek_table[second] = pos;
  151             }
  152             if(framesinsec == 0)
  153                 second++;
  154         }
  155 
  156         /* NOTE: While simply skipping ahead by reading may seem to be more work than seeking,
  157             it is actually much faster, and keeps compatibility with streaming */
  158         for(i=0; i < frame_length - ADTS_MAX_SIZE; i++)
  159         {
  160             if(read_byte_filestream(file) < 0)
  161                 break;
  162         }
  163     }
  164 
  165     if(seek_table_len)
  166     {
  167         *seek_table_len = second;
  168         *seek_table = tmp_seek_table;
  169     }
  170 
  171     info->sampling_rate = sample_rates[sr_idx];
  172     info->bitrate = (int)(((t_framelength / frames) * (info->sampling_rate/1024.0)) +0.5)*8;
  173 
  174     if(file->http)
  175     {
  176         /* Since we only use 5 seconds of aac data to get a rough bitrate, we must use a different
  177            method of calculating the overall length */
  178         if(filelength_filestream(file))
  179         {
  180             info->length = (int)((filelength_filestream(file)/(((info->bitrate*8)/1024)*16))*1000);
  181         }
  182         else
  183         {
  184             /* Since the server didnt tell us how long the file is, 
  185                we have no way of determining length */
  186             info->length = 0;
  187         }
  188     }
  189     else
  190     {
  191         info->length = (int)((float)(frames/frames_per_sec))*1000;
  192     }
  193 
  194     return 0;
  195 }
  196 
  197 int get_AAC_format(char *filename, faadAACInfo *info,
  198                    unsigned long **seek_table, int *seek_table_len,
  199                    int no_seek_table)
  200 {
  201     unsigned long tagsize;
  202     FILE_STREAM *file;
  203     char buffer[10];
  204     unsigned long file_len;
  205     unsigned char adxx_id[5];
  206     unsigned long tmp;
  207 
  208     memset(info, 0, sizeof(faadAACInfo));
  209 
  210     file = open_filestream(filename);
  211 
  212     if(file == NULL)
  213         return -1;
  214 
  215     file_len = filelength_filestream(file);
  216 
  217     /* Skip the tag, if it's there */
  218     tmp = read_buffer_filestream(file, buffer, 10);
  219 
  220     if (StringComp(buffer, "ID3", 3) == 0)
  221     {
  222         unsigned int i;
  223 
  224         /* high bit is not used */
  225         tagsize = (buffer[6] << 21) | (buffer[7] << 14) |
  226             (buffer[8] <<  7) | (buffer[9] <<  0);
  227 
  228         for(i=0; i < tagsize; i++)
  229             if(read_byte_filestream(file) < 0)
  230                 return -1;
  231 
  232         tagsize += 10;
  233     }
  234     else
  235     {
  236         tagsize = 0;
  237 
  238         /* Simple hack to reset to the beginning */
  239         file->buffer_offset = 0;
  240         file->file_offset = 0;
  241     }
  242 
  243     if(file_len)
  244         file_len -= tagsize;
  245 
  246     tmp = read_buffer_filestream(file, adxx_id, 2);
  247     //seek_filestream(file, tagsize, FILE_BEGIN);
  248 
  249     adxx_id[5-1] = 0;
  250     info->length = 0;
  251 
  252     /* Determine the header type of the file, check the first two bytes */
  253     if(StringComp(adxx_id, "AD", 2) == 0)
  254     {
  255         /* We think its an ADIF header, but check the rest just to make sure */
  256         tmp = read_buffer_filestream(file, adxx_id + 2, 2);
  257         
  258         if(StringComp(adxx_id, "ADIF", 4) == 0)
  259         {
  260             read_ADIF_header(file, info);
  261         }
  262     }
  263     else
  264     {
  265         /* No ADIF, check for ADTS header */
  266         if ((adxx_id[0] == 0xFF)&&((adxx_id[1] & 0xF6) == 0xF0))
  267         {
  268             /* ADTS  header located */
  269             /* Since this routine must work for streams, we can't use the seek function to go backwards, thus 
  270                we have to use a quick hack as seen below to go back where we need to. */
  271             
  272             if(file->buffer_offset >= 2)
  273             {
  274                 // simple seeking hack, though not really safe, the probability of it causing a problem is low.
  275                 file->buffer_offset -= 2;
  276                 file->file_offset -= 2;
  277             }
  278 
  279             read_ADTS_header(file, info, seek_table, seek_table_len, tagsize,
  280                 no_seek_table);
  281         }
  282         else
  283         {
  284             /* Unknown/headerless AAC file, assume format: */
  285             info->version = 2;
  286             info->bitrate = 128000;
  287             info->sampling_rate = 44100;
  288             info->channels = 2;
  289             info->headertype = 0;
  290             info->object_type = 1;
  291         }
  292     }
  293 
  294     close_filestream(file);
  295 
  296     return 0;
  297 }
  298 
  299 int StringComp(char const *str1, char const *str2, unsigned long len)
  300 {
  301     signed int c1 = 0, c2 = 0;
  302 
  303     while (len--) {
  304         c1 = *str1++;
  305         c2 = *str2++;
  306 
  307         if (c1 == 0 || c1 != c2)
  308             break;
  309     }
  310 
  311     return c1 - c2;
  312 }
  313 
  314 #ifdef TEST
  315 /* Program to test aacinfo functionality */
  316 
  317 #include <stdio.h>
  318 
  319 void main(int argc, char *argv[])
  320 {
  321     faadAACInfo info;
  322     unsigned long *seek_table = NULL;
  323     int seek_table_len = 0;
  324     char *header, *object;
  325 
  326     if (argc < 2)
  327     {
  328         fprintf(stderr, "USAGE: aacinfo aacfile.aac\n");
  329         return;
  330     }
  331 
  332     get_AAC_format(argv[1], &info, &seek_table, &seek_table_len, 0);
  333 
  334     fprintf(stdout, "MPEG version: %d\n", info.version);
  335     fprintf(stdout, "channels: %d\n", info.channels);
  336     fprintf(stdout, "sampling_rate: %d\n", info.sampling_rate);
  337     fprintf(stdout, "bitrate: %d\n", info.bitrate);
  338     fprintf(stdout, "length: %.3f\n", (float)info.length/1000.0);
  339 
  340     switch (info.object_type)
  341     {
  342     case 0:
  343         object = "MAIN";
  344         break;
  345     case 1:
  346         object = "LC";
  347         break;
  348     case 2:
  349         object = "SSR";
  350         break;
  351     case 3:
  352         object = "LTP";
  353         break;
  354     }
  355     fprintf(stdout, "object_type: %s\n", object);
  356 
  357     switch (info.headertype)
  358     {
  359     case 0:
  360         header = "RAW";
  361         break;
  362     case 1:
  363         header = "ADIF";
  364         break;
  365     case 2:
  366         header = "ADTS";
  367         break;
  368     }
  369     fprintf(stdout, "headertype: %s\n", header);
  370 }
  371 
  372 #endif