1 #include "funcprotos.h"
9 #define MAX(a, b) ((a) > (b) ? (a) : (b))
13 #define MIN(a, b) ((a) < (b) ? (a) : (b))
16 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
18 #define OUTPUT_ALLOCATION 0x100000
20 //static FILE *test = 0;
26 // Number of first sample in output relative to file
27 int64_t output_position;
28 // Current reading position in file
30 int decode_initialized;
34 lame_global_flags *lame_global;
35 // This calculates the number of samples per chunk
36 mpeg3_layer_t *encoded_header;
37 int encode_initialized;
42 unsigned char *encoder_output;
43 int encoder_output_size;
44 int encoder_output_allocated;
45 } quicktime_mp3_codec_t;
47 static void delete_codec(quicktime_audio_map_t *atrack)
50 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
52 if( codec->mp3 ) mpeg3_delete_layer(codec->mp3);
54 for( i=0; i<atrack->channels; ++i ) free(codec->output[i]);
57 if( codec->lame_global )
58 lame_close(codec->lame_global);
60 for( i=0; i<atrack->channels; ++i ) free(codec->input[i]);
63 if( codec->encoder_output ) free(codec->encoder_output);
64 if( codec->encoded_header )
65 mpeg3_delete_layer(codec->encoded_header);
69 static int decode(quicktime_t *file,
70 int16_t *output_i, float *output_f,
71 long samples, int track, int channel)
73 quicktime_audio_map_t *track_map = &(file->atracks[track]);
74 quicktime_vbr_t *vbr = &track_map->vbr;
75 int channels = track_map->channels;
76 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
77 int64_t current_position = track_map->current_position;
78 int64_t end_position = current_position + samples;
79 int i, retry = 0, result = 0;
81 if(output_i) bzero(output_i, sizeof(int16_t) * samples);
82 if(output_f) bzero(output_f, sizeof(float) * samples);
84 if( quicktime_limit_samples(samples) ) return 1;
86 // Initialize and load initial buffer for decoding
87 if( !codec->decode_initialized ) {
88 codec->decode_initialized = 1;
89 quicktime_init_vbr(vbr, channels);
90 codec->output = malloc(sizeof(float*) * track_map->channels);
91 for(i = 0; i < track_map->channels; i++)
92 codec->output[i] = malloc(sizeof(float) * MAXFRAMESAMPLES);
93 codec->mp3 = mpeg3_new_layer();
96 if( quicktime_align_vbr(track_map, current_position) ||
97 codec->output_position != quicktime_vbr_output_end(vbr) ) {
98 quicktime_seek_vbr(track_map, current_position, 1);
99 mpeg3_layer_reset(codec->mp3);
100 codec->output_position = quicktime_vbr_output_end(vbr);
104 while( quicktime_vbr_output_end(vbr) < end_position && retry >= 0 ) {
105 // find a frame header
106 int bfr_sz = quicktime_vbr_input_size(vbr);
107 unsigned char *bfr = quicktime_vbr_input(vbr);
109 while( bfr_sz >= 4 ) {
110 frame_size = mpeg3_layer_header(codec->mp3, bfr);
111 if( frame_size ) break;
115 if( quicktime_read_vbr(file, track_map) ) break;
119 // shift out data before frame header
120 i = bfr - quicktime_vbr_input(vbr);
121 if( i > 0 ) quicktime_shift_vbr(track_map, i);
123 // collect frame data
124 while( quicktime_vbr_input_size(vbr) < frame_size && retry >= 0 ) {
125 if( quicktime_read_vbr(file, track_map) ) break;
128 if( retry < 0 ) break;
129 if( quicktime_vbr_input_size(vbr) < frame_size ) break;
132 result = mpeg3audio_dolayer3(codec->mp3,
133 (char *)quicktime_vbr_input(vbr), frame_size,
136 quicktime_store_vbr_floatp(track_map, codec->output, result);
137 codec->output_position += result;
140 quicktime_shift_vbr(track_map, frame_size);
144 quicktime_copy_vbr_int16(vbr, current_position,
145 samples, output_i, channel);
147 quicktime_copy_vbr_float(vbr, current_position,
148 samples, output_f, channel);
155 static int allocate_output(quicktime_mp3_codec_t *codec,
158 int new_size = codec->encoder_output_size + samples * 4;
159 if(codec->encoder_output_allocated < new_size)
161 unsigned char *new_output = calloc(1, new_size);
163 if(codec->encoder_output)
166 codec->encoder_output,
167 codec->encoder_output_size);
168 free(codec->encoder_output);
170 codec->encoder_output = new_output;
171 codec->encoder_output_allocated = new_size;
178 // Empty the output buffer of frames
179 static int write_frames(quicktime_t *file,
180 quicktime_audio_map_t *track_map,
181 quicktime_trak_t *trak,
182 quicktime_mp3_codec_t *codec,
185 int frame_end = codec->encoder_output_size;
186 unsigned char *bfr = codec->encoder_output;
187 int frame_limit = frame_end - 4;
193 while( !result && i < frame_limit ) {
194 char *hdr = (char *)bfr + i;
195 int frame_size = mpeg3_layer_header(codec->encoded_header,
196 (unsigned char *)hdr);
197 // Not the start of a frame. Skip it, try next bfr byte;
198 if( !frame_size ) { ++i; continue; }
199 // Frame is finished before end of buffer
200 if( i+frame_size > frame_end ) break;
203 frame_samples = mpeg3audio_dolayer3(codec->encoded_header,
204 hdr, frame_size, 0, 0);
206 if( !frame_samples ) continue;
207 result = quicktime_write_vbr_frame(file, track,
208 hdr, frame_size, frame_samples);
209 track_map->current_chunk++;
212 // move any frame fragment down
215 codec->encoder_output_size -= i;
216 while( i < frame_end ) bfr[j++] = bfr[i++];
227 static int encode(quicktime_t *file,
228 int16_t **input_i, float **input_f, int track, long samples)
231 quicktime_audio_map_t *track_map = &(file->atracks[track]);
232 quicktime_trak_t *trak = track_map->track;
233 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
234 int new_size = codec->input_size + samples;
237 if(!codec->encode_initialized)
239 codec->encode_initialized = 1;
240 codec->lame_global = lame_init();
241 lame_set_brate(codec->lame_global, codec->bitrate / 1000);
242 lame_set_quality(codec->lame_global, 0);
243 lame_set_in_samplerate(codec->lame_global,
244 trak->mdia.minf.stbl.stsd.table[0].sample_rate);
245 if((result = lame_init_params(codec->lame_global)) < 0)
246 printf("encode: lame_init_params returned %d\n", result);
247 codec->encoded_header = mpeg3_new_layer();
249 trak->mdia.minf.stbl.stsd.table[0].sample_size = 0;
253 // Stack input on end of buffer
254 if(new_size > codec->input_allocated)
259 codec->input = calloc(sizeof(float*), track_map->channels);
261 for(i = 0; i < track_map->channels; i++)
263 new_input = calloc(sizeof(float), new_size);
266 memcpy(new_input, codec->input[i], sizeof(float) * codec->input_size);
267 free(codec->input[i]);
269 codec->input[i] = new_input;
271 codec->input_allocated = new_size;
275 // Transfer to input buffers
278 for(i = 0; i < track_map->channels; i++)
280 for(j = 0; j < samples; j++)
281 codec->input[i][j] = input_i[i][j];
287 for(i = 0; i < track_map->channels; i++)
289 for(j = 0; j < samples; j++)
290 codec->input[i][j] = input_f[i][j] * 32767;
295 allocate_output(codec, samples);
297 result = lame_encode_buffer_float(codec->lame_global,
299 (track_map->channels > 1) ? codec->input[1] : codec->input[0],
301 codec->encoder_output + codec->encoder_output_size,
302 codec->encoder_output_allocated - codec->encoder_output_size);
304 codec->encoder_output_size += result;
306 result = write_frames(file, track_map, trak, codec, track);
312 static int set_parameter(quicktime_t *file,
317 quicktime_audio_map_t *atrack = &(file->atracks[track]);
318 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
320 if(!strcasecmp(key, "mp3_bitrate"))
321 codec->bitrate = *(int*)value;
328 static void flush(quicktime_t *file, int track)
331 quicktime_audio_map_t *track_map = &(file->atracks[track]);
332 quicktime_trak_t *trak = track_map->track;
333 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
335 if(codec->encode_initialized)
337 result = lame_encode_flush(codec->lame_global,
338 codec->encoder_output + codec->encoder_output_size,
339 codec->encoder_output_allocated - codec->encoder_output_size);
340 codec->encoder_output_size += result;
341 result = write_frames(file, track_map, trak, codec, track);
346 void quicktime_init_codec_mp3(quicktime_audio_map_t *atrack)
348 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
349 quicktime_mp3_codec_t *codec;
351 /* Init public items */
352 codec_base->priv = calloc(1, sizeof(quicktime_mp3_codec_t));
353 codec_base->delete_acodec = delete_codec;
354 codec_base->decode_audio = decode;
355 codec_base->encode_audio = encode;
356 codec_base->set_parameter = set_parameter;
357 codec_base->flush = flush;
358 codec_base->fourcc = QUICKTIME_MP3;
359 codec_base->title = "MP3";
360 codec_base->desc = "MP3 for video";
361 codec_base->wav_id = 0x55;
363 codec = codec_base->priv;
364 codec->bitrate = 256000;