5 // The FAAD includes redefine the same symbols as if they're not intended to
6 // be used by the same program.
13 #include "funcprotos.h"
14 #include "quicktime.h"
17 // Attempts to read more samples than this will crash
18 #define OUTPUT_ALLOCATION 0x100000
19 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
25 faacDecHandle decoder_handle
;
26 faacDecFrameInfo frame_info
;
27 faacDecConfigurationPtr decoder_config
;
28 int decoder_initialized
;
31 faacEncHandle encoder_handle
;
32 faacEncConfigurationPtr encoder_params
;
36 // Interleaved samples
40 // Number of samples allocated
42 unsigned char *compressed_buffer
;
44 int quantizer_quality
;
45 int encoder_initialized
;
46 } quicktime_mp4a_codec_t
;
53 static int delete_codec(quicktime_audio_map_t
*atrack
)
55 quicktime_mp4a_codec_t
*codec
=
56 ((quicktime_codec_t
*)atrack
->codec
)->priv
;
58 if(codec
->decoder_initialized
)
60 faacDecClose(codec
->decoder_handle
);
63 if(codec
->encoder_initialized
)
65 faacEncClose(codec
->encoder_handle
);
66 if(codec
->compressed_buffer
) free(codec
->compressed_buffer
);
67 if(codec
->input_buffer
) free(codec
->input_buffer
);
73 static int decode(quicktime_t
*file
,
80 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
81 quicktime_trak_t
*trak
= track_map
->track
;
82 quicktime_mp4a_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
83 int64_t current_position
= track_map
->current_position
;
84 int64_t end_position
= current_position
+ samples
;
85 quicktime_vbr_t
*vbr
= &track_map
->vbr
;
89 if(!codec
->decoder_initialized
)
91 uint32_t samplerate
= trak
->mdia
.minf
.stbl
.stsd
.table
[0].sample_rate
;
92 // FAAD needs unsigned char here
93 unsigned char channels
= track_map
->channels
;
94 quicktime_init_vbr(vbr
, channels
);
95 codec
->decoder_handle
= faacDecOpen();
96 codec
->decoder_config
= faacDecGetCurrentConfiguration(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 faacDecSetConfiguration(codec
->decoder_handle
, codec
->decoder_config
);
103 quicktime_align_vbr(track_map
, samples
);
104 quicktime_read_vbr(file
, track_map
);
105 if(faacDecInit(codec
->decoder_handle
,
106 quicktime_vbr_input(vbr
),
107 quicktime_vbr_input_size(vbr
),
113 //printf("decode %d %d\n", samplerate, channels);
114 codec
->decoder_initialized
= 1;
117 if(quicktime_align_vbr(track_map
,
124 // Decode until buffer is full
125 while(quicktime_vbr_end(vbr
) < end_position
)
127 // Fill until min buffer size reached or EOF
129 * while(quicktime_vbr_input_size(vbr) <
130 * FAAD_MIN_STREAMSIZE * track_map->channels)
132 * if(quicktime_read_vbr(file, track_map)) break;
136 if(quicktime_read_vbr(file
, track_map
)) break;
138 bzero(&codec
->frame_info
, sizeof(faacDecFrameInfo
));
139 float *sample_buffer
= faacDecDecode(codec
->decoder_handle
,
141 quicktime_vbr_input(vbr
),
142 quicktime_vbr_input_size(vbr
));
144 if (codec
->frame_info
.error
> 0)
146 // printf("decode mp4a: %s\n",
147 // faacDecGetErrorMessage(codec->frame_info.error));
151 * printf("decode 1 %d %d %d\n",
152 * quicktime_vbr_input_size(vbr),
153 * codec->frame_info.bytesconsumed,
154 * codec->frame_info.samples);
156 * static FILE *test = 0;
157 * if(!test) test = fopen("/tmp/test.aac", "w");
158 * fwrite(quicktime_vbr_input(vbr), quicktime_vbr_input_size(vbr), 1, test);
163 * static FILE *test = 0;
164 * if(!test) test = fopen("/hmov/test.pcm", "w");
166 * for(i = 0; i < codec->frame_info.samples; i++)
168 * int16_t sample = (int)(sample_buffer[i] * 32767);
169 * fwrite(&sample, 2, 1, test);
174 // quicktime_shift_vbr(track_map, codec->frame_info.bytesconsumed);
175 quicktime_shift_vbr(track_map
, quicktime_vbr_input_size(vbr
));
176 quicktime_store_vbr_float(track_map
,
178 codec
->frame_info
.samples
/ track_map
->channels
);
182 // Transfer from buffer to output
184 quicktime_copy_vbr_int16(vbr
,
191 quicktime_copy_vbr_float(vbr
,
201 static int encode(quicktime_t
*file
,
208 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
209 quicktime_trak_t
*trak
= track_map
->track
;
210 quicktime_mp4a_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
211 int channels
= quicktime_track_channels(file
, track
);
214 if(!codec
->encoder_initialized
)
216 unsigned long input_samples
;
217 unsigned long max_output_bytes
;
218 int sample_rate
= quicktime_sample_rate(file
, track
);
219 codec
->encoder_initialized
= 1;
220 codec
->encoder_handle
= faacEncOpen(quicktime_sample_rate(file
, track
),
225 codec
->frame_size
= input_samples
/ channels
;
226 codec
->max_frame_bytes
= max_output_bytes
;
227 codec
->compressed_buffer
= calloc(1, max_output_bytes
);
228 codec
->encoder_params
= faacEncGetCurrentConfiguration(codec
->encoder_handle
);
230 // Parameters from ffmpeg
231 codec
->encoder_params
->aacObjectType
= LOW
;
232 codec
->encoder_params
->mpegVersion
= MPEG4
;
233 codec
->encoder_params
->useTns
= 0;
234 codec
->encoder_params
->allowMidside
= 1;
235 codec
->encoder_params
->inputFormat
= FAAC_INPUT_FLOAT
;
236 codec
->encoder_params
->outputFormat
= 0;
237 codec
->encoder_params
->bitRate
= codec
->bitrate
/ channels
;
238 codec
->encoder_params
->quantqual
= codec
->quantizer_quality
;
239 codec
->encoder_params
->bandWidth
= sample_rate
/ 2;
241 if(!faacEncSetConfiguration(codec
->encoder_handle
, codec
->encoder_params
))
243 fprintf(stderr
, "encode: unsupported MPEG-4 Audio configuration!@#!@#\n");
249 // Create esds header
250 unsigned char *buffer
;
251 unsigned long buffer_size
;
252 faacEncGetDecoderSpecificInfo(codec
->encoder_handle
,
255 quicktime_set_mpeg4_header(&trak
->mdia
.minf
.stbl
.stsd
.table
[0],
258 trak
->mdia
.minf
.stbl
.stsd
.table
[0].version
= 1;
259 // Quicktime player needs this.
260 trak
->mdia
.minf
.stbl
.stsd
.table
[0].compression_id
= 0xfffe;
264 // Stack new audio at end of old audio
265 int new_allocation
= codec
->input_size
+ samples
;
266 if(new_allocation
> codec
->input_allocated
)
268 codec
->input_buffer
= realloc(codec
->input_buffer
,
272 codec
->input_allocated
= new_allocation
;
275 float *output
= (float*)codec
->input_buffer
+ codec
->input_size
* channels
;
278 for(i
= 0; i
< samples
; i
++)
280 for(j
= 0; j
< channels
; j
++)
282 *output
++ = input_f
[j
][i
] * 32767;
289 for(i
= 0; i
< samples
; i
++)
291 for(j
= 0; j
< channels
; j
++)
293 *output
++ = (float)input_i
[j
][i
];
298 codec
->input_size
+= samples
;
301 for(i
= 0; i
+ codec
->frame_size
< codec
->input_size
; i
+= codec
->frame_size
)
303 int bytes
= faacEncEncode(codec
->encoder_handle
,
304 (int32_t*)(codec
->input_buffer
+ i
* channels
),
305 codec
->frame_size
* channels
,
306 codec
->compressed_buffer
,
307 codec
->max_frame_bytes
);
309 * printf("encode 1 %lld %d %d\n",
310 * track_map->current_position,
314 // Write out the packet
317 quicktime_write_vbr_frame(file
,
319 codec
->compressed_buffer
,
325 for(j
= i
* channels
, k
= 0; j
< codec
->input_size
* channels
; j
++, k
++)
327 codec
->input_buffer
[k
] = codec
->input_buffer
[j
];
329 codec
->input_size
-= i
;
336 static void flush(quicktime_t
*file
, int track
)
338 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
339 quicktime_trak_t
*trak
= track_map
->track
;
340 quicktime_mp4a_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
341 int channels
= quicktime_track_channels(file
, track
);
343 if(codec
->encoder_initialized
)
346 i
< codec
->input_size
&&
347 i
+ codec
->frame_size
< codec
->input_allocated
;
348 i
+= codec
->frame_size
)
350 int bytes
= faacEncEncode(codec
->encoder_handle
,
351 (int32_t*)(codec
->input_buffer
+ i
* channels
),
352 codec
->frame_size
* channels
,
353 codec
->compressed_buffer
,
354 codec
->max_frame_bytes
);
357 * printf("flush 1 %d %d %d\n",
358 * codec->encoder_params->bitRate,
360 * codec->max_frame_bytes);
362 // Write out the packet
365 quicktime_write_vbr_frame(file
,
367 codec
->compressed_buffer
,
376 static int set_parameter(quicktime_t
*file
,
381 quicktime_audio_map_t
*atrack
= &(file
->atracks
[track
]);
382 char *compressor
= quicktime_compressor(atrack
->track
);
384 if(quicktime_match_32(compressor
, QUICKTIME_MP4A
))
386 quicktime_mp4a_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
387 if(!strcasecmp(key
, "mp4a_bitrate"))
389 codec
->bitrate
= *(int*)value
;
392 if(!strcasecmp(key
, "mp4a_quantqual"))
394 codec
->quantizer_quality
= *(int*)value
;
402 void quicktime_init_codec_mp4a(quicktime_audio_map_t
*atrack
)
404 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)atrack
->codec
;
405 quicktime_mp4a_codec_t
*codec
;
406 codec_base
->priv
= calloc(1, sizeof(quicktime_mp4a_codec_t
));
407 codec_base
->delete_acodec
= delete_codec
;
408 codec_base
->decode_audio
= decode
;
409 codec_base
->encode_audio
= encode
;
410 codec_base
->set_parameter
= set_parameter
;
411 codec_base
->flush
= flush
;
412 codec_base
->fourcc
= "mp4a";
413 codec_base
->title
= "MPEG4 audio";
414 codec_base
->desc
= "Audio section of MPEG4 standard";
416 codec
= (quicktime_mp4a_codec_t
*)codec_base
->priv
;
417 // Default encoding parameters here
418 codec
->bitrate
= 256000;
419 codec
->quantizer_quality
= 100;