"Fossies" - the Fresh Open Source Software Archive

Member "quicktime4linux-2.3/mp4a.c" (9 Jan 2007, 10488 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 #include <stdint.h>
    2 #include <string.h>
    3 
    4 #include "faac.h"
    5 
    6 // The FAAD includes redefine the same symbols as if they're not intended to
    7 // be used by the same program.
    8 #undef MAIN
    9 #undef SSR
   10 #undef LTP
   11 
   12 
   13 #include "faad.h"
   14 #include "funcprotos.h"
   15 #include "quicktime.h"
   16 
   17 
   18 // Attempts to read more samples than this will crash
   19 #define OUTPUT_ALLOCATION 0x100000
   20 #define CLAMP(x, y, z) ((x) = ((x) <  (y) ? (y) : ((x) > (z) ? (z) : (x))))
   21 
   22 
   23 typedef struct
   24 {
   25 // Decoder objects
   26     faacDecHandle decoder_handle;
   27     faacDecFrameInfo frame_info;
   28     faacDecConfigurationPtr decoder_config;
   29     int decoder_initialized;
   30 
   31 
   32     faacEncHandle encoder_handle;
   33     faacEncConfigurationPtr encoder_params;
   34 // Number of frames
   35     int frame_size;
   36     int max_frame_bytes;
   37 // Interleaved samples
   38     float *input_buffer;
   39 // Number of frames
   40     int input_size;
   41 // Number of samples allocated
   42     int input_allocated;
   43     unsigned char *compressed_buffer;
   44 
   45 // Encoding objects
   46     int bitrate;
   47     int quantizer_quality;
   48     int encoder_initialized;
   49 } quicktime_mp4a_codec_t;
   50 
   51 
   52 
   53 
   54 
   55 
   56 static int delete_codec(quicktime_audio_map_t *atrack)
   57 {
   58     quicktime_mp4a_codec_t *codec = 
   59         ((quicktime_codec_t*)atrack->codec)->priv;
   60 
   61     if(codec->decoder_initialized)
   62     {
   63         faacDecClose(codec->decoder_handle);
   64     }
   65 
   66     if(codec->encoder_initialized)
   67     {
   68         faacEncClose(codec->encoder_handle);
   69         if(codec->compressed_buffer) free(codec->compressed_buffer);
   70         if(codec->input_buffer) free(codec->input_buffer);
   71     }
   72 
   73     free(codec);
   74 }
   75 
   76 static int decode(quicktime_t *file, 
   77                     int16_t *output_i, 
   78                     float *output_f, 
   79                     long samples, 
   80                     int track, 
   81                     int channel)
   82 {
   83     quicktime_audio_map_t *track_map = &(file->atracks[track]);
   84     quicktime_trak_t *trak = track_map->track;
   85     quicktime_mp4a_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
   86     int64_t current_position = track_map->current_position;
   87     int64_t end_position = current_position + samples;
   88     quicktime_vbr_t *vbr = &track_map->vbr;
   89 
   90 
   91 // Initialize decoder
   92     if(!codec->decoder_initialized)
   93     {
   94         uint32_t samplerate = trak->mdia.minf.stbl.stsd.table[0].sample_rate;
   95 // FAAD needs unsigned char here
   96         unsigned char channels = track_map->channels;
   97         quicktime_init_vbr(vbr, channels);
   98         codec->decoder_handle = faacDecOpen();
   99         codec->decoder_config = faacDecGetCurrentConfiguration(codec->decoder_handle);
  100         codec->decoder_config->outputFormat = FAAD_FMT_FLOAT;
  101 //      codec->decoder_config->defSampleRate = 
  102 //          trak->mdia.minf.stbl.stsd.table[0].sample_rate;
  103 
  104         faacDecSetConfiguration(codec->decoder_handle, codec->decoder_config);
  105         
  106         quicktime_align_vbr(track_map, samples);
  107         quicktime_read_vbr(file, track_map);
  108         if(faacDecInit(codec->decoder_handle,
  109             quicktime_vbr_input(vbr), 
  110             quicktime_vbr_input_size(vbr),
  111             &samplerate,
  112             &channels) < 0)
  113         {
  114             return 1;
  115         }
  116 //printf("decode %d %d\n", samplerate, channels);
  117         codec->decoder_initialized = 1;
  118     }
  119 
  120     if(quicktime_align_vbr(track_map, 
  121         samples))
  122     {
  123         return 1;
  124     }
  125     else
  126     {
  127 // Decode until buffer is full
  128         while(quicktime_vbr_end(vbr) < end_position)
  129         {
  130 // Fill until min buffer size reached or EOF
  131 /*
  132  *          while(quicktime_vbr_input_size(vbr) <
  133  *              FAAD_MIN_STREAMSIZE * track_map->channels)
  134  *          {
  135  *              if(quicktime_read_vbr(file, track_map)) break;
  136  *          }
  137  */
  138 
  139             if(quicktime_read_vbr(file, track_map)) break;
  140 
  141             bzero(&codec->frame_info, sizeof(faacDecFrameInfo));
  142             float *sample_buffer = faacDecDecode(codec->decoder_handle, 
  143                 &codec->frame_info,
  144                 quicktime_vbr_input(vbr), 
  145                 quicktime_vbr_input_size(vbr));
  146 
  147             if (codec->frame_info.error > 0)
  148             {
  149 //              printf("decode mp4a: %s\n",
  150 //                  faacDecGetErrorMessage(codec->frame_info.error));
  151             }
  152 
  153 /*
  154  * printf("decode 1 %d %d %d\n", 
  155  * quicktime_vbr_input_size(vbr), 
  156  * codec->frame_info.bytesconsumed,
  157  * codec->frame_info.samples);
  158  * 
  159  * static FILE *test = 0;
  160  * if(!test) test = fopen("/tmp/test.aac", "w");
  161  * fwrite(quicktime_vbr_input(vbr), quicktime_vbr_input_size(vbr), 1, test);
  162  */
  163 
  164 
  165 /*
  166  * static FILE *test = 0;
  167  * if(!test) test = fopen("/hmov/test.pcm", "w");
  168  * int i;
  169  * for(i = 0; i < codec->frame_info.samples; i++)
  170  * {
  171  * int16_t sample = (int)(sample_buffer[i] * 32767);
  172  * fwrite(&sample, 2, 1, test);
  173  * }
  174  * fflush(test);
  175  */
  176 
  177 //              quicktime_shift_vbr(track_map, codec->frame_info.bytesconsumed);
  178                 quicktime_shift_vbr(track_map, quicktime_vbr_input_size(vbr));
  179                 quicktime_store_vbr_float(track_map,
  180                     sample_buffer,
  181                     codec->frame_info.samples / track_map->channels);
  182         }
  183 
  184 
  185 // Transfer from buffer to output
  186         if(output_i)
  187             quicktime_copy_vbr_int16(vbr, 
  188                 current_position, 
  189                 samples, 
  190                 output_i, 
  191                 channel);
  192         else
  193         if(output_f)
  194             quicktime_copy_vbr_float(vbr, 
  195                 current_position, 
  196                 samples,
  197                 output_f, 
  198                 channel);
  199     }
  200     return 0;
  201 }
  202 
  203 
  204 static int encode(quicktime_t *file, 
  205     int16_t **input_i, 
  206     float **input_f, 
  207     int track, 
  208     long samples)
  209 {
  210     int result = 0;
  211     quicktime_audio_map_t *track_map = &(file->atracks[track]);
  212     quicktime_trak_t *trak = track_map->track;
  213     quicktime_mp4a_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
  214     int channels = quicktime_track_channels(file, track);
  215     int i, j, k;
  216 
  217     if(!codec->encoder_initialized)
  218     {
  219         unsigned long input_samples;
  220         unsigned long max_output_bytes;
  221         int sample_rate = quicktime_sample_rate(file, track);
  222         codec->encoder_initialized = 1;
  223         codec->encoder_handle = faacEncOpen(quicktime_sample_rate(file, track), 
  224             channels,
  225             &input_samples, 
  226             &max_output_bytes);
  227 
  228         codec->frame_size = input_samples / channels;
  229         codec->max_frame_bytes = max_output_bytes;
  230         codec->compressed_buffer = calloc(1, max_output_bytes);
  231         codec->encoder_params = faacEncGetCurrentConfiguration(codec->encoder_handle);
  232 
  233 // Parameters from ffmpeg
  234         codec->encoder_params->aacObjectType = LOW;
  235         codec->encoder_params->mpegVersion = MPEG4;
  236         codec->encoder_params->useTns = 0;
  237         codec->encoder_params->allowMidside = 1;
  238         codec->encoder_params->inputFormat = FAAC_INPUT_FLOAT;
  239         codec->encoder_params->outputFormat = 0;
  240         codec->encoder_params->bitRate = codec->bitrate / channels;
  241         codec->encoder_params->quantqual = codec->quantizer_quality;
  242         codec->encoder_params->bandWidth = sample_rate / 2;
  243 
  244         if(!faacEncSetConfiguration(codec->encoder_handle, codec->encoder_params))
  245         {
  246             fprintf(stderr, "encode: unsupported MPEG-4 Audio configuration!@#!@#\n");
  247             return 1;
  248         }
  249 
  250 
  251 
  252 // Create esds header
  253         unsigned char *buffer;
  254         unsigned long buffer_size;
  255         faacEncGetDecoderSpecificInfo(codec->encoder_handle, 
  256             &buffer,
  257             &buffer_size);
  258         quicktime_set_mpeg4_header(&trak->mdia.minf.stbl.stsd.table[0],
  259             buffer, 
  260             buffer_size);
  261         trak->mdia.minf.stbl.stsd.table[0].version = 1;
  262 // Quicktime player needs this.
  263         trak->mdia.minf.stbl.stsd.table[0].compression_id = 0xfffe;
  264     }
  265 
  266 
  267 // Stack new audio at end of old audio
  268     int new_allocation = codec->input_size + samples;
  269     if(new_allocation > codec->input_allocated)
  270     {
  271         codec->input_buffer = realloc(codec->input_buffer, 
  272             new_allocation * 
  273             sizeof(float) * 
  274             channels);
  275         codec->input_allocated = new_allocation;
  276     }
  277 
  278     float *output = (float*)codec->input_buffer + codec->input_size * channels;
  279     if(input_f)
  280     {
  281         for(i = 0; i < samples; i++)
  282         {
  283             for(j = 0; j < channels; j++)
  284             {
  285                 *output++ = input_f[j][i] * 32767;
  286             }
  287         }
  288     }
  289     else
  290     if(input_i)
  291     {
  292         for(i = 0; i < samples; i++)
  293         {
  294             for(j = 0; j < channels; j++)
  295             {
  296                 *output++ = (float)input_i[j][i];
  297             }
  298         }
  299     }
  300 
  301     codec->input_size += samples;
  302 
  303 
  304     for(i = 0; i + codec->frame_size < codec->input_size; i += codec->frame_size)
  305     {
  306         int bytes = faacEncEncode(codec->encoder_handle,
  307                 (int32_t*)(codec->input_buffer + i * channels),
  308                 codec->frame_size * channels,
  309                 codec->compressed_buffer,
  310                 codec->max_frame_bytes);
  311 /*
  312  * printf("encode 1 %lld %d %d\n", 
  313  * track_map->current_position,
  314  * codec->frame_size, 
  315  * bytes);
  316  */
  317 // Write out the packet
  318         if(bytes)
  319         {
  320             quicktime_write_vbr_frame(file, 
  321                 track,
  322                 codec->compressed_buffer,
  323                 bytes,
  324                 codec->frame_size);
  325         }
  326     }
  327 
  328     for(j = i * channels, k = 0; j < codec->input_size * channels; j++, k++)
  329     {
  330         codec->input_buffer[k] = codec->input_buffer[j];
  331     }
  332     codec->input_size -= i;  
  333 
  334     return result;
  335 }
  336 
  337 
  338 
  339 static void flush(quicktime_t *file, int track)
  340 {
  341     quicktime_audio_map_t *track_map = &(file->atracks[track]);
  342     quicktime_trak_t *trak = track_map->track;
  343     quicktime_mp4a_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
  344     int channels = quicktime_track_channels(file, track);
  345     int i;
  346     if(codec->encoder_initialized)
  347     {
  348         for(i = 0; 
  349             i < codec->input_size && 
  350                 i + codec->frame_size < codec->input_allocated; 
  351             i += codec->frame_size)
  352         {
  353             int bytes = faacEncEncode(codec->encoder_handle,
  354                     (int32_t*)(codec->input_buffer + i * channels),
  355                     codec->frame_size * channels,
  356                     codec->compressed_buffer,
  357                     codec->max_frame_bytes);
  358 
  359 /*
  360  * printf("flush 1 %d %d %d\n", 
  361  * codec->encoder_params->bitRate, 
  362  * bytes, 
  363  * codec->max_frame_bytes);
  364  */
  365 // Write out the packet
  366             if(bytes)
  367             {
  368                 quicktime_write_vbr_frame(file, 
  369                     track,
  370                     codec->compressed_buffer,
  371                     bytes,
  372                     codec->frame_size);
  373             }
  374         }
  375     }
  376 }
  377 
  378 
  379 static int set_parameter(quicktime_t *file, 
  380     int track, 
  381     char *key, 
  382     void *value)
  383 {
  384     quicktime_audio_map_t *atrack = &(file->atracks[track]);
  385     char *compressor = quicktime_compressor(atrack->track);
  386 
  387     if(quicktime_match_32(compressor, QUICKTIME_MP4A))
  388     {
  389         quicktime_mp4a_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
  390         if(!strcasecmp(key, "mp4a_bitrate"))
  391         {
  392             codec->bitrate = *(int*)value;
  393         }
  394         else
  395         if(!strcasecmp(key, "mp4a_quantqual"))
  396         {
  397             codec->quantizer_quality = *(int*)value;
  398         }
  399     }
  400     return 0;
  401 }
  402 
  403 
  404 
  405 void quicktime_init_codec_mp4a(quicktime_audio_map_t *atrack)
  406 {
  407     quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
  408     quicktime_mp4a_codec_t *codec;
  409     codec_base->priv = calloc(1, sizeof(quicktime_mp4a_codec_t));
  410     codec_base->delete_acodec = delete_codec;
  411     codec_base->decode_audio = decode;
  412     codec_base->encode_audio = encode;
  413     codec_base->set_parameter = set_parameter;
  414     codec_base->flush = flush;
  415     codec_base->fourcc = "mp4a";
  416     codec_base->title = "MPEG4 audio";
  417     codec_base->desc = "Audio section of MPEG4 standard";
  418 
  419     codec = (quicktime_mp4a_codec_t*)codec_base->priv;
  420 // Default encoding parameters here
  421     codec->bitrate = 256000;
  422     codec->quantizer_quality = 100;
  423 }
  424 
  425 
  426 
  427