1 #include "colormodels.h"
2 #include "funcprotos.h"
5 static int delete_vcodec_stub(quicktime_video_map_t
*vtrack
)
7 printf("delete_vcodec_stub called\n");
11 static int delete_acodec_stub(quicktime_audio_map_t
*atrack
)
13 printf("delete_acodec_stub called\n");
17 static int decode_video_stub(quicktime_t
*file
,
18 unsigned char **row_pointers
,
21 printf("decode_video_stub called\n");
25 static int encode_video_stub(quicktime_t
*file
,
26 unsigned char **row_pointers
,
29 printf("encode_video_stub called\n");
33 static int decode_audio_stub(quicktime_t
*file
,
40 printf("decode_audio_stub called\n");
44 static int encode_audio_stub(quicktime_t
*file
,
50 printf("encode_audio_stub called\n");
55 static int reads_colormodel_stub(quicktime_t
*file
,
59 return (colormodel
== BC_RGB888
);
62 static int writes_colormodel_stub(quicktime_t
*file
,
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
)
79 memcpy(result
, QUICKTIME_MP3
, 4);
82 memcpy(result
, QUICKTIME_WMA
, 4);
85 printf("quicktime_id_to_codec: unknown audio id: %p\n", id
);
90 int quicktime_codec_to_id(char *codec
)
92 if(quicktime_match_32(codec
, QUICKTIME_MP3
))
95 if(quicktime_match_32(codec
, QUICKTIME_WMA
))
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
;
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
);
126 "new_vcodec: couldn't find codec for \"%c%c%c%c\"\n",
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
);
148 "new_acodec: couldn't find codec for \"%c%c%c%c\"\n",
161 int quicktime_init_vcodec(quicktime_video_map_t
*vtrack
)
163 int result
= new_vcodec(vtrack
);
167 int quicktime_init_acodec(quicktime_audio_map_t
*atrack
)
169 int result
= new_acodec(atrack
);
174 int quicktime_delete_vcodec(quicktime_video_map_t
*vtrack
)
178 quicktime_codec_t
*codec_base
= vtrack
->codec
;
180 codec_base
->delete_vcodec(vtrack
);
187 int quicktime_delete_acodec(quicktime_audio_map_t
*atrack
)
191 quicktime_codec_t
*codec_base
= atrack
->codec
;
193 codec_base
->delete_acodec(atrack
);
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
];
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
];
229 long quicktime_decode_video(quicktime_t
*file
,
230 unsigned char **row_pointers
,
235 if(track
< 0 || track
>= file
->total_vtracks
)
237 fprintf(stderr
, "quicktime_decode_video: track %d out of range %d - %d\n",
240 file
->total_vtracks
);
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
;
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
,
263 file
->vtracks
[track
].current_position
++;
267 void quicktime_set_parameter(quicktime_t
*file
, char *key
, void *value
)
270 for(i
= 0; i
< file
->total_vtracks
; i
++)
272 quicktime_codec_t
*codec
= (quicktime_codec_t
*)file
->vtracks
[i
].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
;
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
,
290 result
= ((quicktime_codec_t
*)file
->vtracks
[track
].codec
)->encode_video(file
, row_pointers
, track
);
291 file
->vtracks
[track
].current_position
++;
296 int quicktime_decode_audio(quicktime_t
*file
,
302 int quicktime_track
, quicktime_channel
;
305 quicktime_channel_location(file
, &quicktime_track
, &quicktime_channel
, channel
);
306 result
= ((quicktime_codec_t
*)file
->atracks
[quicktime_track
].codec
)->decode_audio(file
,
312 file
->atracks
[quicktime_track
].current_position
+= samples
;
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
)
324 char *compressor
= quicktime_audio_compressor(file
, 0);
326 result
= ((quicktime_codec_t
*)file
->atracks
[0].codec
)->encode_audio(file
,
331 file
->atracks
[0].current_position
+= samples
;
336 int quicktime_reads_cmodel(quicktime_t
*file
,
340 int result
= ((quicktime_codec_t
*)file
->vtracks
[track
].codec
)->reads_colormodel(file
, colormodel
, track
);
344 int quicktime_writes_cmodel(quicktime_t
*file
,
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
);
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
)
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
);