Merge branch 'ct' of git.pipapo.org:cinelerra-ct into ct
[cinelerra_cv/ct.git] / quicktime / codecs.c
blobc8bd4a6e5b5a2fc772af0b0e31f51da14d647ca8
1 #include "colormodels.h"
2 #include "funcprotos.h"
3 #include "quicktime.h"
4 #include <string.h>
6 static int delete_vcodec_stub(quicktime_video_map_t *vtrack)
8 printf("delete_vcodec_stub called\n");
9 return 0;
12 static int delete_acodec_stub(quicktime_audio_map_t *atrack)
14 printf("delete_acodec_stub called\n");
15 return 0;
18 static int decode_video_stub(quicktime_t *file,
19 unsigned char **row_pointers,
20 int track)
22 printf("decode_video_stub called\n");
23 return 1;
26 static int encode_video_stub(quicktime_t *file,
27 unsigned char **row_pointers,
28 int track)
30 printf("encode_video_stub called\n");
31 return 1;
34 static int decode_audio_stub(quicktime_t *file,
35 int16_t *output_i,
36 float *output_f,
37 long samples,
38 int track,
39 int channel)
41 printf("decode_audio_stub called\n");
42 return 1;
45 static int encode_audio_stub(quicktime_t *file,
46 int16_t **input_i,
47 float **input_f,
48 int track,
49 long samples)
51 printf("encode_audio_stub called\n");
52 return 1;
56 static int reads_colormodel_stub(quicktime_t *file,
57 int colormodel,
58 int track)
60 return (colormodel == BC_RGB888);
63 static int writes_colormodel_stub(quicktime_t *file,
64 int colormodel,
65 int track)
67 return (colormodel == BC_RGB888);
70 static void flush_codec_stub(quicktime_t *file, int track)
74 /* Convert Microsoft audio id to codec */
75 void quicktime_id_to_codec(char *result, int id)
77 switch(id)
79 case 0x55:
80 memcpy(result, QUICKTIME_MP3, 4);
81 break;
82 case 0x161:
83 memcpy(result, QUICKTIME_WMA, 4);
84 break;
85 default:
86 printf("quicktime_id_to_codec: unknown audio id: %p\n", id);
87 break;
91 int quicktime_codec_to_id(char *codec)
93 if(quicktime_match_32(codec, QUICKTIME_MP3))
94 return 0x55;
95 else
96 if(quicktime_match_32(codec, QUICKTIME_WMA))
97 return 0x161;
98 else
99 printf("quicktime_codec_to_id: unknown codec %c%c%c%c\n", codec[0], codec[1], codec[2], codec[3]);
103 static quicktime_codec_t* new_codec()
105 quicktime_codec_t *codec = calloc(1, sizeof(quicktime_codec_t));
106 codec->delete_vcodec = delete_vcodec_stub;
107 codec->delete_acodec = delete_acodec_stub;
108 codec->decode_video = decode_video_stub;
109 codec->encode_video = encode_video_stub;
110 codec->decode_audio = decode_audio_stub;
111 codec->encode_audio = encode_audio_stub;
112 codec->reads_colormodel = reads_colormodel_stub;
113 codec->writes_colormodel = writes_colormodel_stub;
114 codec->flush = flush_codec_stub;
115 return codec;
118 int new_vcodec(quicktime_video_map_t *vtrack)
120 quicktime_codec_t *codec_base = vtrack->codec = new_codec();
121 char *compressor = vtrack->track->mdia.minf.stbl.stsd.table[0].format;
122 int result = quicktime_find_vcodec(vtrack);
124 if(result)
126 fprintf(stderr,
127 "new_vcodec: couldn't find codec for \"%c%c%c%c\"\n",
128 compressor[0],
129 compressor[1],
130 compressor[2],
131 compressor[3]);
132 free(codec_base);
133 vtrack->codec = 0;
134 return 1;
137 return 0;
140 int new_acodec(quicktime_audio_map_t *atrack)
142 quicktime_codec_t *codec_base = atrack->codec = new_codec();
143 char *compressor = atrack->track->mdia.minf.stbl.stsd.table[0].format;
144 int result = quicktime_find_acodec(atrack);
146 if(result)
148 fprintf(stderr,
149 "new_acodec: couldn't find codec for \"%c%c%c%c\"\n",
150 compressor[0],
151 compressor[1],
152 compressor[2],
153 compressor[3]);
154 free(codec_base);
155 atrack->codec = 0;
156 return 1;
159 return 0;
162 int quicktime_init_vcodec(quicktime_video_map_t *vtrack)
164 int result = new_vcodec(vtrack);
165 return result;
168 int quicktime_init_acodec(quicktime_audio_map_t *atrack)
170 int result = new_acodec(atrack);
171 return result;
175 int quicktime_delete_vcodec(quicktime_video_map_t *vtrack)
177 if(vtrack->codec)
179 quicktime_codec_t *codec_base = vtrack->codec;
180 if(codec_base->priv)
181 codec_base->delete_vcodec(vtrack);
182 free(vtrack->codec);
184 vtrack->codec = 0;
185 return 0;
188 int quicktime_delete_acodec(quicktime_audio_map_t *atrack)
190 if(atrack->codec)
192 quicktime_codec_t *codec_base = atrack->codec;
193 if(codec_base->priv)
194 codec_base->delete_acodec(atrack);
195 free(atrack->codec);
197 atrack->codec = 0;
198 return 0;
201 int quicktime_supported_video(quicktime_t *file, int track)
203 if(track < file->total_vtracks)
205 quicktime_video_map_t *video_map = &file->vtracks[track];
207 if(video_map->codec)
208 return 1;
209 else
210 return 0;
212 return 0;
215 int quicktime_supported_audio(quicktime_t *file, int track)
217 if(track < file->total_atracks)
219 quicktime_audio_map_t *audio_map = &file->atracks[track];
220 if(audio_map->codec)
221 return 1;
222 else
223 return 0;
225 return 0;
230 long quicktime_decode_video(quicktime_t *file,
231 unsigned char **row_pointers,
232 int track)
234 int result;
236 if(track < 0 || track >= file->total_vtracks)
238 fprintf(stderr, "quicktime_decode_video: track %d out of range %d - %d\n",
239 track,
241 file->total_vtracks);
242 return 1;
245 /* Get dimensions from first video track */
246 if(!file->do_scaling)
248 quicktime_video_map_t *video_map = &file->vtracks[track];
249 quicktime_trak_t *trak = video_map->track;
250 int track_width = trak->tkhd.track_width;
251 int track_height = trak->tkhd.track_height;
253 file->in_x = 0;
254 file->in_y = 0;
255 file->in_w = track_width;
256 file->in_h = track_height;
257 file->out_w = track_width;
258 file->out_h = track_height;
261 result = ((quicktime_codec_t*)file->vtracks[track].codec)->decode_video(file,
262 row_pointers,
263 track);
264 file->vtracks[track].current_position++;
265 return result;
268 void quicktime_set_parameter(quicktime_t *file, char *key, void *value)
270 int i;
271 for(i = 0; i < file->total_vtracks; i++)
273 quicktime_codec_t *codec = (quicktime_codec_t*)file->vtracks[i].codec;
274 if(codec)
275 if(codec->set_parameter) codec->set_parameter(file, i, key, value);
278 for(i = 0; i < file->total_atracks; i++)
280 quicktime_codec_t *codec = (quicktime_codec_t*)file->atracks[i].codec;
281 if(codec)
282 if(codec->set_parameter) codec->set_parameter(file, i, key, value);
286 int quicktime_encode_video(quicktime_t *file,
287 unsigned char **row_pointers,
288 int track)
290 int result;
291 result = ((quicktime_codec_t*)file->vtracks[track].codec)->encode_video(file, row_pointers, track);
292 file->vtracks[track].current_position++;
293 return result;
297 int quicktime_decode_audio(quicktime_t *file,
298 int16_t *output_i,
299 float *output_f,
300 long samples,
301 int channel)
303 int quicktime_track, quicktime_channel;
304 int result = 1;
306 quicktime_channel_location(file, &quicktime_track, &quicktime_channel, channel);
307 result = ((quicktime_codec_t*)file->atracks[quicktime_track].codec)->decode_audio(file,
308 output_i,
309 output_f,
310 samples,
311 quicktime_track,
312 quicktime_channel);
313 file->atracks[quicktime_track].current_position += samples;
315 return result;
318 /* Since all channels are written at the same time: */
319 /* Encode using the compressor for the first audio track. */
320 /* Which means all the audio channels must be on the same track. */
322 int quicktime_encode_audio(quicktime_t *file, int16_t **input_i, float **input_f, long samples)
324 int result = 1;
325 char *compressor = quicktime_audio_compressor(file, 0);
327 result = ((quicktime_codec_t*)file->atracks[0].codec)->encode_audio(file,
328 input_i,
329 input_f,
331 samples);
332 file->atracks[0].current_position += samples;
334 return result;
337 int quicktime_reads_cmodel(quicktime_t *file,
338 int colormodel,
339 int track)
341 int result = ((quicktime_codec_t*)file->vtracks[track].codec)->reads_colormodel(file, colormodel, track);
342 return result;
345 int quicktime_writes_cmodel(quicktime_t *file,
346 int colormodel,
347 int track)
349 return ((quicktime_codec_t*)file->vtracks[track].codec)->writes_colormodel(file, colormodel, track);
352 /* Compressors that can only encode a window at a time */
353 /* need to flush extra data here. */
355 int quicktime_flush_acodec(quicktime_t *file, int track)
357 ((quicktime_codec_t*)file->atracks[track].codec)->flush(file, track);
358 return 0;
361 void quicktime_flush_vcodec(quicktime_t *file, int track)
363 ((quicktime_codec_t*)file->vtracks[track].codec)->flush(file, track);
366 int64_t quicktime_samples_to_bytes(quicktime_trak_t *track, long samples)
368 char *compressor = track->mdia.minf.stbl.stsd.table[0].format;
369 int channels = track->mdia.minf.stbl.stsd.table[0].channels;
371 if(quicktime_match_32(compressor, QUICKTIME_IMA4))
372 return samples * channels;
374 if(quicktime_match_32(compressor, QUICKTIME_ULAW))
375 return samples * channels;
377 /* Default use the sample size specification for TWOS and RAW */
378 return samples * channels * track->mdia.minf.stbl.stsd.table[0].sample_size / 8;
381 int quicktime_codecs_flush(quicktime_t *file)
383 int result = 0;
384 int i;
385 if(!file->wr) return result;
387 if(file->total_atracks)
389 for(i = 0; i < file->total_atracks && !result; i++)
391 quicktime_flush_acodec(file, i);
395 if(file->total_vtracks)
397 for(i = 0; i < file->total_vtracks && !result; i++)
399 quicktime_flush_vcodec(file, i);
402 return result;