allow ffmpeg video to resample curr_pos, add bluray format
[goodguy/history.git] / cinelerra-5.0 / quicktime / twos.c
1 #include "funcprotos.h"
2 #include "quicktime.h"
3 #include "twos.h"
4
5 /* =================================== private for twos */
6
7
8 typedef struct
9 {
10         char *work_buffer;
11         long buffer_size;
12         int little_endian;
13 } quicktime_twos_codec_t;
14
15 static int byte_order(void)
16 {                /* 1 if little endian */
17         int16_t byteordertest;
18         int byteorder;
19
20         byteordertest = 0x0001;
21         byteorder = *((unsigned char *)&byteordertest);
22         return byteorder;
23 }
24
25 static int get_work_buffer(quicktime_t *file, int track, long bytes)
26 {
27         quicktime_twos_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
28
29         if(codec->work_buffer && codec->buffer_size != bytes)
30         {
31                 free(codec->work_buffer);
32                 codec->work_buffer = 0;
33         }
34         
35         if(!codec->work_buffer) 
36         {
37                 codec->buffer_size = bytes;
38                 if(!(codec->work_buffer = malloc(bytes))) return 1;
39         }
40         return 0;
41 }
42
43 /* =================================== public for twos */
44
45 static void delete_codec(quicktime_audio_map_t *atrack)
46 {
47         quicktime_twos_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
48
49         if(codec->work_buffer) free(codec->work_buffer);
50         codec->work_buffer = 0;
51         codec->buffer_size = 0;
52         free(codec);
53 }
54
55 static int swap_bytes(char *buffer, long samples, int channels, int bits)
56 {
57         long i = 0;
58         char byte1, *buffer1, *buffer2;
59
60         if(!byte_order()) return 0;
61
62         switch(bits) {
63                 case 16:
64                         buffer1 = buffer;
65                         buffer2 = buffer + 1;
66                         while(i < samples * channels * 2) {
67                                 byte1 = buffer2[i];
68                                 buffer2[i] = buffer1[i];
69                                 buffer1[i] = byte1;
70                                 i += 2;
71                         }
72                         break;
73
74                 case 24:
75                         buffer1 = buffer;
76                         buffer2 = buffer + 2;
77                         while(i < samples * channels * 3) {
78                                 byte1 = buffer2[i];
79                                 buffer2[i] = buffer1[i];
80                                 buffer1[i] = byte1;
81                                 i += 3;
82                         }
83                         break;
84
85                 default: break;
86         }
87         return 0;
88 }
89
90
91 static int decode(quicktime_t *file, 
92                                         int16_t *output_i, 
93                                         float *output_f, 
94                                         long samples, 
95                                         int track, 
96                                         int channel)
97 {
98         int result = 0;
99         long i, j;
100         quicktime_audio_map_t *track_map = &(file->atracks[track]);
101         quicktime_twos_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
102         int step = track_map->channels * quicktime_audio_bits(file, track) / 8;
103
104         get_work_buffer(file, track, samples * step);
105 /*
106  * printf("decode 1 %d\n", quicktime_audio_bits(file, track));
107  * sleep(1);
108  */
109         result = !quicktime_read_audio(file, codec->work_buffer, samples, track);
110
111
112 /* Undo increment since this is done in codecs.c */
113         track_map->current_position -= samples;
114
115 /* Handle AVI byte order */
116         if(file->use_avi)
117                 swap_bytes(codec->work_buffer, 
118                         samples, 
119                         track_map->channels, 
120                         quicktime_audio_bits(file, track));
121
122         switch(quicktime_audio_bits(file, track))
123         {
124                 case 8:
125                         if(output_i && !result)
126                         {
127                                 for(i = 0, j = channel; i < samples; i++)
128                                 {
129                                         if(file->use_avi)
130                                                 output_i[i] = (int16_t)(((unsigned char)codec->work_buffer[j]) << 8) - 
131                                                         0x7fff;
132                                         else
133                                                 output_i[i] = ((int16_t)codec->work_buffer[j]) << 8;
134                                         j += step;
135                                 }
136                         }
137                         else
138                         if(output_f && !result)
139                         {
140                                 for(i = 0, j = channel; i < samples; i++)
141                                 {
142                                         if(file->use_avi)
143                                                 output_f[i] = ((float)((unsigned char)codec->work_buffer[j]) - 0x7f) / 
144                                                         0x7f;
145                                         else
146                                                 output_f[i] = ((float)codec->work_buffer[j]) / 0x7f;
147                                         j += step;
148                                 }
149                         }
150                         break;
151                 
152                 case 16:
153                         if(output_i && !result)
154                         {
155                                 for(i = 0, j = channel * 2; i < samples; i++)
156                                 {
157                                         if(codec->little_endian)
158                                         {
159                                                 output_i[i] = ((int16_t)codec->work_buffer[j + 1]) << 8 |
160                                                                                 ((unsigned char)codec->work_buffer[j]);
161                                         }
162                                         else
163                                         {
164                                                 output_i[i] = ((int16_t)codec->work_buffer[j]) << 8 |
165                                                                                 ((unsigned char)codec->work_buffer[j + 1]);
166                                         }
167                                         j += step;
168                                 }
169                         }
170                         else
171                         if(output_f && !result)
172                         {
173                                 for(i = 0, j = channel * 2; i < samples; i++)
174                                 {
175                                         if(codec->little_endian)
176                                         {
177                                                 output_f[i] = (float)((((int16_t)codec->work_buffer[j + 1]) << 8) |
178                                                                         ((unsigned char)codec->work_buffer[j])) / 0x7fff;
179                                         }
180                                         else
181                                         {
182                                                 output_f[i] = (float)((((int16_t)codec->work_buffer[j]) << 8) |
183                                                                         ((unsigned char)codec->work_buffer[j + 1])) / 0x7fff;
184                                         }
185                                         
186                                         j += step;
187                                 }
188                         }
189                         break;
190                 
191                 case 24:
192                         if(output_i && !result)
193                         {
194                                 for(i = 0, j = channel * 3; i < samples; i++)
195                                 {
196                                         output_i[i] = (((int16_t)codec->work_buffer[j]) << 8) | 
197                                                                         ((unsigned char)codec->work_buffer[j + 1]);
198                                         j += step;
199                                 }
200                         }
201                         else
202                         if(output_f && !result)
203                         {
204                                 for(i = 0, j = channel * 3; i < samples; i++)
205                                 {
206                                         output_f[i] = (float)((((int)codec->work_buffer[j]) << 16) | 
207                                                                         (((unsigned char)codec->work_buffer[j + 1]) << 8) |
208                                                                         ((unsigned char)codec->work_buffer[j + 2])) / 0x7fffff;
209                                         j += step;
210                                 }
211                         }
212                         break;
213                 
214                 default:
215                         break;
216         }
217
218
219         return result;
220 }
221
222 #define CLAMP(x, y, z) ((x) = ((x) <  (y) ? (y) : ((x) > (z) ? (z) : (x))))
223
224 static int encode(quicktime_t *file, 
225                                                         int16_t **input_i, 
226                                                         float **input_f, 
227                                                         int track, 
228                                                         long samples)
229 {
230         int result = 0;
231         long i, j;
232         quicktime_audio_map_t *track_map = &(file->atracks[track]);
233         quicktime_twos_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
234         int step = track_map->channels * quicktime_audio_bits(file, track) / 8;
235         int sample;
236         float sample_f;
237
238         get_work_buffer(file, track, samples * step);
239
240         if(input_i)
241         {
242                 for(i = 0; i < track_map->channels; i++)
243                 {
244                         switch(quicktime_audio_bits(file, track))
245                         {
246                                 case 8:
247                                         for(j = 0; j < samples; j++)
248                                         {
249                                                 sample = input_i[i][j] >> 8;
250                                                 codec->work_buffer[j * step + i] = sample;
251                                         }
252                                         break;
253                                 case 16:
254                                         for(j = 0; j < samples; j++)
255                                         {
256                                                 sample = input_i[i][j];
257                                                 codec->work_buffer[j * step + i * 2] = ((unsigned int)sample & 0xff00) >> 8;
258                                                 codec->work_buffer[j * step + i * 2 + 1] = ((unsigned int)sample) & 0xff;
259                                         }
260                                         break;
261                                 case 24:
262                                         for(j = 0; j < samples; j++)
263                                         {
264                                                 sample = input_i[i][j];
265                                                 codec->work_buffer[j * step + i * 3] = ((unsigned int)sample & 0xff00) >> 8;
266                                                 codec->work_buffer[j * step + i * 3 + 1] = ((unsigned int)sample & 0xff);
267                                                 codec->work_buffer[j * step + i * 3 + 2] = 0;
268                                         }
269                                         break;
270                         }
271                 }
272         }
273         else
274         {
275                 for(i = 0; i < track_map->channels; i++)
276                 {
277                         switch(quicktime_audio_bits(file, track))
278                         {
279                                 case 8:
280                                         for(j = 0; j < samples; j++)
281                                         {
282                                                 sample_f = input_f[i][j];
283                                                 if(sample_f < 0)
284                                                         sample = (int)(sample_f * 0x7f - 0.5);
285                                                 else
286                                                         sample = (int)(sample_f * 0x7f + 0.5);
287                                                 CLAMP(sample, -0x7f, 0x7f);
288                                                 codec->work_buffer[j * step + i] = sample;
289                                         }
290                                         break;
291                                 case 16:
292                                         for(j = 0; j < samples; j++)
293                                         {
294                                                 sample_f = input_f[i][j];
295                                                 if(sample_f < 0)
296                                                         sample = (int)(sample_f * 0x7fff - 0.5);
297                                                 else
298                                                         sample = (int)(sample_f * 0x7fff + 0.5);
299                                                 CLAMP(sample, -0x7fff, 0x7fff);
300                                                 codec->work_buffer[j * step + i * 2] = ((unsigned int)sample & 0xff00) >> 8;
301                                                 codec->work_buffer[j * step + i * 2 + 1] = ((unsigned int)sample) & 0xff;
302                                         }
303                                         break;
304                                 case 24:
305                                         for(j = 0; j < samples; j++)
306                                         {
307                                                 sample_f = input_f[i][j];
308                                                 if(sample_f < 0)
309                                                         sample = (int)(sample_f * 0x7fffff - 0.5);
310                                                 else
311                                                         sample = (int)(sample_f * 0x7fffff + 0.5);
312                                                 CLAMP(sample, -0x7fffff, 0x7fffff);
313                                                 codec->work_buffer[j * step + i * 3] = ((unsigned int)sample & 0xff0000) >> 16;
314                                                 codec->work_buffer[j * step + i * 3 + 1] = ((unsigned int)sample & 0xff00) >> 8;
315                                                 codec->work_buffer[j * step + i * 3 + 2] = ((unsigned int)sample) & 0xff;
316                                         }
317                                         break;
318                         }
319                 }
320         }
321
322 /* Handle AVI byte order */
323         if(file->use_avi)
324                 swap_bytes(codec->work_buffer, 
325                         samples, 
326                         track_map->channels, 
327                         quicktime_audio_bits(file, track));
328
329         result = quicktime_write_audio(file, codec->work_buffer, samples, track);
330
331         return result;
332 }
333
334 static void init_common(quicktime_audio_map_t *atrack, 
335         char *fourcc,
336         char *title,
337         char *description)
338 {
339         quicktime_twos_codec_t *codec;
340         quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
341
342 /* Init public items */
343         codec_base->delete_acodec = delete_codec;
344         codec_base->decode_audio = decode;
345         codec_base->encode_audio = encode;
346         codec_base->fourcc = fourcc;
347         codec_base->title = title;
348         codec_base->desc = description;
349         codec_base->wav_id = 0x01;
350
351 /* Init private items */
352         codec = codec_base->priv = calloc(1, sizeof(quicktime_twos_codec_t));
353         codec->work_buffer = 0;
354         codec->buffer_size = 0;
355         if(quicktime_match_32(fourcc, QUICKTIME_SOWT)) 
356                 codec->little_endian = 1;
357 }
358
359 void quicktime_init_codec_twos(quicktime_audio_map_t *atrack)
360 {
361         init_common(atrack, QUICKTIME_TWOS, "Twos complement", "Twos complement");
362 }
363
364 void quicktime_init_codec_sowt(quicktime_audio_map_t *atrack)
365 {
366         init_common(atrack, QUICKTIME_SOWT, "Twos complement", "Twos complement");
367 }