r665: Merged the official release 2.0.
[cinelerra_cv.git] / quicktime / codecs.c
blobea7eef58b79010c1da29615e6ed60b81af4172b8
1 #include "colormodels.h"
2 #include "funcprotos.h"
3 #include "quicktime.h"
5 static int delete_vcodec_stub(quicktime_video_map_t *vtrack)
7 printf("delete_vcodec_stub called\n");
8 return 0;
11 static int delete_acodec_stub(quicktime_audio_map_t *atrack)
13 printf("delete_acodec_stub called\n");
14 return 0;
17 static int decode_video_stub(quicktime_t *file,
18 unsigned char **row_pointers,
19 int track)
21 printf("decode_video_stub called\n");
22 return 1;
25 static int encode_video_stub(quicktime_t *file,
26 unsigned char **row_pointers,
27 int track)
29 printf("encode_video_stub called\n");
30 return 1;
33 static int decode_audio_stub(quicktime_t *file,
34 int16_t *output_i,
35 float *output_f,
36 long samples,
37 int track,
38 int channel)
40 printf("decode_audio_stub called\n");
41 return 1;
44 static int encode_audio_stub(quicktime_t *file,
45 int16_t **input_i,
46 float **input_f,
47 int track,
48 long samples)
50 printf("encode_audio_stub called\n");
51 return 1;
55 static int reads_colormodel_stub(quicktime_t *file,
56 int colormodel,
57 int track)
59 return (colormodel == BC_RGB888);
62 static int writes_colormodel_stub(quicktime_t *file,
63 int colormodel,
64 int track)
66 return (colormodel == BC_RGB888);
69 static void flush_codec_stub(quicktime_t *file, int track)
73 /* Convert Microsoft audio id to codec */
74 void quicktime_id_to_codec(char *result, int id)
76 switch(id)
78 case 0x55:
79 memcpy(result, QUICKTIME_MP3, 4);
80 break;
81 case 0x161:
82 memcpy(result, QUICKTIME_WMA, 4);
83 break;
84 default:
85 printf("quicktime_id_to_codec: unknown audio id: %p\n", id);
86 break;
90 int quicktime_codec_to_id(char *codec)
92 if(quicktime_match_32(codec, QUICKTIME_MP3))
93 return 0x55;
94 else
95 if(quicktime_match_32(codec, QUICKTIME_WMA))
96 return 0x161;
97 else
98 printf("quicktime_codec_to_id: unknown codec %c%c%c%c\n", codec[0], codec[1], codec[2], codec[3]);
102 static quicktime_codec_t* new_codec()
104 quicktime_codec_t *codec = calloc(1, sizeof(quicktime_codec_t));
105 codec->delete_vcodec = delete_vcodec_stub;
106 codec->delete_acodec = delete_acodec_stub;
107 codec->decode_video = decode_video_stub;
108 codec->encode_video = encode_video_stub;
109 codec->decode_audio = decode_audio_stub;
110 codec->encode_audio = encode_audio_stub;
111 codec->reads_colormodel = reads_colormodel_stub;
112 codec->writes_colormodel = writes_colormodel_stub;
113 codec->flush = flush_codec_stub;
114 return codec;
117 int new_vcodec(quicktime_video_map_t *vtrack)
119 quicktime_codec_t *codec_base = vtrack->codec = new_codec();
120 char *compressor = vtrack->track->mdia.minf.stbl.stsd.table[0].format;
121 int result = quicktime_find_vcodec(vtrack);
123 if(result)
125 fprintf(stderr,
126 "new_vcodec: couldn't find codec for \"%c%c%c%c\"\n",
127 compressor[0],
128 compressor[1],
129 compressor[2],
130 compressor[3]);
131 free(codec_base);
132 vtrack->codec = 0;
133 return 1;
136 return 0;
139 int new_acodec(quicktime_audio_map_t *atrack)
141 quicktime_codec_t *codec_base = atrack->codec = new_codec();
142 char *compressor = atrack->track->mdia.minf.stbl.stsd.table[0].format;
143 int result = quicktime_find_acodec(atrack);
145 if(result)
147 fprintf(stderr,
148 "new_acodec: couldn't find codec for \"%c%c%c%c\"\n",
149 compressor[0],
150 compressor[1],
151 compressor[2],
152 compressor[3]);
153 free(codec_base);
154 atrack->codec = 0;
155 return 1;
158 return 0;
161 int quicktime_init_vcodec(quicktime_video_map_t *vtrack)
163 int result = new_vcodec(vtrack);
164 return result;
167 int quicktime_init_acodec(quicktime_audio_map_t *atrack)
169 int result = new_acodec(atrack);
170 return result;
174 int quicktime_delete_vcodec(quicktime_video_map_t *vtrack)
176 if(vtrack->codec)
178 quicktime_codec_t *codec_base = vtrack->codec;
179 if(codec_base->priv)
180 codec_base->delete_vcodec(vtrack);
181 free(vtrack->codec);
183 vtrack->codec = 0;
184 return 0;
187 int quicktime_delete_acodec(quicktime_audio_map_t *atrack)
189 if(atrack->codec)
191 quicktime_codec_t *codec_base = atrack->codec;
192 if(codec_base->priv)
193 codec_base->delete_acodec(atrack);
194 free(atrack->codec);
196 atrack->codec = 0;
197 return 0;
200 int quicktime_supported_video(quicktime_t *file, int track)
202 if(track < file->total_vtracks)
204 quicktime_video_map_t *video_map = &file->vtracks[track];
206 if(video_map->codec)
207 return 1;
208 else
209 return 0;
211 return 0;
214 int quicktime_supported_audio(quicktime_t *file, int track)
216 if(track < file->total_atracks)
218 quicktime_audio_map_t *audio_map = &file->atracks[track];
219 if(audio_map->codec)
220 return 1;
221 else
222 return 0;
224 return 0;
229 long quicktime_decode_video(quicktime_t *file,
230 unsigned char **row_pointers,
231 int track)
233 int result;
235 if(track < 0 || track >= file->total_vtracks)
237 fprintf(stderr, "quicktime_decode_video: track %d out of range %d - %d\n",
238 track,
240 file->total_vtracks);
241 return 1;
244 /* Get dimensions from first video track */
245 if(!file->do_scaling)
247 quicktime_video_map_t *video_map = &file->vtracks[track];
248 quicktime_trak_t *trak = video_map->track;
249 int track_width = trak->tkhd.track_width;
250 int track_height = trak->tkhd.track_height;
252 file->in_x = 0;
253 file->in_y = 0;
254 file->in_w = track_width;
255 file->in_h = track_height;
256 file->out_w = track_width;
257 file->out_h = track_height;
260 result = ((quicktime_codec_t*)file->vtracks[track].codec)->decode_video(file,
261 row_pointers,
262 track);
263 file->vtracks[track].current_position++;
264 return result;
267 void quicktime_set_parameter(quicktime_t *file, char *key, void *value)
269 int i;
270 for(i = 0; i < file->total_vtracks; i++)
272 quicktime_codec_t *codec = (quicktime_codec_t*)file->vtracks[i].codec;
273 if(codec)
274 if(codec->set_parameter) codec->set_parameter(file, i, key, value);
277 for(i = 0; i < file->total_atracks; i++)
279 quicktime_codec_t *codec = (quicktime_codec_t*)file->atracks[i].codec;
280 if(codec)
281 if(codec->set_parameter) codec->set_parameter(file, i, key, value);
285 int quicktime_encode_video(quicktime_t *file,
286 unsigned char **row_pointers,
287 int track)
289 int result;
290 result = ((quicktime_codec_t*)file->vtracks[track].codec)->encode_video(file, row_pointers, track);
291 file->vtracks[track].current_position++;
292 return result;
296 int quicktime_decode_audio(quicktime_t *file,
297 int16_t *output_i,
298 float *output_f,
299 long samples,
300 int channel)
302 int quicktime_track, quicktime_channel;
303 int result = 1;
305 quicktime_channel_location(file, &quicktime_track, &quicktime_channel, channel);
306 result = ((quicktime_codec_t*)file->atracks[quicktime_track].codec)->decode_audio(file,
307 output_i,
308 output_f,
309 samples,
310 quicktime_track,
311 quicktime_channel);
312 file->atracks[quicktime_track].current_position += samples;
314 return result;
317 /* Since all channels are written at the same time: */
318 /* Encode using the compressor for the first audio track. */
319 /* Which means all the audio channels must be on the same track. */
321 int quicktime_encode_audio(quicktime_t *file, int16_t **input_i, float **input_f, long samples)
323 int result = 1;
324 char *compressor = quicktime_audio_compressor(file, 0);
326 result = ((quicktime_codec_t*)file->atracks[0].codec)->encode_audio(file,
327 input_i,
328 input_f,
330 samples);
331 file->atracks[0].current_position += samples;
333 return result;
336 int quicktime_reads_cmodel(quicktime_t *file,
337 int colormodel,
338 int track)
340 int result = ((quicktime_codec_t*)file->vtracks[track].codec)->reads_colormodel(file, colormodel, track);
341 return result;
344 int quicktime_writes_cmodel(quicktime_t *file,
345 int colormodel,
346 int track)
348 return ((quicktime_codec_t*)file->vtracks[track].codec)->writes_colormodel(file, colormodel, track);
351 /* Compressors that can only encode a window at a time */
352 /* need to flush extra data here. */
354 int quicktime_flush_acodec(quicktime_t *file, int track)
356 ((quicktime_codec_t*)file->atracks[track].codec)->flush(file, track);
357 return 0;
360 void quicktime_flush_vcodec(quicktime_t *file, int track)
362 ((quicktime_codec_t*)file->vtracks[track].codec)->flush(file, track);
365 int64_t quicktime_samples_to_bytes(quicktime_trak_t *track, long samples)
367 char *compressor = track->mdia.minf.stbl.stsd.table[0].format;
368 int channels = track->mdia.minf.stbl.stsd.table[0].channels;
370 if(quicktime_match_32(compressor, QUICKTIME_IMA4))
371 return samples * channels;
373 if(quicktime_match_32(compressor, QUICKTIME_ULAW))
374 return samples * channels;
376 /* Default use the sample size specification for TWOS and RAW */
377 return samples * channels * track->mdia.minf.stbl.stsd.table[0].sample_size / 8;
380 int quicktime_codecs_flush(quicktime_t *file)
382 int result = 0;
383 int i;
384 if(!file->wr) return result;
386 if(file->total_atracks)
388 for(i = 0; i < file->total_atracks && !result; i++)
390 quicktime_flush_acodec(file, i);
394 if(file->total_vtracks)
396 for(i = 0; i < file->total_vtracks && !result; i++)
398 quicktime_flush_vcodec(file, i);
401 return result;