initial commit
[goodguy/history.git] / cinelerra-5.0 / quicktime / codecs.c
1 #include "colormodels.h"
2 #include "funcprotos.h"
3 #include "quicktime.h"
4 #include <string.h>
5
6 static void delete_vcodec_stub(quicktime_video_map_t *vtrack)
7 {
8         printf("delete_vcodec_stub called\n");
9 }
10
11 static void delete_acodec_stub(quicktime_audio_map_t *atrack)
12 {
13         printf("delete_acodec_stub called\n");
14 }
15
16 static int decode_video_stub(quicktime_t *file, 
17                                 unsigned char **row_pointers, 
18                                 int track)
19 {
20         printf("decode_video_stub called\n");
21         return 1;
22 }
23
24 static int encode_video_stub(quicktime_t *file, 
25                                 unsigned char **row_pointers, 
26                                 int track)
27 {
28         printf("encode_video_stub called\n");
29         return 1;
30 }
31
32 static int decode_audio_stub(quicktime_t *file, 
33                                         int16_t *output_i, 
34                                         float *output_f, 
35                                         long samples, 
36                                         int track, 
37                                         int channel)
38 {
39         printf("decode_audio_stub called\n");
40         return 1;
41 }
42
43 static int encode_audio_stub(quicktime_t *file, 
44                                 int16_t **input_i, 
45                                 float **input_f, 
46                                 int track, 
47                                 long samples)
48 {
49         printf("encode_audio_stub called\n");
50         return 1;
51 }
52
53
54 static int reads_colormodel_stub(quicktime_t *file, 
55                 int colormodel, 
56                 int track)
57 {
58         return (colormodel == BC_RGB888);
59 }
60
61 static int writes_colormodel_stub(quicktime_t *file, 
62                 int colormodel, 
63                 int track)
64 {
65         return (colormodel == BC_RGB888);
66 }
67
68 static void flush_codec_stub(quicktime_t *file, int track)
69 {
70 }
71
72 /* Convert Microsoft audio id to codec */
73 void quicktime_id_to_codec(char *result, int id)
74 {
75         switch(id)
76         {
77                 case 0x55:
78                         memcpy(result, QUICKTIME_MP3, 4);
79                         break;
80                 case 0x161:
81                         memcpy(result, QUICKTIME_WMA, 4);
82                         break;
83                 default:
84                         printf("quicktime_id_to_codec: unknown audio id: 0x%06x\n", id);
85                         break;
86         }
87 }
88
89 int quicktime_codec_to_id(char *codec)
90 {
91         if(quicktime_match_32(codec, QUICKTIME_MP3))
92                 return 0x55;
93         else
94         if(quicktime_match_32(codec, QUICKTIME_WMA))
95                 return 0x161;
96         else
97                 printf("quicktime_codec_to_id: unknown codec %c%c%c%c\n",
98                         codec[0], codec[1], codec[2], codec[3]);
99         return 0;
100 }
101
102
103 quicktime_codec_t* quicktime_new_codec()
104 {
105         quicktime_codec_t *codec = malloc(sizeof(*codec));
106         if( !codec ) return 0;
107         memset(codec, 0, sizeof(*codec));
108         codec->delete_vcodec = delete_vcodec_stub;
109         codec->delete_acodec = delete_acodec_stub;
110         codec->decode_video = decode_video_stub;
111         codec->encode_video = encode_video_stub;
112         codec->decode_audio = decode_audio_stub;
113         codec->encode_audio = encode_audio_stub;
114         codec->reads_colormodel = reads_colormodel_stub;
115         codec->writes_colormodel = writes_colormodel_stub;
116         codec->flush = flush_codec_stub;
117         return codec;
118 }
119
120 void quicktime_del_codec(quicktime_codec_t *codec)
121 {
122         if( codec ) free(codec);
123 }
124
125 int new_vcodec(quicktime_video_map_t *vtrack)
126 {
127         int result = quicktime_find_vcodec(vtrack);
128         if(result) {
129                 char *compressor = vtrack->track->mdia.minf.stbl.stsd.table[0].format;
130                 fprintf(stderr, 
131                         "new_vcodec: couldn't find codec for \"%c%c%c%c\"\n",
132                         compressor[0], compressor[1], compressor[2], compressor[3]);
133                 vtrack->codec = 0;
134                 return 1;
135         }
136         return 0;
137 }
138
139 int new_acodec(quicktime_audio_map_t *atrack)
140 {
141         int result = quicktime_find_acodec(atrack);
142         if(result) {
143                 char *compressor = atrack->track->mdia.minf.stbl.stsd.table[0].format;
144                 fprintf(stderr, 
145                         "new_acodec: couldn't find codec for \"%c%c%c%c\"\n",
146                         compressor[0], compressor[1], compressor[2], compressor[3]);
147                 atrack->codec = 0;
148                 return 1;
149         }
150         return 0;
151 }
152
153 int quicktime_init_vcodec(quicktime_video_map_t *vtrack)
154 {
155         int result = new_vcodec(vtrack);
156         return result;
157 }
158
159 int quicktime_init_acodec(quicktime_audio_map_t *atrack)
160 {
161         int result = new_acodec(atrack);
162         return result;
163 }
164
165
166 int quicktime_delete_vcodec(quicktime_video_map_t *vtrack)
167 {
168         if(vtrack->codec)
169         {
170                 quicktime_codec_t *codec_base = vtrack->codec;
171                 if(codec_base->priv)
172                         codec_base->delete_vcodec(vtrack);
173                 free(vtrack->codec);
174         }
175         vtrack->codec = 0;
176         return 0;
177 }
178
179 int quicktime_delete_acodec(quicktime_audio_map_t *atrack)
180 {
181         if(atrack->codec)
182         {
183                 quicktime_codec_t *codec_base = atrack->codec;
184                 if(codec_base->priv)
185                         codec_base->delete_acodec(atrack);
186                 free(atrack->codec);
187         }
188         atrack->codec = 0;
189         return 0;
190 }
191
192 int quicktime_supported_video(quicktime_t *file, int track)
193 {
194         if(track < file->total_vtracks)
195         {
196                 quicktime_video_map_t *video_map = &file->vtracks[track];
197
198                 if(video_map->codec)
199                         return 1;
200                 else
201                         return 0;
202         }
203         return 0;
204 }
205
206 int quicktime_supported_audio(quicktime_t *file, int track)
207 {
208         if(track < file->total_atracks)
209         {
210                 quicktime_audio_map_t *audio_map = &file->atracks[track];
211                 if(audio_map->codec)
212                         return 1;
213                 else
214                         return 0;
215         }
216         return 0;
217         
218 }
219
220
221 long quicktime_decode_video(quicktime_t *file, 
222         unsigned char **row_pointers, 
223         int track)
224 {
225         int result;
226
227         if(track < 0 || track >= file->total_vtracks)
228         {
229                 fprintf(stderr, "quicktime_decode_video: track %d out of range %d - %d\n",
230                         track,
231                         0,
232                         file->total_vtracks);
233                 return 1;
234         }
235
236 /* Get dimensions from first video track */
237         if(!file->do_scaling)
238         {
239                 quicktime_video_map_t *video_map = &file->vtracks[track];
240                 quicktime_trak_t *trak = video_map->track;
241                 int track_width = trak->tkhd.track_width;
242                 int track_height = trak->tkhd.track_height;
243
244                 file->in_x = 0;
245                 file->in_y = 0;
246                 file->in_w = track_width;
247                 file->in_h = track_height;
248                 file->out_w = track_width;
249                 file->out_h = track_height;
250         }
251
252         result = ((quicktime_codec_t*)file->vtracks[track].codec)->decode_video(file, 
253                 row_pointers, 
254                 track);
255         file->vtracks[track].current_position++;
256         return result;
257 }
258
259 void quicktime_set_parameter(quicktime_t *file, const char *key, void *value)
260 {
261         int i;
262         for(i = 0; i < file->total_vtracks; i++)
263         {
264                 quicktime_codec_t *codec = (quicktime_codec_t*)file->vtracks[i].codec;
265                 if(codec)
266                         if(codec->set_parameter) codec->set_parameter(file, i,(char*)key, value);
267         }
268
269         for(i = 0; i < file->total_atracks; i++)
270         {
271                 quicktime_codec_t *codec = (quicktime_codec_t*)file->atracks[i].codec;
272                 if(codec)
273                         if(codec->set_parameter) codec->set_parameter(file, i,(char*)key, value);
274         }
275 }
276
277 int quicktime_encode_video(quicktime_t *file, 
278         unsigned char **row_pointers, 
279         int track)
280 {
281         int result;
282         result = ((quicktime_codec_t*)file->vtracks[track].codec)->encode_video(file, row_pointers, track);
283         file->vtracks[track].current_position++;
284         return result;
285 }
286
287
288 int quicktime_decode_audio(quicktime_t *file, 
289                                 int16_t *output_i, 
290                                 float *output_f, 
291                                 long samples, 
292                                 int channel)
293 {
294         int quicktime_track, quicktime_channel;
295         int result = 1;
296
297         quicktime_channel_location(file, &quicktime_track, &quicktime_channel, channel);
298         result = ((quicktime_codec_t*)file->atracks[quicktime_track].codec)->decode_audio(file, 
299                                 output_i, 
300                                 output_f, 
301                                 samples, 
302                                 quicktime_track, 
303                                 quicktime_channel);
304         file->atracks[quicktime_track].current_position += samples;
305
306         return result;
307 }
308
309 /* Since all channels are written at the same time: */
310 /* Encode using the compressor for the first audio track. */
311 /* Which means all the audio channels must be on the same track. */
312
313 int quicktime_encode_audio(quicktime_t *file, int16_t **input_i, float **input_f, long samples)
314 {
315         int result = 1;
316         //char *compressor = quicktime_audio_compressor(file, 0);
317
318         result = ((quicktime_codec_t*)file->atracks[0].codec)->encode_audio(file, 
319                 input_i, 
320                 input_f,
321                 0, 
322                 samples);
323         file->atracks[0].current_position += samples;
324
325         return result;
326 }
327
328 int quicktime_reads_cmodel(quicktime_t *file, 
329         int colormodel, 
330         int track)
331 {
332         int result = ((quicktime_codec_t*)file->vtracks[track].codec)->reads_colormodel(file, colormodel, track);
333         return result;
334 }
335
336 int quicktime_writes_cmodel(quicktime_t *file, 
337         int colormodel, 
338         int track)
339 {
340         return ((quicktime_codec_t*)file->vtracks[track].codec)->writes_colormodel(file, colormodel, track);
341 }
342
343 /* Compressors that can only encode a window at a time */
344 /* need to flush extra data here. */
345
346 int quicktime_flush_acodec(quicktime_t *file, int track)
347 {
348         ((quicktime_codec_t*)file->atracks[track].codec)->flush(file, track);
349         return 0;
350 };
351
352 void quicktime_flush_vcodec(quicktime_t *file, int track)
353 {
354         ((quicktime_codec_t*)file->vtracks[track].codec)->flush(file, track);
355 }
356
357 int64_t quicktime_samples_to_bytes(quicktime_trak_t *track, long samples)
358 {
359         char *compressor = track->mdia.minf.stbl.stsd.table[0].format;
360         int channels = track->mdia.minf.stbl.stsd.table[0].channels;
361
362         if(quicktime_match_32(compressor, QUICKTIME_DV))
363                 return (int64_t)samples * track->mdia.minf.stbl.stsz.sample_size;
364
365         if(quicktime_match_32(compressor, QUICKTIME_IMA4)) 
366                 return samples * channels;
367
368         if(quicktime_match_32(compressor, QUICKTIME_ULAW)) 
369                 return samples * channels;
370
371 /* Default use the sample size specification for TWOS and RAW */
372         return samples * channels * track->mdia.minf.stbl.stsd.table[0].sample_size / 8;
373 }
374
375 int quicktime_codecs_flush(quicktime_t *file)
376 {
377         int result = 0;
378         int i;
379         if(!file->wr) return result;
380
381         if(file->total_atracks)
382         {
383                 for(i = 0; i < file->total_atracks && !result; i++)
384                 {
385                         quicktime_flush_acodec(file, i);
386                 }
387         }
388
389         if(file->total_vtracks)
390         {
391                 for(i = 0; i < file->total_vtracks && !result; i++)
392                 {
393                         quicktime_flush_vcodec(file, i);
394                 }
395         }
396         return result;
397 }
398