6 // The FAAD includes redefine the same symbols as if they're not intended to
7 // be used by the same program.
14 #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 faacDecHandle decoder_handle
;
27 faacDecFrameInfo frame_info
;
28 faacDecConfigurationPtr decoder_config
;
29 int decoder_initialized
;
32 faacEncHandle encoder_handle
;
33 faacEncConfigurationPtr encoder_params
;
37 // Interleaved samples
41 // Number of samples allocated
43 unsigned char *compressed_buffer
;
45 int quantizer_quality
;
46 int encoder_initialized
;
47 } quicktime_mp4a_codec_t
;
54 static int delete_codec(quicktime_audio_map_t
*atrack
)
56 quicktime_mp4a_codec_t
*codec
=
57 ((quicktime_codec_t
*)atrack
->codec
)->priv
;
59 if(codec
->decoder_initialized
)
61 faacDecClose(codec
->decoder_handle
);
64 if(codec
->encoder_initialized
)
66 faacEncClose(codec
->encoder_handle
);
67 if(codec
->compressed_buffer
) free(codec
->compressed_buffer
);
68 if(codec
->input_buffer
) free(codec
->input_buffer
);
74 static int decode(quicktime_t
*file
,
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
;
90 if(!codec
->decoder_initialized
)
92 uint32_t samplerate
= trak
->mdia
.minf
.stbl
.stsd
.table
[0].sample_rate
;
93 // FAAD needs unsigned char here
94 unsigned char channels
= track_map
->channels
;
95 quicktime_init_vbr(vbr
, channels
);
96 codec
->decoder_handle
= faacDecOpen();
97 codec
->decoder_config
= faacDecGetCurrentConfiguration(codec
->decoder_handle
);
98 codec
->decoder_config
->outputFormat
= FAAD_FMT_FLOAT
;
99 // codec->decoder_config->defSampleRate =
100 // trak->mdia.minf.stbl.stsd.table[0].sample_rate;
102 faacDecSetConfiguration(codec
->decoder_handle
, codec
->decoder_config
);
104 quicktime_align_vbr(track_map
, samples
);
105 quicktime_read_vbr(file
, track_map
);
106 if(faacDecInit(codec
->decoder_handle
,
107 quicktime_vbr_input(vbr
),
108 quicktime_vbr_input_size(vbr
),
114 //printf("decode %d %d\n", samplerate, channels);
115 codec
->decoder_initialized
= 1;
118 if(quicktime_align_vbr(track_map
,
125 // Decode until buffer is full
126 while(quicktime_vbr_end(vbr
) < end_position
)
128 // Fill until min buffer size reached or EOF
130 * while(quicktime_vbr_input_size(vbr) <
131 * FAAD_MIN_STREAMSIZE * track_map->channels)
133 * if(quicktime_read_vbr(file, track_map)) break;
137 if(quicktime_read_vbr(file
, track_map
)) break;
139 bzero(&codec
->frame_info
, sizeof(faacDecFrameInfo
));
140 float *sample_buffer
= faacDecDecode(codec
->decoder_handle
,
142 quicktime_vbr_input(vbr
),
143 quicktime_vbr_input_size(vbr
));
145 if (codec
->frame_info
.error
> 0)
147 // printf("decode mp4a: %s\n",
148 // faacDecGetErrorMessage(codec->frame_info.error));
152 * printf("decode 1 %d %d %d\n",
153 * quicktime_vbr_input_size(vbr),
154 * codec->frame_info.bytesconsumed,
155 * codec->frame_info.samples);
157 * static FILE *test = 0;
158 * if(!test) test = fopen("/tmp/test.aac", "w");
159 * fwrite(quicktime_vbr_input(vbr), quicktime_vbr_input_size(vbr), 1, test);
164 * static FILE *test = 0;
165 * if(!test) test = fopen("/hmov/test.pcm", "w");
167 * for(i = 0; i < codec->frame_info.samples; i++)
169 * int16_t sample = (int)(sample_buffer[i] * 32767);
170 * fwrite(&sample, 2, 1, test);
175 // quicktime_shift_vbr(track_map, codec->frame_info.bytesconsumed);
176 quicktime_shift_vbr(track_map
, quicktime_vbr_input_size(vbr
));
177 quicktime_store_vbr_float(track_map
,
179 codec
->frame_info
.samples
/ track_map
->channels
);
183 // Transfer from buffer to output
185 quicktime_copy_vbr_int16(vbr
,
192 quicktime_copy_vbr_float(vbr
,
202 static int encode(quicktime_t
*file
,
209 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
210 quicktime_trak_t
*trak
= track_map
->track
;
211 quicktime_mp4a_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
212 int channels
= quicktime_track_channels(file
, track
);
215 if(!codec
->encoder_initialized
)
217 unsigned long input_samples
;
218 unsigned long max_output_bytes
;
219 int sample_rate
= quicktime_sample_rate(file
, track
);
220 codec
->encoder_initialized
= 1;
221 codec
->encoder_handle
= faacEncOpen(quicktime_sample_rate(file
, track
),
226 codec
->frame_size
= input_samples
/ channels
;
227 codec
->max_frame_bytes
= max_output_bytes
;
228 codec
->compressed_buffer
= calloc(1, max_output_bytes
);
229 codec
->encoder_params
= faacEncGetCurrentConfiguration(codec
->encoder_handle
);
231 // Parameters from ffmpeg
232 codec
->encoder_params
->aacObjectType
= LOW
;
233 codec
->encoder_params
->mpegVersion
= MPEG4
;
234 codec
->encoder_params
->useTns
= 0;
235 codec
->encoder_params
->allowMidside
= 1;
236 codec
->encoder_params
->inputFormat
= FAAC_INPUT_FLOAT
;
237 codec
->encoder_params
->outputFormat
= 0;
238 codec
->encoder_params
->bitRate
= codec
->bitrate
/ channels
;
239 codec
->encoder_params
->quantqual
= codec
->quantizer_quality
;
240 codec
->encoder_params
->bandWidth
= sample_rate
/ 2;
242 if(!faacEncSetConfiguration(codec
->encoder_handle
, codec
->encoder_params
))
244 fprintf(stderr
, "encode: unsupported MPEG-4 Audio configuration!@#!@#\n");
250 // Create esds header
251 unsigned char *buffer
;
252 unsigned long buffer_size
;
253 faacEncGetDecoderSpecificInfo(codec
->encoder_handle
,
256 quicktime_set_mpeg4_header(&trak
->mdia
.minf
.stbl
.stsd
.table
[0],
259 trak
->mdia
.minf
.stbl
.stsd
.table
[0].version
= 1;
260 // Quicktime player needs this.
261 trak
->mdia
.minf
.stbl
.stsd
.table
[0].compression_id
= 0xfffe;
265 // Stack new audio at end of old audio
266 int new_allocation
= codec
->input_size
+ samples
;
267 if(new_allocation
> codec
->input_allocated
)
269 codec
->input_buffer
= realloc(codec
->input_buffer
,
273 codec
->input_allocated
= new_allocation
;
276 float *output
= (float*)codec
->input_buffer
+ codec
->input_size
* channels
;
279 for(i
= 0; i
< samples
; i
++)
281 for(j
= 0; j
< channels
; j
++)
283 *output
++ = input_f
[j
][i
] * 32767;
290 for(i
= 0; i
< samples
; i
++)
292 for(j
= 0; j
< channels
; j
++)
294 *output
++ = (float)input_i
[j
][i
];
299 codec
->input_size
+= samples
;
302 for(i
= 0; i
+ codec
->frame_size
< codec
->input_size
; i
+= codec
->frame_size
)
304 int bytes
= faacEncEncode(codec
->encoder_handle
,
305 (int32_t*)(codec
->input_buffer
+ i
* channels
),
306 codec
->frame_size
* channels
,
307 codec
->compressed_buffer
,
308 codec
->max_frame_bytes
);
310 * printf("encode 1 %lld %d %d\n",
311 * track_map->current_position,
315 // Write out the packet
318 quicktime_write_vbr_frame(file
,
320 codec
->compressed_buffer
,
326 for(j
= i
* channels
, k
= 0; j
< codec
->input_size
* channels
; j
++, k
++)
328 codec
->input_buffer
[k
] = codec
->input_buffer
[j
];
330 codec
->input_size
-= i
;
337 static void flush(quicktime_t
*file
, int track
)
339 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
340 quicktime_trak_t
*trak
= track_map
->track
;
341 quicktime_mp4a_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
342 int channels
= quicktime_track_channels(file
, track
);
344 if(codec
->encoder_initialized
)
347 i
< codec
->input_size
&&
348 i
+ codec
->frame_size
< codec
->input_allocated
;
349 i
+= codec
->frame_size
)
351 int bytes
= faacEncEncode(codec
->encoder_handle
,
352 (int32_t*)(codec
->input_buffer
+ i
* channels
),
353 codec
->frame_size
* channels
,
354 codec
->compressed_buffer
,
355 codec
->max_frame_bytes
);
358 * printf("flush 1 %d %d %d\n",
359 * codec->encoder_params->bitRate,
361 * codec->max_frame_bytes);
363 // Write out the packet
366 quicktime_write_vbr_frame(file
,
368 codec
->compressed_buffer
,
377 static int set_parameter(quicktime_t
*file
,
382 quicktime_audio_map_t
*atrack
= &(file
->atracks
[track
]);
383 char *compressor
= quicktime_compressor(atrack
->track
);
385 if(quicktime_match_32(compressor
, QUICKTIME_MP4A
))
387 quicktime_mp4a_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
388 if(!strcasecmp(key
, "mp4a_bitrate"))
390 codec
->bitrate
= *(int*)value
;
393 if(!strcasecmp(key
, "mp4a_quantqual"))
395 codec
->quantizer_quality
= *(int*)value
;
403 void quicktime_init_codec_mp4a(quicktime_audio_map_t
*atrack
)
405 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)atrack
->codec
;
406 quicktime_mp4a_codec_t
*codec
;
407 codec_base
->priv
= calloc(1, sizeof(quicktime_mp4a_codec_t
));
408 codec_base
->delete_acodec
= delete_codec
;
409 codec_base
->decode_audio
= decode
;
410 codec_base
->encode_audio
= encode
;
411 codec_base
->set_parameter
= set_parameter
;
412 codec_base
->flush
= flush
;
413 codec_base
->fourcc
= "mp4a";
414 codec_base
->title
= "MPEG4 audio";
415 codec_base
->desc
= "Audio section of MPEG4 standard";
417 codec
= (quicktime_mp4a_codec_t
*)codec_base
->priv
;
418 // Default encoding parameters here
419 codec
->bitrate
= 256000;
420 codec
->quantizer_quality
= 100;