r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / quicktime / qtmp3.c
blob8e3be88ea73f0ba39adb48db9ae4aa298d030cc8
1 #include "funcprotos.h"
3 #ifdef MMX
4 #define MMX_TEMP
5 #undef MMX
6 #endif
7 #include "lame.h"
9 #ifdef MMX_TEMP
10 #define MMX
11 #endif
14 #include "mpeg3private.h"
15 #include "mpeg3protos.h"
16 #include "quicktime.h"
17 #include "qtmp3.h"
19 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
21 #define OUTPUT_ALLOCATION 0x100000
23 //static FILE *test = 0;
25 typedef struct
27 // mp3 decoder
28 mpeg3_layer_t *mp3;
29 // Can't use same structure for header testing
30 mpeg3_layer_t *mp3_header;
31 unsigned char *packet_buffer;
32 int packet_allocated;
35 // Number of first sample in output relative to file
36 int64_t output_position;
37 // Number of samples in output buffer
38 long output_size;
39 // Number of samples allocated in output buffer
40 long output_allocated;
41 // Current reading position in file
42 int64_t chunk;
43 int decode_initialized;
44 float **output;
48 // mp3 encoder
49 lame_global_flags *lame_global;
50 // This calculates the number of samples per chunk
51 mpeg3_layer_t *encoded_header;
52 int encode_initialized;
53 float **input;
54 int input_size;
55 int input_allocated;
56 int bitrate;
57 unsigned char *encoder_output;
58 int encoder_output_size;
59 int encoder_output_allocated;
60 } quicktime_mp3_codec_t;
66 static int delete_codec(quicktime_audio_map_t *atrack)
68 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
69 if(codec->mp3) mpeg3_delete_layer(codec->mp3);
70 if(codec->mp3_header) mpeg3_delete_layer(codec->mp3_header);
71 if(codec->packet_buffer) free(codec->packet_buffer);
72 if(codec->output)
74 int i;
75 for(i = 0; i < atrack->channels; i++)
76 free(codec->output[i]);
77 free(codec->output);
80 if(codec->lame_global)
82 lame_close(codec->lame_global);
85 if(codec->input)
87 int i;
88 for(i = 0; i < atrack->channels; i++)
90 free(codec->input[i]);
92 free(codec->input);
95 if(codec->encoder_output)
96 free(codec->encoder_output);
98 if(codec->encoded_header)
99 mpeg3_delete_layer(codec->encoded_header);
101 free(codec);
103 return 0;
106 static int chunk_len(quicktime_t *file,
107 quicktime_mp3_codec_t *codec,
108 int64_t offset,
109 int64_t next_chunk)
111 int result = 0;
112 unsigned char header[4];
113 int accum = 0;
115 while(offset < next_chunk)
117 quicktime_set_position(file, offset);
118 result = !quicktime_read_data(file, (unsigned char*)&header, 4);
120 if(result)
122 return accum;
125 // Decode size of mp3 frame
126 result = mpeg3_layer_header(codec->mp3_header,
127 header);
129 // Invalid header
130 if(!result)
131 return accum;
132 else
133 // Valid header
135 accum += result;
136 offset += result;
137 quicktime_set_position(file, offset + result);
140 return accum;
152 static int decode(quicktime_t *file,
153 int16_t *output_i,
154 float *output_f,
155 long samples,
156 int track,
157 int channel)
159 int result = 0;
160 quicktime_audio_map_t *track_map = &(file->atracks[track]);
161 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
162 quicktime_trak_t *trak = track_map->track;
163 long current_position = track_map->current_position;
164 long end_position = current_position + samples;
165 float *pcm;
166 int i, j, k;
167 int64_t offset1;
168 int64_t offset2;
169 int chunk_size;
170 int new_size;
171 int frame_size;
172 int try = 0;
173 float **temp_output;
175 if(samples > OUTPUT_ALLOCATION)
176 printf("decode: can't read more than %d samples at a time.\n", OUTPUT_ALLOCATION);
179 //printf("decode 1\n");
180 if(output_i) bzero(output_i, sizeof(int16_t) * samples);
181 if(output_f) bzero(output_f, sizeof(float) * samples);
183 temp_output = malloc(sizeof(float*) * track_map->channels);
185 // Seeked outside output buffer's range or not initialized: restart
186 if(current_position < codec->output_position ||
187 current_position > codec->output_position + codec->output_size ||
188 !codec->decode_initialized)
190 quicktime_chunk_of_sample(&codec->output_position,
191 &codec->chunk,
192 trak,
193 current_position);
195 // We know the first mp3 packet in the chunk has a pcm_offset from the encoding.
196 codec->output_size = 0;
197 //printf("decode 1 %lld %d\n", codec->output_position, quicktime_chunk_samples(trak, codec->chunk));
198 codec->output_position = quicktime_sample_of_chunk(trak, codec->chunk);
199 //printf("decode 2 %lld\n", codec->output_position);
201 // Initialize and load initial buffer for decoding
202 if(!codec->decode_initialized)
204 int i;
205 codec->decode_initialized = 1;
206 codec->output = malloc(sizeof(float*) * track_map->channels);
207 for(i = 0; i < track_map->channels; i++)
209 codec->output[i] = malloc(sizeof(float) * OUTPUT_ALLOCATION);
211 codec->output_allocated = OUTPUT_ALLOCATION;
212 codec->mp3 = mpeg3_new_layer();
213 codec->mp3_header = mpeg3_new_layer();
217 // Decode chunks until output is big enough
218 while(codec->output_position + codec->output_size <
219 current_position + samples &&
220 try < 6)
222 // Decode a chunk
223 offset1 = quicktime_chunk_to_offset(file, trak, codec->chunk);
224 offset2 = quicktime_chunk_to_offset(file, trak, codec->chunk + 1);
226 if(offset2 == offset1) break;
228 chunk_size = chunk_len(file, codec, offset1, offset2);
230 if(codec->packet_allocated < chunk_size &&
231 codec->packet_buffer)
233 free(codec->packet_buffer);
234 codec->packet_buffer = 0;
237 if(!codec->packet_buffer)
239 codec->packet_buffer = calloc(1, chunk_size);
240 codec->packet_allocated = chunk_size;
243 quicktime_set_position(file, offset1);
244 result = !quicktime_read_data(file, codec->packet_buffer, chunk_size);
245 if(result) break;
247 for(i = 0; i < chunk_size; )
249 // Allocate more output
250 new_size = codec->output_size + MAXFRAMESAMPLES;
251 if(new_size > codec->output_allocated)
253 for(j = 0; j < track_map->channels; j++)
255 float *new_output = calloc(sizeof(float), new_size);
256 memcpy(new_output,
257 codec->output[j],
258 sizeof(float) * codec->output_size);
259 free(codec->output[j]);
260 codec->output[j] = new_output;
262 codec->output_allocated = new_size;
265 // Decode a frame
266 for(j = 0; j < track_map->channels; j++)
267 temp_output[j] = codec->output[j] + codec->output_size;
269 frame_size = mpeg3_layer_header(codec->mp3,
270 codec->packet_buffer + i);
272 result = mpeg3audio_dolayer3(codec->mp3,
273 codec->packet_buffer + i,
274 frame_size,
275 temp_output,
279 if(result)
281 codec->output_size += result;
282 result = 0;
283 try = 0;
285 else
287 try++;
290 i += frame_size;
293 codec->chunk++;
296 // Transfer region of output to argument
297 pcm = codec->output[channel];
298 if(output_i)
300 for(i = current_position - codec->output_position, j = 0;
301 j < samples && i < codec->output_size;
302 j++, i++)
304 int sample = pcm[i] * 32767;
305 CLAMP(sample, -32768, 32767);
306 output_i[j] = sample;
309 else
310 if(output_f)
312 for(i = current_position - codec->output_position, j = 0;
313 j < samples && i < codec->output_size;
314 j++, i++)
316 output_f[j] = pcm[i];
320 // Delete excess output
321 if(codec->output_size > OUTPUT_ALLOCATION)
323 int diff = codec->output_size - OUTPUT_ALLOCATION;
324 for(k = 0; k < track_map->channels; k++)
326 pcm = codec->output[k];
327 for(i = 0, j = diff; j < codec->output_size; i++, j++)
329 pcm[i] = pcm[j];
332 codec->output_size -= diff;
333 codec->output_position += diff;
336 free(temp_output);
337 //printf("decode 100\n");
338 return 0;
344 static int allocate_output(quicktime_mp3_codec_t *codec,
345 int samples)
347 int new_size = codec->encoder_output_size + samples * 4;
348 if(codec->encoder_output_allocated < new_size)
350 unsigned char *new_output = calloc(1, new_size);
352 if(codec->encoder_output)
354 memcpy(new_output,
355 codec->encoder_output,
356 codec->encoder_output_size);
357 free(codec->encoder_output);
359 codec->encoder_output = new_output;
360 codec->encoder_output_allocated = new_size;
367 // Empty the output buffer of frames
368 static int write_frames(quicktime_t *file,
369 quicktime_audio_map_t *track_map,
370 quicktime_trak_t *trak,
371 quicktime_mp3_codec_t *codec)
373 int result = 0;
374 int i, j;
375 int frames_end = 0;
376 quicktime_atom_t chunk_atom;
378 // Write to chunks
379 for(i = 0; i < codec->encoder_output_size - 4; )
381 unsigned char *header = codec->encoder_output + i;
382 int frame_size = mpeg3_layer_header(codec->encoded_header, header);
384 if(frame_size)
386 // Frame is finished before end of buffer
387 if(i + frame_size <= codec->encoder_output_size)
389 // Write the chunk
390 int64_t offset;
391 int frame_samples = mpeg3audio_dolayer3(codec->encoded_header,
392 header,
393 frame_size,
397 quicktime_write_chunk_header(file, trak, &chunk_atom);
398 result = !quicktime_write_data(file, header, frame_size);
399 // Knows not to save the chunksizes for audio
400 quicktime_write_chunk_footer(file,
401 trak,
402 track_map->current_chunk,
403 &chunk_atom,
404 frame_samples);
406 track_map->current_chunk++;
407 i += frame_size;
408 frames_end = i;
410 else
411 // Frame isn't finished before end of buffer.
413 frames_end = i;
414 break;
417 else
418 // Not the start of a frame. Skip it.
420 i++;
421 frames_end = i;
425 if(frames_end > 0)
427 for(i = frames_end, j = 0; i < codec->encoder_output_size; i++, j++)
429 codec->encoder_output[j] = codec->encoder_output[i];
431 codec->encoder_output_size -= frames_end;
433 return result;
441 static int encode(quicktime_t *file,
442 int16_t **input_i,
443 float **input_f,
444 int track,
445 long samples)
447 int result = 0;
448 quicktime_audio_map_t *track_map = &(file->atracks[track]);
449 quicktime_trak_t *trak = track_map->track;
450 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
451 int new_size = codec->input_size + samples;
452 int i, j;
453 int frames_end = 0;
455 if(!codec->encode_initialized)
457 codec->encode_initialized = 1;
458 codec->lame_global = lame_init();
459 lame_set_brate(codec->lame_global, codec->bitrate / 1000);
460 lame_set_quality(codec->lame_global, 0);
461 lame_set_in_samplerate(codec->lame_global,
462 trak->mdia.minf.stbl.stsd.table[0].sample_rate);
463 if((result = lame_init_params(codec->lame_global)) < 0)
464 printf("encode: lame_init_params returned %d\n", result);
465 codec->encoded_header = mpeg3_new_layer();
466 if(file->use_avi)
467 trak->mdia.minf.stbl.stsd.table[0].sample_size = 0;
471 // Stack input on end of buffer
472 if(new_size > codec->input_allocated)
474 float *new_input;
476 if(!codec->input)
477 codec->input = calloc(sizeof(float*), track_map->channels);
479 for(i = 0; i < track_map->channels; i++)
481 new_input = calloc(sizeof(float), new_size);
482 if(codec->input[i])
484 memcpy(new_input, codec->input[i], sizeof(float) * codec->input_size);
485 free(codec->input[i]);
487 codec->input[i] = new_input;
489 codec->input_allocated = new_size;
493 // Transfer to input buffers
494 if(input_i)
496 for(i = 0; i < track_map->channels; i++)
498 for(j = 0; j < samples; j++)
499 codec->input[i][j] = input_i[i][j];
502 else
503 if(input_f)
505 for(i = 0; i < track_map->channels; i++)
507 for(j = 0; j < samples; j++)
508 codec->input[i][j] = input_f[i][j] * 32767;
512 // Encode
513 allocate_output(codec, samples);
515 result = lame_encode_buffer_float(codec->lame_global,
516 codec->input[0],
517 (track_map->channels > 1) ? codec->input[1] : codec->input[0],
518 samples,
519 codec->encoder_output + codec->encoder_output_size,
520 codec->encoder_output_allocated - codec->encoder_output_size);
522 codec->encoder_output_size += result;
524 result = write_frames(file,
525 track_map,
526 trak,
527 codec);
529 return result;
534 static int set_parameter(quicktime_t *file,
535 int track,
536 char *key,
537 void *value)
539 quicktime_audio_map_t *atrack = &(file->atracks[track]);
540 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
542 if(!strcasecmp(key, "mp3_bitrate"))
543 codec->bitrate = *(int*)value;
545 return 0;
550 static void flush(quicktime_t *file, int track)
552 int result = 0;
553 int64_t offset = quicktime_position(file);
554 quicktime_audio_map_t *track_map = &(file->atracks[track]);
555 quicktime_trak_t *trak = track_map->track;
556 quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
558 if(codec->encode_initialized)
560 result = lame_encode_flush(codec->lame_global,
561 codec->encoder_output + codec->encoder_output_size,
562 codec->encoder_output_allocated - codec->encoder_output_size);
563 codec->encoder_output_size += result;
564 result = write_frames(file,
565 track_map,
566 trak,
567 codec);
572 void quicktime_init_codec_mp3(quicktime_audio_map_t *atrack)
574 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
575 quicktime_mp3_codec_t *codec;
577 /* Init public items */
578 codec_base->priv = calloc(1, sizeof(quicktime_mp3_codec_t));
579 codec_base->delete_acodec = delete_codec;
580 codec_base->decode_audio = decode;
581 codec_base->encode_audio = encode;
582 codec_base->set_parameter = set_parameter;
583 codec_base->flush = flush;
584 codec_base->fourcc = QUICKTIME_MP3;
585 codec_base->title = "MP3";
586 codec_base->desc = "MP3 for video";
587 codec_base->wav_id = 0x55;
589 codec = codec_base->priv;
590 codec->bitrate = 256000;