6 // The FAAD includes redefine the same symbols as if they're not intended to
7 // be used by the same program.
13 #include "funcprotos.h"
15 #include "quicktime.h"
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))))
26 NeAACDecHandle decoder_handle;
27 NeAACDecFrameInfo frame_info;
28 NeAACDecConfigurationPtr decoder_config;
29 int decoder_initialized;
31 faacEncHandle encoder_handle;
32 faacEncConfigurationPtr encoder_params;
33 // Number of first sample in output relative to file
34 int64_t output_position;
38 // Interleaved samples
42 // Number of samples allocated
44 unsigned char *compressed_buffer;
48 int quantizer_quality;
49 int encoder_initialized;
50 } quicktime_mp4a_codec_t;
57 static void delete_codec(quicktime_audio_map_t *atrack)
59 quicktime_mp4a_codec_t *codec =
60 ((quicktime_codec_t*)atrack->codec)->priv;
62 if(codec->decoder_initialized)
64 NeAACDecClose(codec->decoder_handle);
67 if(codec->encoder_initialized)
69 faacEncClose(codec->encoder_handle);
70 if(codec->compressed_buffer) free(codec->compressed_buffer);
71 if(codec->input_buffer) free(codec->input_buffer);
77 static int decode(quicktime_t *file,
78 int16_t *output_i, float *output_f,
79 long samples, int track, int channel)
81 quicktime_audio_map_t *track_map = &(file->atracks[track]);
82 quicktime_trak_t *trak = track_map->track;
83 quicktime_mp4a_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
84 int64_t current_position = track_map->current_position;
85 int64_t end_position = current_position + samples;
86 quicktime_vbr_t *vbr = &track_map->vbr;
87 if( quicktime_limit_samples(samples) ) return 1;
90 if( !codec->decoder_initialized ) {
91 unsigned long samplerate = trak->mdia.minf.stbl.stsd.table[0].sample_rate;
92 // FAAD needs unsigned char here
93 uint8_t channels = track_map->channels;
94 quicktime_init_vbr(vbr, channels);
95 codec->decoder_handle = NeAACDecOpen();
96 codec->decoder_config = NeAACDecGetCurrentConfiguration(codec->decoder_handle);
97 codec->decoder_config->outputFormat = FAAD_FMT_FLOAT;
98 // codec->decoder_config->defSampleRate =
99 // trak->mdia.minf.stbl.stsd.table[0].sample_rate;
101 NeAACDecSetConfiguration(codec->decoder_handle, codec->decoder_config);
104 char *mp4_hdr = trak->mdia.minf.stbl.stsd.table[0].esds.mpeg4_header;
105 int hdr_len = trak->mdia.minf.stbl.stsd.table[0].esds.mpeg4_header_size;
106 if( !mp4_hdr || !hdr_len ) {
107 quicktime_seek_vbr(track_map, 0, 0);
108 quicktime_read_vbr(file, track_map);
110 if( NeAACDecInit(codec->decoder_handle,
111 quicktime_vbr_input(vbr), quicktime_vbr_input_size(vbr),
112 &samplerate, &channels) < 0 ) return 1;
115 if( NeAACDecInit2(codec->decoder_handle,
116 (unsigned char *)mp4_hdr, hdr_len,
117 &samplerate, &channels) < 0 ) return 1;
119 //printf("decode %d samplerate=%d channels=%d\n", __LINE__, samplerate, channels);
120 codec->decoder_initialized = 1;
123 if( quicktime_align_vbr(track_map, current_position) ||
124 codec->output_position != quicktime_vbr_output_end(vbr) ) {
125 quicktime_seek_vbr(track_map, current_position, 1);
126 codec->output_position = quicktime_vbr_output_end(vbr);
129 // Decode until buffer is full
130 while( quicktime_vbr_output_end(vbr) < end_position ) {
131 if(quicktime_read_vbr(file, track_map)) break;
133 bzero(&codec->frame_info, sizeof(NeAACDecFrameInfo));
134 float *sample_buffer = NeAACDecDecode(codec->decoder_handle, &codec->frame_info,
135 quicktime_vbr_input(vbr), quicktime_vbr_input_size(vbr));
137 quicktime_shift_vbr(track_map, quicktime_vbr_input_size(vbr));
138 int result = codec->frame_info.samples / track_map->channels;
139 quicktime_store_vbr_float(track_map, sample_buffer, result);
140 codec->output_position += result;
143 // Transfer from buffer to output
145 quicktime_copy_vbr_int16(vbr, current_position,
146 samples, output_i, channel);
148 quicktime_copy_vbr_float(vbr, current_position,
149 samples, output_f, channel);
155 static int encode(quicktime_t *file,
162 quicktime_audio_map_t *track_map = &(file->atracks[track]);
163 quicktime_trak_t *trak = track_map->track;
164 quicktime_mp4a_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
165 int channels = quicktime_track_channels(file, track);
168 if(!codec->encoder_initialized)
170 unsigned long input_samples;
171 unsigned long max_output_bytes;
172 int sample_rate = quicktime_sample_rate(file, track);
173 codec->encoder_initialized = 1;
174 codec->encoder_handle = faacEncOpen(quicktime_sample_rate(file, track),
179 codec->frame_size = input_samples / channels;
180 codec->max_frame_bytes = max_output_bytes;
181 codec->compressed_buffer = calloc(1, max_output_bytes);
182 codec->encoder_params = faacEncGetCurrentConfiguration(codec->encoder_handle);
184 // Parameters from ffmpeg
185 codec->encoder_params->aacObjectType = LOW;
186 codec->encoder_params->mpegVersion = MPEG4;
187 codec->encoder_params->useTns = 0;
188 codec->encoder_params->allowMidside = 1;
189 codec->encoder_params->inputFormat = FAAC_INPUT_FLOAT;
190 codec->encoder_params->outputFormat = 0;
191 codec->encoder_params->bitRate = codec->bitrate / channels;
192 codec->encoder_params->quantqual = codec->quantizer_quality;
193 codec->encoder_params->bandWidth = sample_rate / 2;
195 if(!faacEncSetConfiguration(codec->encoder_handle, codec->encoder_params))
197 fprintf(stderr, "encode: unsupported MPEG-4 Audio configuration!@#!@#\n");
203 // Create esds header
204 unsigned char *buffer;
205 unsigned long buffer_size;
206 faacEncGetDecoderSpecificInfo(codec->encoder_handle,
209 quicktime_set_mpeg4_header(&trak->mdia.minf.stbl.stsd.table[0],
212 //breaks android player
213 //trak->mdia.minf.stbl.stsd.table[0].version = 1;
214 // Quicktime player needs this.
215 trak->mdia.minf.stbl.stsd.table[0].compression_id = 0xfffe;
219 // Stack new audio at end of old audio
220 int new_allocation = codec->input_size + samples;
221 if(new_allocation > codec->input_allocated)
223 codec->input_buffer = realloc(codec->input_buffer,
227 codec->input_allocated = new_allocation;
230 float *output = (float*)codec->input_buffer + codec->input_size * channels;
233 for(i = 0; i < samples; i++)
235 for(j = 0; j < channels; j++)
237 *output++ = input_f[j][i] * 32767;
244 for(i = 0; i < samples; i++)
246 for(j = 0; j < channels; j++)
248 *output++ = (float)input_i[j][i];
253 codec->input_size += samples;
256 for(i = 0; i + codec->frame_size < codec->input_size; i += codec->frame_size)
258 int bytes = faacEncEncode(codec->encoder_handle,
259 (int32_t*)(codec->input_buffer + i * channels),
260 codec->frame_size * channels,
261 codec->compressed_buffer,
262 codec->max_frame_bytes);
264 * printf("encode 1 %lld %d %d\n",
265 * track_map->current_position,
269 // Write out the packet
272 quicktime_write_vbr_frame(file, track,
273 (char*)codec->compressed_buffer, bytes,
278 for(j = i * channels, k = 0; j < codec->input_size * channels; j++, k++)
280 codec->input_buffer[k] = codec->input_buffer[j];
282 codec->input_size -= i;
289 static void flush(quicktime_t *file, int track)
291 quicktime_audio_map_t *track_map = &(file->atracks[track]);
292 quicktime_mp4a_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
293 int channels = quicktime_track_channels(file, track);
295 if(codec->encoder_initialized)
298 i < codec->input_size &&
299 i + codec->frame_size < codec->input_allocated;
300 i += codec->frame_size)
302 int bytes = faacEncEncode(codec->encoder_handle,
303 (int32_t*)(codec->input_buffer + i * channels),
304 codec->frame_size * channels,
305 codec->compressed_buffer,
306 codec->max_frame_bytes);
309 * printf("flush 1 %d %d %d\n",
310 * codec->encoder_params->bitRate,
312 * codec->max_frame_bytes);
314 // Write out the packet
317 quicktime_write_vbr_frame(file, track,
318 (char*)codec->compressed_buffer, bytes,
326 static int set_parameter(quicktime_t *file,
331 quicktime_audio_map_t *atrack = &(file->atracks[track]);
332 char *compressor = quicktime_compressor(atrack->track);
334 if(quicktime_match_32(compressor, QUICKTIME_MP4A))
336 quicktime_mp4a_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
337 if(!strcasecmp(key, "mp4a_bitrate"))
339 codec->bitrate = *(int*)value;
342 if(!strcasecmp(key, "mp4a_quantqual"))
344 codec->quantizer_quality = *(int*)value;
352 void quicktime_init_codec_mp4a(quicktime_audio_map_t *atrack)
354 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
355 quicktime_mp4a_codec_t *codec;
356 codec_base->priv = calloc(1, sizeof(quicktime_mp4a_codec_t));
357 codec_base->delete_acodec = delete_codec;
358 codec_base->decode_audio = decode;
359 codec_base->encode_audio = encode;
360 codec_base->set_parameter = set_parameter;
361 codec_base->flush = flush;
362 codec_base->fourcc = QUICKTIME_MP4A;
363 codec_base->title = "MPEG4 audio";
364 codec_base->desc = "Audio section of MPEG4 standard";
366 codec = (quicktime_mp4a_codec_t*)codec_base->priv;
367 // Default encoding parameters here
368 codec->bitrate = 256000;
369 codec->quantizer_quality = 100;