00001 #include <stdint.h>
00002 #include <string.h>
00003
00004 #include "faac.h"
00005
00006
00007
00008 #undef MAIN
00009 #undef SSR
00010 #undef LTP
00011
00012
00013 #include <faad.h>
00014 #include "funcprotos.h"
00015 #include "quicktime.h"
00016
00017
00018
00019 #define OUTPUT_ALLOCATION 0x100000
00020 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
00021
00022
00023 typedef struct
00024 {
00025
00026 faacDecHandle decoder_handle;
00027 faacDecFrameInfo frame_info;
00028 faacDecConfigurationPtr decoder_config;
00029 int decoder_initialized;
00030
00031
00032 faacEncHandle encoder_handle;
00033 faacEncConfigurationPtr encoder_params;
00034
00035 int frame_size;
00036 int max_frame_bytes;
00037
00038 float *input_buffer;
00039
00040 int input_size;
00041
00042 int input_allocated;
00043 unsigned char *compressed_buffer;
00044 int bitrate;
00045 int quantizer_quality;
00046 int encoder_initialized;
00047 } quicktime_mp4a_codec_t;
00048
00049
00050
00051
00052
00053
00054 static int delete_codec(quicktime_audio_map_t *atrack)
00055 {
00056 quicktime_mp4a_codec_t *codec =
00057 ((quicktime_codec_t*)atrack->codec)->priv;
00058
00059 if(codec->decoder_initialized)
00060 {
00061 faacDecClose(codec->decoder_handle);
00062 }
00063
00064 if(codec->encoder_initialized)
00065 {
00066 faacEncClose(codec->encoder_handle);
00067 if(codec->compressed_buffer) free(codec->compressed_buffer);
00068 if(codec->input_buffer) free(codec->input_buffer);
00069 }
00070
00071 free(codec);
00072 }
00073
00074 static int decode(quicktime_t *file,
00075 int16_t *output_i,
00076 float *output_f,
00077 long samples,
00078 int track,
00079 int channel)
00080 {
00081 quicktime_audio_map_t *track_map = &(file->atracks[track]);
00082 quicktime_trak_t *trak = track_map->track;
00083 quicktime_mp4a_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
00084 int64_t current_position = track_map->current_position;
00085 int64_t end_position = current_position + samples;
00086 quicktime_vbr_t *vbr = &track_map->vbr;
00087
00088
00089
00090 if(!codec->decoder_initialized)
00091 {
00092 uint32_t samplerate = trak->mdia.minf.stbl.stsd.table[0].sample_rate;
00093
00094 unsigned char channels = track_map->channels;
00095 quicktime_init_vbr(vbr, channels);
00096 codec->decoder_handle = faacDecOpen();
00097 codec->decoder_config = faacDecGetCurrentConfiguration(codec->decoder_handle);
00098 codec->decoder_config->outputFormat = FAAD_FMT_FLOAT;
00099
00100
00101
00102 faacDecSetConfiguration(codec->decoder_handle, codec->decoder_config);
00103
00104 quicktime_align_vbr(track_map, samples);
00105 quicktime_read_vbr(file, track_map);
00106 if(faacDecInit(codec->decoder_handle,
00107 quicktime_vbr_input(vbr),
00108 quicktime_vbr_input_size(vbr),
00109 &samplerate,
00110 &channels) < 0)
00111 {
00112 return 1;
00113 }
00114
00115 codec->decoder_initialized = 1;
00116 }
00117
00118 if(quicktime_align_vbr(track_map,
00119 samples))
00120 {
00121 return 1;
00122 }
00123 else
00124 {
00125
00126 while(quicktime_vbr_end(vbr) < end_position)
00127 {
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 if(quicktime_read_vbr(file, track_map)) break;
00138
00139 bzero(&codec->frame_info, sizeof(faacDecFrameInfo));
00140 float *sample_buffer = faacDecDecode(codec->decoder_handle,
00141 &codec->frame_info,
00142 quicktime_vbr_input(vbr),
00143 quicktime_vbr_input_size(vbr));
00144
00145 if (codec->frame_info.error > 0)
00146 {
00147
00148
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 quicktime_shift_vbr(track_map, quicktime_vbr_input_size(vbr));
00177 quicktime_store_vbr_float(track_map,
00178 sample_buffer,
00179 codec->frame_info.samples / track_map->channels);
00180 }
00181
00182
00183
00184 if(output_i)
00185 quicktime_copy_vbr_int16(vbr,
00186 current_position,
00187 samples,
00188 output_i,
00189 channel);
00190 else
00191 if(output_f)
00192 quicktime_copy_vbr_float(vbr,
00193 current_position,
00194 samples,
00195 output_f,
00196 channel);
00197 }
00198 return 0;
00199 }
00200
00201
00202 static int encode(quicktime_t *file,
00203 int16_t **input_i,
00204 float **input_f,
00205 int track,
00206 long samples)
00207 {
00208 int result = 0;
00209 quicktime_audio_map_t *track_map = &(file->atracks[track]);
00210 quicktime_trak_t *trak = track_map->track;
00211 quicktime_mp4a_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
00212 int channels = quicktime_track_channels(file, track);
00213 int i, j, k;
00214
00215 if(!codec->encoder_initialized)
00216 {
00217 unsigned long input_samples;
00218 unsigned long max_output_bytes;
00219 int sample_rate = quicktime_sample_rate(file, track);
00220 codec->encoder_initialized = 1;
00221 codec->encoder_handle = faacEncOpen(quicktime_sample_rate(file, track),
00222 channels,
00223 &input_samples,
00224 &max_output_bytes);
00225
00226 codec->frame_size = input_samples / channels;
00227 codec->max_frame_bytes = max_output_bytes;
00228 codec->compressed_buffer = calloc(1, max_output_bytes);
00229 codec->encoder_params = faacEncGetCurrentConfiguration(codec->encoder_handle);
00230
00231
00232 codec->encoder_params->aacObjectType = LOW;
00233 codec->encoder_params->mpegVersion = MPEG4;
00234 codec->encoder_params->useTns = 0;
00235 codec->encoder_params->allowMidside = 1;
00236 codec->encoder_params->inputFormat = FAAC_INPUT_FLOAT;
00237 codec->encoder_params->outputFormat = 0;
00238 codec->encoder_params->bitRate = codec->bitrate / channels;
00239 codec->encoder_params->quantqual = codec->quantizer_quality;
00240 codec->encoder_params->bandWidth = sample_rate / 2;
00241
00242 if(!faacEncSetConfiguration(codec->encoder_handle, codec->encoder_params))
00243 {
00244 fprintf(stderr, "encode: unsupported MPEG-4 Audio configuration!@#!@#\n");
00245 return 1;
00246 }
00247
00248
00249
00250
00251 unsigned char *buffer;
00252 unsigned long buffer_size;
00253 faacEncGetDecoderSpecificInfo(codec->encoder_handle,
00254 &buffer,
00255 &buffer_size);
00256 quicktime_set_mpeg4_header(&trak->mdia.minf.stbl.stsd.table[0],
00257 buffer,
00258 buffer_size);
00259 trak->mdia.minf.stbl.stsd.table[0].version = 1;
00260
00261 trak->mdia.minf.stbl.stsd.table[0].compression_id = 0xfffe;
00262 }
00263
00264
00265
00266 int new_allocation = codec->input_size + samples;
00267 if(new_allocation > codec->input_allocated)
00268 {
00269 codec->input_buffer = realloc(codec->input_buffer,
00270 new_allocation *
00271 sizeof(float) *
00272 channels);
00273 codec->input_allocated = new_allocation;
00274 }
00275
00276 float *output = (float*)codec->input_buffer + codec->input_size * channels;
00277 if(input_f)
00278 {
00279 for(i = 0; i < samples; i++)
00280 {
00281 for(j = 0; j < channels; j++)
00282 {
00283 *output++ = input_f[j][i] * 32767;
00284 }
00285 }
00286 }
00287 else
00288 if(input_i)
00289 {
00290 for(i = 0; i < samples; i++)
00291 {
00292 for(j = 0; j < channels; j++)
00293 {
00294 *output++ = (float)input_i[j][i];
00295 }
00296 }
00297 }
00298
00299 codec->input_size += samples;
00300
00301
00302 for(i = 0; i + codec->frame_size < codec->input_size; i += codec->frame_size)
00303 {
00304 int bytes = faacEncEncode(codec->encoder_handle,
00305 (int32_t*)(codec->input_buffer + i * channels),
00306 codec->frame_size * channels,
00307 codec->compressed_buffer,
00308 codec->max_frame_bytes);
00309
00310
00311
00312
00313
00314
00315
00316 if(bytes)
00317 {
00318 quicktime_write_vbr_frame(file,
00319 track,
00320 codec->compressed_buffer,
00321 bytes,
00322 codec->frame_size);
00323 }
00324 }
00325
00326 for(j = i * channels, k = 0; j < codec->input_size * channels; j++, k++)
00327 {
00328 codec->input_buffer[k] = codec->input_buffer[j];
00329 }
00330 codec->input_size -= i;
00331
00332 return result;
00333 }
00334
00335
00336
00337 static void flush(quicktime_t *file, int track)
00338 {
00339 quicktime_audio_map_t *track_map = &(file->atracks[track]);
00340 quicktime_trak_t *trak = track_map->track;
00341 quicktime_mp4a_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
00342 int channels = quicktime_track_channels(file, track);
00343 int i;
00344 if(codec->encoder_initialized)
00345 {
00346 for(i = 0;
00347 i < codec->input_size &&
00348 i + codec->frame_size < codec->input_allocated;
00349 i += codec->frame_size)
00350 {
00351 int bytes = faacEncEncode(codec->encoder_handle,
00352 (int32_t*)(codec->input_buffer + i * channels),
00353 codec->frame_size * channels,
00354 codec->compressed_buffer,
00355 codec->max_frame_bytes);
00356
00357
00358
00359
00360
00361
00362
00363
00364 if(bytes)
00365 {
00366 quicktime_write_vbr_frame(file,
00367 track,
00368 codec->compressed_buffer,
00369 bytes,
00370 codec->frame_size);
00371 }
00372 }
00373 }
00374 }
00375
00376
00377 static int set_parameter(quicktime_t *file,
00378 int track,
00379 char *key,
00380 void *value)
00381 {
00382 quicktime_audio_map_t *atrack = &(file->atracks[track]);
00383 char *compressor = quicktime_compressor(atrack->track);
00384
00385 if(quicktime_match_32(compressor, QUICKTIME_MP4A))
00386 {
00387 quicktime_mp4a_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
00388 if(!strcasecmp(key, "mp4a_bitrate"))
00389 {
00390 codec->bitrate = *(int*)value;
00391 }
00392 else
00393 if(!strcasecmp(key, "mp4a_quantqual"))
00394 {
00395 codec->quantizer_quality = *(int*)value;
00396 }
00397 }
00398 return 0;
00399 }
00400
00401
00402
00403 void quicktime_init_codec_mp4a(quicktime_audio_map_t *atrack)
00404 {
00405 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
00406 quicktime_mp4a_codec_t *codec;
00407 codec_base->priv = calloc(1, sizeof(quicktime_mp4a_codec_t));
00408 codec_base->delete_acodec = delete_codec;
00409 codec_base->decode_audio = decode;
00410 codec_base->encode_audio = encode;
00411 codec_base->set_parameter = set_parameter;
00412 codec_base->flush = flush;
00413 codec_base->fourcc = "mp4a";
00414 codec_base->title = "MPEG4 audio";
00415 codec_base->desc = "Audio section of MPEG4 standard";
00416
00417 codec = (quicktime_mp4a_codec_t*)codec_base->priv;
00418
00419 codec->bitrate = 256000;
00420 codec->quantizer_quality = 100;
00421 }
00422
00423
00424
00425