r717: Made the highlighted text color of the menus WHITE
[cinelerra_cv/mob.git] / quicktime / qtmp3.c
blobe5d37fc6fc6f07773b5aafd2618496163d7db9c3
1 #include "funcprotos.h"
3 #include <lame/lame.h>
6 #include "mpeg3private.h"
7 #include "mpeg3protos.h"
8 #include "quicktime.h"
9 #include "qtmp3.h"
11 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
13 #define OUTPUT_ALLOCATION 0x100000
15 //static FILE *test = 0;
17 typedef struct
19 // mp3 decoder
20 mpeg3_layer_t *mp3;
21 // Can't use same structure for header testing
22 mpeg3_layer_t *mp3_header;
23 unsigned char *packet_buffer;
24 int packet_allocated;
27 // Number of first sample in output relative to file
28 int64_t output_position;
29 // Number of samples in output buffer
30 long output_size;
31 // Number of samples allocated in output buffer
32 long output_allocated;
33 // Current reading position in file
34 int64_t chunk;
35 int decode_initialized;
36 float **output;
40 // mp3 encoder
41 lame_global_flags *lame_global;
42 // This calculates the number of samples per chunk
43 mpeg3_layer_t *encoded_header;
44 int encode_initialized;
45 float **input;
46 int input_size;
47 int input_allocated;
48 int bitrate;
49 unsigned char *encoder_output;
50 int encoder_output_size;
51 int encoder_output_allocated;
52 } quicktime_mp3_codec_t;
58 static int delete_codec(quicktime_audio_map_t *atrack)
60 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
61 if(codec->mp3) mpeg3_delete_layer(codec->mp3);
62 if(codec->mp3_header) mpeg3_delete_layer(codec->mp3_header);
63 if(codec->packet_buffer) free(codec->packet_buffer);
64 if(codec->output)
66 int i;
67 for(i = 0; i < atrack->channels; i++)
68 free(codec->output[i]);
69 free(codec->output);
72 if(codec->lame_global)
74 lame_close(codec->lame_global);
77 if(codec->input)
79 int i;
80 for(i = 0; i < atrack->channels; i++)
82 free(codec->input[i]);
84 free(codec->input);
87 if(codec->encoder_output)
88 free(codec->encoder_output);
90 if(codec->encoded_header)
91 mpeg3_delete_layer(codec->encoded_header);
93 free(codec);
95 return 0;
98 static int chunk_len(quicktime_t *file,
99 quicktime_mp3_codec_t *codec,
100 int64_t offset,
101 int64_t next_chunk)
103 int result = 0;
104 unsigned char header[4];
105 int accum = 0;
107 while(offset < next_chunk)
109 quicktime_set_position(file, offset);
110 result = !quicktime_read_data(file, (unsigned char*)&header, 4);
112 if(result)
114 return accum;
117 // Decode size of mp3 frame
118 result = mpeg3_layer_header(codec->mp3_header,
119 header);
121 // Invalid header
122 if(!result)
123 return accum;
124 else
125 // Valid header
127 accum += result;
128 offset += result;
129 quicktime_set_position(file, offset + result);
132 return accum;
144 static int decode(quicktime_t *file,
145 int16_t *output_i,
146 float *output_f,
147 long samples,
148 int track,
149 int channel)
151 int result = 0;
152 quicktime_audio_map_t *track_map = &(file->atracks[track]);
153 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
154 quicktime_trak_t *trak = track_map->track;
155 long current_position = track_map->current_position;
156 long end_position = current_position + samples;
157 float *pcm;
158 int i, j, k;
159 int64_t offset1;
160 int64_t offset2;
161 int chunk_size;
162 int new_size;
163 int frame_size;
164 int try = 0;
165 float **temp_output;
167 if(samples > OUTPUT_ALLOCATION)
168 printf("decode: can't read more than %d samples at a time.\n", OUTPUT_ALLOCATION);
171 //printf("decode 1\n");
172 if(output_i) bzero(output_i, sizeof(int16_t) * samples);
173 if(output_f) bzero(output_f, sizeof(float) * samples);
175 temp_output = malloc(sizeof(float*) * track_map->channels);
177 // Seeked outside output buffer's range or not initialized: restart
178 if(current_position < codec->output_position ||
179 current_position > codec->output_position + codec->output_size ||
180 !codec->decode_initialized)
182 quicktime_chunk_of_sample(&codec->output_position,
183 &codec->chunk,
184 trak,
185 current_position);
187 // We know the first mp3 packet in the chunk has a pcm_offset from the encoding.
188 codec->output_size = 0;
189 //printf("decode 1 %lld %d\n", codec->output_position, quicktime_chunk_samples(trak, codec->chunk));
190 codec->output_position = quicktime_sample_of_chunk(trak, codec->chunk);
191 //printf("decode 2 %lld\n", codec->output_position);
193 // Initialize and load initial buffer for decoding
194 if(!codec->decode_initialized)
196 int i;
197 codec->decode_initialized = 1;
198 codec->output = malloc(sizeof(float*) * track_map->channels);
199 for(i = 0; i < track_map->channels; i++)
201 codec->output[i] = malloc(sizeof(float) * OUTPUT_ALLOCATION);
203 codec->output_allocated = OUTPUT_ALLOCATION;
204 codec->mp3 = mpeg3_new_layer();
205 codec->mp3_header = mpeg3_new_layer();
209 // Decode chunks until output is big enough
210 while(codec->output_position + codec->output_size <
211 current_position + samples &&
212 try < 6)
214 // Decode a chunk
215 offset1 = quicktime_chunk_to_offset(file, trak, codec->chunk);
216 offset2 = quicktime_chunk_to_offset(file, trak, codec->chunk + 1);
218 if(offset2 == offset1) break;
220 chunk_size = chunk_len(file, codec, offset1, offset2);
222 if(codec->packet_allocated < chunk_size &&
223 codec->packet_buffer)
225 free(codec->packet_buffer);
226 codec->packet_buffer = 0;
229 if(!codec->packet_buffer)
231 codec->packet_buffer = calloc(1, chunk_size);
232 codec->packet_allocated = chunk_size;
235 quicktime_set_position(file, offset1);
236 result = !quicktime_read_data(file, codec->packet_buffer, chunk_size);
237 if(result) break;
239 for(i = 0; i < chunk_size; )
241 // Allocate more output
242 new_size = codec->output_size + MAXFRAMESAMPLES;
243 if(new_size > codec->output_allocated)
245 for(j = 0; j < track_map->channels; j++)
247 float *new_output = calloc(sizeof(float), new_size);
248 memcpy(new_output,
249 codec->output[j],
250 sizeof(float) * codec->output_size);
251 free(codec->output[j]);
252 codec->output[j] = new_output;
254 codec->output_allocated = new_size;
257 // Decode a frame
258 for(j = 0; j < track_map->channels; j++)
259 temp_output[j] = codec->output[j] + codec->output_size;
261 frame_size = mpeg3_layer_header(codec->mp3,
262 codec->packet_buffer + i);
264 result = mpeg3audio_dolayer3(codec->mp3,
265 codec->packet_buffer + i,
266 frame_size,
267 temp_output,
271 if(result)
273 codec->output_size += result;
274 result = 0;
275 try = 0;
277 else
279 try++;
282 i += frame_size;
285 codec->chunk++;
288 // Transfer region of output to argument
289 pcm = codec->output[channel];
290 if(output_i)
292 for(i = current_position - codec->output_position, j = 0;
293 j < samples && i < codec->output_size;
294 j++, i++)
296 int sample = pcm[i] * 32767;
297 CLAMP(sample, -32768, 32767);
298 output_i[j] = sample;
301 else
302 if(output_f)
304 for(i = current_position - codec->output_position, j = 0;
305 j < samples && i < codec->output_size;
306 j++, i++)
308 output_f[j] = pcm[i];
312 // Delete excess output
313 if(codec->output_size > OUTPUT_ALLOCATION)
315 int diff = codec->output_size - OUTPUT_ALLOCATION;
316 for(k = 0; k < track_map->channels; k++)
318 pcm = codec->output[k];
319 for(i = 0, j = diff; j < codec->output_size; i++, j++)
321 pcm[i] = pcm[j];
324 codec->output_size -= diff;
325 codec->output_position += diff;
328 free(temp_output);
329 //printf("decode 100\n");
330 return 0;
336 static int allocate_output(quicktime_mp3_codec_t *codec,
337 int samples)
339 int new_size = codec->encoder_output_size + samples * 4;
340 if(codec->encoder_output_allocated < new_size)
342 unsigned char *new_output = calloc(1, new_size);
344 if(codec->encoder_output)
346 memcpy(new_output,
347 codec->encoder_output,
348 codec->encoder_output_size);
349 free(codec->encoder_output);
351 codec->encoder_output = new_output;
352 codec->encoder_output_allocated = new_size;
359 // Empty the output buffer of frames
360 static int write_frames(quicktime_t *file,
361 quicktime_audio_map_t *track_map,
362 quicktime_trak_t *trak,
363 quicktime_mp3_codec_t *codec,
364 int track)
366 int result = 0;
367 int i, j;
368 int frames_end = 0;
369 quicktime_atom_t chunk_atom;
371 // Write to chunks
372 for(i = 0; i < codec->encoder_output_size - 4; )
374 unsigned char *header = codec->encoder_output + i;
375 int frame_size = mpeg3_layer_header(codec->encoded_header, header);
377 if(frame_size)
379 // Frame is finished before end of buffer
380 if(i + frame_size <= codec->encoder_output_size)
382 // Write the chunk
383 int64_t offset;
384 int frame_samples = mpeg3audio_dolayer3(codec->encoded_header,
385 header,
386 frame_size,
391 quicktime_write_vbr_frame(file,
392 track,
393 header,
394 frame_size,
395 frame_samples);
399 // quicktime_write_chunk_header(file, trak, &chunk_atom);
400 // result = !quicktime_write_data(file, header, frame_size);
401 // // Knows not to save the chunksizes for audio
402 // quicktime_write_chunk_footer(file,
403 // trak,
404 // track_map->current_chunk,
405 // &chunk_atom,
406 // frame_samples);
407 track_map->current_chunk++;
411 i += frame_size;
412 frames_end = i;
414 else
415 // Frame isn't finished before end of buffer.
417 frames_end = i;
418 break;
421 else
422 // Not the start of a frame. Skip it.
424 i++;
425 frames_end = i;
429 if(frames_end > 0)
431 for(i = frames_end, j = 0; i < codec->encoder_output_size; i++, j++)
433 codec->encoder_output[j] = codec->encoder_output[i];
435 codec->encoder_output_size -= frames_end;
437 return result;
445 static int encode(quicktime_t *file,
446 int16_t **input_i,
447 float **input_f,
448 int track,
449 long samples)
451 int result = 0;
452 quicktime_audio_map_t *track_map = &(file->atracks[track]);
453 quicktime_trak_t *trak = track_map->track;
454 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
455 int new_size = codec->input_size + samples;
456 int i, j;
457 int frames_end = 0;
459 if(!codec->encode_initialized)
461 codec->encode_initialized = 1;
462 codec->lame_global = lame_init();
463 lame_set_brate(codec->lame_global, codec->bitrate / 1000);
464 lame_set_quality(codec->lame_global, 0);
465 lame_set_in_samplerate(codec->lame_global,
466 trak->mdia.minf.stbl.stsd.table[0].sample_rate);
467 if((result = lame_init_params(codec->lame_global)) < 0)
468 printf("encode: lame_init_params returned %d\n", result);
469 codec->encoded_header = mpeg3_new_layer();
470 if(file->use_avi)
471 trak->mdia.minf.stbl.stsd.table[0].sample_size = 0;
475 // Stack input on end of buffer
476 if(new_size > codec->input_allocated)
478 float *new_input;
480 if(!codec->input)
481 codec->input = calloc(sizeof(float*), track_map->channels);
483 for(i = 0; i < track_map->channels; i++)
485 new_input = calloc(sizeof(float), new_size);
486 if(codec->input[i])
488 memcpy(new_input, codec->input[i], sizeof(float) * codec->input_size);
489 free(codec->input[i]);
491 codec->input[i] = new_input;
493 codec->input_allocated = new_size;
497 // Transfer to input buffers
498 if(input_i)
500 for(i = 0; i < track_map->channels; i++)
502 for(j = 0; j < samples; j++)
503 codec->input[i][j] = input_i[i][j];
506 else
507 if(input_f)
509 for(i = 0; i < track_map->channels; i++)
511 for(j = 0; j < samples; j++)
512 codec->input[i][j] = input_f[i][j] * 32767;
516 // Encode
517 allocate_output(codec, samples);
519 result = lame_encode_buffer_float(codec->lame_global,
520 codec->input[0],
521 (track_map->channels > 1) ? codec->input[1] : codec->input[0],
522 samples,
523 codec->encoder_output + codec->encoder_output_size,
524 codec->encoder_output_allocated - codec->encoder_output_size);
526 codec->encoder_output_size += result;
528 result = write_frames(file,
529 track_map,
530 trak,
531 codec,
532 track);
534 return result;
539 static int set_parameter(quicktime_t *file,
540 int track,
541 char *key,
542 void *value)
544 quicktime_audio_map_t *atrack = &(file->atracks[track]);
545 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
547 if(!strcasecmp(key, "mp3_bitrate"))
548 codec->bitrate = *(int*)value;
550 return 0;
555 static void flush(quicktime_t *file, int track)
557 int result = 0;
558 int64_t offset = quicktime_position(file);
559 quicktime_audio_map_t *track_map = &(file->atracks[track]);
560 quicktime_trak_t *trak = track_map->track;
561 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
563 if(codec->encode_initialized)
565 result = lame_encode_flush(codec->lame_global,
566 codec->encoder_output + codec->encoder_output_size,
567 codec->encoder_output_allocated - codec->encoder_output_size);
568 codec->encoder_output_size += result;
569 result = write_frames(file,
570 track_map,
571 trak,
572 codec,
573 track);
578 void quicktime_init_codec_mp3(quicktime_audio_map_t *atrack)
580 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
581 quicktime_mp3_codec_t *codec;
583 /* Init public items */
584 codec_base->priv = calloc(1, sizeof(quicktime_mp3_codec_t));
585 codec_base->delete_acodec = delete_codec;
586 codec_base->decode_audio = decode;
587 codec_base->encode_audio = encode;
588 codec_base->set_parameter = set_parameter;
589 codec_base->flush = flush;
590 codec_base->fourcc = QUICKTIME_MP3;
591 codec_base->title = "MP3";
592 codec_base->desc = "MP3 for video";
593 codec_base->wav_id = 0x55;
595 codec = codec_base->priv;
596 codec->bitrate = 256000;