allow ffmpeg video to resample curr_pos, add bluray format
[goodguy/history.git] / cinelerra-5.0 / quicktime / qtmp3.c
1 #include "funcprotos.h"
2 #include "lame.h"
3 #include "libzmpeg3.h"
4 #include "quicktime.h"
5 #include "qtmp3.h"
6 #include <string.h>
7
8 #ifndef MAX
9 #define MAX(a, b) ((a) > (b) ? (a) : (b))
10 #endif
11
12 #ifndef MIN
13 #define MIN(a, b) ((a) < (b) ? (a) : (b))
14 #endif
15
16 #define CLAMP(x, y, z) ((x) = ((x) <  (y) ? (y) : ((x) > (z) ? (z) : (x))))
17
18 #define OUTPUT_ALLOCATION 0x100000
19
20 //static FILE *test = 0;
21
22 typedef struct
23 {
24 // mp3 decoder
25         mpeg3_layer_t *mp3;
26 // Number of first sample in output relative to file
27         int64_t output_position;
28 // Current reading position in file
29         int64_t chunk;
30         int decode_initialized;
31         float **output;
32
33 // mp3 encoder
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;
38         float **input;
39         int input_size;
40         int input_allocated;
41         int bitrate;
42         unsigned char *encoder_output;
43         int encoder_output_size;
44         int encoder_output_allocated;
45 } quicktime_mp3_codec_t;
46
47 static void delete_codec(quicktime_audio_map_t *atrack)
48 {
49         int i;
50         quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
51
52         if( codec->mp3 ) mpeg3_delete_layer(codec->mp3);
53         if( codec->output ) {
54                 for( i=0; i<atrack->channels; ++i ) free(codec->output[i]);
55                 free(codec->output);
56         }
57         if( codec->lame_global )
58                 lame_close(codec->lame_global);
59         if( codec->input ) {
60                 for( i=0; i<atrack->channels; ++i ) free(codec->input[i]);
61                 free(codec->input);
62         }
63         if( codec->encoder_output ) free(codec->encoder_output);
64         if( codec->encoded_header )
65                 mpeg3_delete_layer(codec->encoded_header);
66         free(codec);
67 }
68
69 static int decode(quicktime_t *file,
70         int16_t *output_i, float *output_f, 
71         long samples, int track, int channel)
72 {
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;
80
81         if(output_i) bzero(output_i, sizeof(int16_t) * samples);
82         if(output_f) bzero(output_f, sizeof(float) * samples);
83
84         if( quicktime_limit_samples(samples) ) return 1;
85
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();
94         }
95
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);
101         }
102
103         retry = 64;
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);
108                 int frame_size = 0;
109                 while( bfr_sz >= 4 ) {
110                         frame_size = mpeg3_layer_header(codec->mp3, bfr);
111                         if( frame_size ) break;
112                         ++bfr;  --bfr_sz;
113                 }
114                 if( !frame_size ) {
115                         if( quicktime_read_vbr(file, track_map) ) break;
116                         --retry;  continue;
117                 }
118
119 // shift out data before frame header
120                 i = bfr - quicktime_vbr_input(vbr);
121                 if( i > 0 ) quicktime_shift_vbr(track_map, i);
122
123 // collect frame data
124                 while( quicktime_vbr_input_size(vbr) < frame_size && retry >= 0 ) {
125                         if( quicktime_read_vbr(file, track_map) ) break;
126                         --retry;
127                 }
128                 if( retry < 0  ) break;
129                 if( quicktime_vbr_input_size(vbr) < frame_size ) break;
130
131 // decode frame
132                 result = mpeg3audio_dolayer3(codec->mp3, 
133                                 (char *)quicktime_vbr_input(vbr), frame_size,
134                                 codec->output, 1);
135                 if( result > 0 ) {
136                         quicktime_store_vbr_floatp(track_map, codec->output, result);
137                         codec->output_position += result;
138                         retry = 64;
139                 }
140                 quicktime_shift_vbr(track_map, frame_size);
141         }
142
143         if(output_i)
144                 quicktime_copy_vbr_int16(vbr, current_position,
145                         samples, output_i, channel);
146         if(output_f)
147                 quicktime_copy_vbr_float(vbr, current_position,
148                         samples, output_f, channel);
149         return 0;
150 }
151
152
153
154
155 static int allocate_output(quicktime_mp3_codec_t *codec,
156         int samples)
157 {
158         int new_size = codec->encoder_output_size + samples * 4;
159         if(codec->encoder_output_allocated < new_size)
160         {
161                 unsigned char *new_output = calloc(1, new_size);
162
163                 if(codec->encoder_output)
164                 {
165                         memcpy(new_output, 
166                                 codec->encoder_output, 
167                                 codec->encoder_output_size);
168                         free(codec->encoder_output);
169                 }
170                 codec->encoder_output = new_output;
171                 codec->encoder_output_allocated = new_size;
172         }
173         return 0;
174 }
175
176
177
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,
183         int track)
184 {
185         int frame_end = codec->encoder_output_size;
186         unsigned char *bfr = codec->encoder_output;
187         int frame_limit = frame_end - 4;
188         int frame_samples;
189         int result = 0;
190         int i = 0;
191         
192 // Write to chunks
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;
201                 i += frame_size;
202 // Write the chunk
203                 frame_samples = mpeg3audio_dolayer3(codec->encoded_header, 
204                         hdr, frame_size, 0, 0);
205 // Frame is a dud
206                 if( !frame_samples ) continue;
207                 result = quicktime_write_vbr_frame(file, track,
208                         hdr, frame_size, frame_samples);
209                 track_map->current_chunk++;
210         }
211
212 // move any frame fragment down
213         if( i > 0 ) {
214                 int j = 0;
215                 codec->encoder_output_size -= i;
216                 while( i < frame_end ) bfr[j++] = bfr[i++];
217         }
218
219         return result;
220 }
221
222
223
224
225
226
227 static int encode(quicktime_t *file, 
228         int16_t **input_i, float **input_f, int track, long samples)
229 {
230         int result = 0;
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;
235         int i, j;
236
237         if(!codec->encode_initialized)
238         {
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();
248                 if(file->use_avi)
249                         trak->mdia.minf.stbl.stsd.table[0].sample_size = 0;
250         }
251
252
253 // Stack input on end of buffer
254         if(new_size > codec->input_allocated)
255         {
256                 float *new_input;
257
258                 if(!codec->input) 
259                         codec->input = calloc(sizeof(float*), track_map->channels);
260
261                 for(i = 0; i < track_map->channels; i++)
262                 {
263                         new_input = calloc(sizeof(float), new_size);
264                         if(codec->input[i])
265                         {
266                                 memcpy(new_input, codec->input[i], sizeof(float) * codec->input_size);
267                                 free(codec->input[i]);
268                         }
269                         codec->input[i] = new_input;
270                 }
271                 codec->input_allocated = new_size;
272         }
273
274
275 // Transfer to input buffers
276         if(input_i)
277         {
278                 for(i = 0; i < track_map->channels; i++)
279                 {
280                         for(j = 0; j < samples; j++)
281                                 codec->input[i][j] = input_i[i][j];
282                 }
283         }
284         else
285         if(input_f)
286         {
287                 for(i = 0; i < track_map->channels; i++)
288                 {
289                         for(j = 0; j < samples; j++)
290                                 codec->input[i][j] = input_f[i][j] * 32767;
291                 }
292         }
293
294 // Encode
295         allocate_output(codec, samples);
296
297         result = lame_encode_buffer_float(codec->lame_global,
298                 codec->input[0],
299                 (track_map->channels > 1) ? codec->input[1] : codec->input[0],
300                 samples,
301                 codec->encoder_output + codec->encoder_output_size,
302                 codec->encoder_output_allocated - codec->encoder_output_size);
303
304         codec->encoder_output_size += result;
305
306         result = write_frames(file, track_map, trak, codec, track);
307         return result;
308 }
309
310
311
312 static int set_parameter(quicktime_t *file, 
313                 int track, 
314                 char *key, 
315                 void *value)
316 {
317         quicktime_audio_map_t *atrack = &(file->atracks[track]);
318         quicktime_mp3_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
319
320         if(!strcasecmp(key, "mp3_bitrate"))
321                 codec->bitrate = *(int*)value;
322
323         return 0;
324 }
325
326
327
328 static void flush(quicktime_t *file, int track)
329 {
330         int result = 0;
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;
334
335         if(codec->encode_initialized)
336         {
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);
342         }
343 }
344
345
346 void quicktime_init_codec_mp3(quicktime_audio_map_t *atrack)
347 {
348         quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
349         quicktime_mp3_codec_t *codec;
350
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;
362
363         codec = codec_base->priv;
364         codec->bitrate = 256000;
365 }
366
367
368
369