1 #include "colormodels.h"
2 #include "funcprotos.h"
6 static int delete_vcodec_stub(quicktime_video_map_t
*vtrack
)
8 printf("delete_vcodec_stub called\n");
12 static int delete_acodec_stub(quicktime_audio_map_t
*atrack
)
14 printf("delete_acodec_stub called\n");
18 static int decode_video_stub(quicktime_t
*file
,
19 unsigned char **row_pointers
,
22 printf("decode_video_stub called\n");
26 static int encode_video_stub(quicktime_t
*file
,
27 unsigned char **row_pointers
,
30 printf("encode_video_stub called\n");
34 static int decode_audio_stub(quicktime_t
*file
,
41 printf("decode_audio_stub called\n");
45 static int encode_audio_stub(quicktime_t
*file
,
51 printf("encode_audio_stub called\n");
56 static int reads_colormodel_stub(quicktime_t
*file
,
60 return (colormodel
== BC_RGB888
);
63 static int writes_colormodel_stub(quicktime_t
*file
,
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
)
80 memcpy(result
, QUICKTIME_MP3
, 4);
83 memcpy(result
, QUICKTIME_WMA
, 4);
86 printf("quicktime_id_to_codec: unknown audio id: %p\n", id
);
91 int quicktime_codec_to_id(char *codec
)
93 if(quicktime_match_32(codec
, QUICKTIME_MP3
))
96 if(quicktime_match_32(codec
, QUICKTIME_WMA
))
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
;
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
);
127 "new_vcodec: couldn't find codec for \"%c%c%c%c\"\n",
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
);
149 "new_acodec: couldn't find codec for \"%c%c%c%c\"\n",
162 int quicktime_init_vcodec(quicktime_video_map_t
*vtrack
)
164 int result
= new_vcodec(vtrack
);
168 int quicktime_init_acodec(quicktime_audio_map_t
*atrack
)
170 int result
= new_acodec(atrack
);
175 int quicktime_delete_vcodec(quicktime_video_map_t
*vtrack
)
179 quicktime_codec_t
*codec_base
= vtrack
->codec
;
181 codec_base
->delete_vcodec(vtrack
);
188 int quicktime_delete_acodec(quicktime_audio_map_t
*atrack
)
192 quicktime_codec_t
*codec_base
= atrack
->codec
;
194 codec_base
->delete_acodec(atrack
);
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
];
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
];
230 long quicktime_decode_video(quicktime_t
*file
,
231 unsigned char **row_pointers
,
236 if(track
< 0 || track
>= file
->total_vtracks
)
238 fprintf(stderr
, "quicktime_decode_video: track %d out of range %d - %d\n",
241 file
->total_vtracks
);
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
;
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
,
264 file
->vtracks
[track
].current_position
++;
268 void quicktime_set_parameter(quicktime_t
*file
, char *key
, void *value
)
271 for(i
= 0; i
< file
->total_vtracks
; i
++)
273 quicktime_codec_t
*codec
= (quicktime_codec_t
*)file
->vtracks
[i
].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
;
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
,
291 result
= ((quicktime_codec_t
*)file
->vtracks
[track
].codec
)->encode_video(file
, row_pointers
, track
);
292 file
->vtracks
[track
].current_position
++;
297 int quicktime_decode_audio(quicktime_t
*file
,
303 int quicktime_track
, quicktime_channel
;
306 quicktime_channel_location(file
, &quicktime_track
, &quicktime_channel
, channel
);
307 result
= ((quicktime_codec_t
*)file
->atracks
[quicktime_track
].codec
)->decode_audio(file
,
313 file
->atracks
[quicktime_track
].current_position
+= samples
;
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
)
325 char *compressor
= quicktime_audio_compressor(file
, 0);
327 result
= ((quicktime_codec_t
*)file
->atracks
[0].codec
)->encode_audio(file
,
332 file
->atracks
[0].current_position
+= samples
;
337 int quicktime_reads_cmodel(quicktime_t
*file
,
341 int result
= ((quicktime_codec_t
*)file
->vtracks
[track
].codec
)->reads_colormodel(file
, colormodel
, track
);
345 int quicktime_writes_cmodel(quicktime_t
*file
,
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
);
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
)
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
);