comparison libvo/vo_gif89a.c @ 9540:ea4ca6a17d96

remove yuv2rgb and support frame duplication
author joey
date Thu, 06 Mar 2003 04:59:20 +0000
parents 8b572238f63e
children e49a62a6e3cb
comparison
equal deleted inserted replaced
9539:1df740eaa156 9540:ea4ca6a17d96
56 #include "video_out.h" 56 #include "video_out.h"
57 #include "video_out_internal.h" 57 #include "video_out_internal.h"
58 #include "../postproc/rgb2rgb.h" 58 #include "../postproc/rgb2rgb.h"
59 59
60 #define MPLAYER_VERSION 0.90 60 #define MPLAYER_VERSION 0.90
61 #define VO_GIF_REVISION 4 61 #define VO_GIF_REVISION 6
62 62
63 static vo_info_t info = { 63 static vo_info_t info = {
64 "animated GIF output", 64 "animated GIF output",
65 "gif89a", 65 "gif89a",
66 "Joey Parrish joey@nicewarrior.org", 66 "Joey Parrish joey@nicewarrior.org",
93 // the output width and height 93 // the output width and height
94 static uint32_t img_width; 94 static uint32_t img_width;
95 static uint32_t img_height; 95 static uint32_t img_height;
96 // image data for slice rendering 96 // image data for slice rendering
97 static uint8_t *slice_data = NULL; 97 static uint8_t *slice_data = NULL;
98 // pointer for whole frame rendering
99 static uint8_t *frame_data = NULL;
100 // reduced image data for flip_page 98 // reduced image data for flip_page
101 static uint8_t *reduce_data = NULL; 99 static uint8_t *reduce_data = NULL;
102 // reduced color map for flip_page 100 // reduced color map for flip_page
103 static ColorMapObject *reduce_cmap = NULL; 101 static ColorMapObject *reduce_cmap = NULL;
104 102
196 // reconfigure need not be a fatal error, so return 0. 194 // reconfigure need not be a fatal error, so return 0.
197 // multiple configs without uninit will result in two 195 // multiple configs without uninit will result in two
198 // movies concatenated in one gif file. the output 196 // movies concatenated in one gif file. the output
199 // gif will have the dimensions of the first movie. 197 // gif will have the dimensions of the first movie.
200 198
201 switch (format) { 199 if (format != IMGFMT_RGB24) {
202 case IMGFMT_RGB24: break; 200 printf("GIF89a: Error - given unsupported colorspace.\n");
203 case IMGFMT_YV12: 201 return 1;
204 yuv2rgb_init(24, MODE_BGR); 202 }
205 slice_data = malloc(img_width * img_height * 3); 203
206 if (slice_data == NULL) {
207 printf("GIF89a: malloc failed.\n");
208 return 1;
209 }
210 break;
211 default:
212 printf("GIF89a: Error - given unsupported colorspace.\n");
213 return 1;
214 }
215
216 // the EGifSetGifVersion line causes segfaults in certain 204 // the EGifSetGifVersion line causes segfaults in certain
217 // earlier versions of libungif. i don't know exactly which, 205 // earlier versions of libungif. i don't know exactly which,
218 // but certainly in all those before v4. if you have problems, 206 // but certainly in all those before v4. if you have problems,
219 // you need to upgrade your gif library. 207 // you need to upgrade your gif library.
220 #ifdef HAVE_GIF_4 208 #ifdef HAVE_GIF_4
228 if (new_gif == NULL) { 216 if (new_gif == NULL) {
229 printf("GIF89a: error opening file \"%s\" for output.\n", gif_filename); 217 printf("GIF89a: error opening file \"%s\" for output.\n", gif_filename);
230 return 1; 218 return 1;
231 } 219 }
232 220
221 slice_data = malloc(img_width * img_height * 3);
222 if (slice_data == NULL) {
223 printf("GIF89a: malloc failed.\n");
224 return 1;
225 }
226
233 reduce_data = malloc(img_width * img_height); 227 reduce_data = malloc(img_width * img_height);
234 if (reduce_data == NULL) { 228 if (reduce_data == NULL) {
235 printf("GIF89a: malloc failed.\n"); 229 printf("GIF89a: malloc failed.\n");
236 return 1; 230 return 1;
237 } 231 }
293 static void flip_page(void) 287 static void flip_page(void)
294 { 288 {
295 char CB[4]; // control block 289 char CB[4]; // control block
296 int delay = 0; 290 int delay = 0;
297 int ret; 291 int ret;
298 uint8_t *img_data;
299 292
300 cycle_pos++; 293 cycle_pos++;
301 if (cycle_pos < frame_cycle - frame_adj) 294 if (cycle_pos < frame_cycle - frame_adj)
302 return; // we are skipping this frame 295 return; // we are skipping this frame
303 296
304 // slice_data is used for per slice rendering,
305 // and frame_data is used for per frame rendering.
306 // i seperated these two because slice_data is
307 // ram i allocate, and frame_data is not.
308 // using one pointer for both can lead to
309 // either segfault (freeing ram that i'm not supposed
310 // to) or memory leaks (not freeing any ram at all)
311 if (slice_data != NULL) img_data = slice_data;
312 else img_data = frame_data;
313
314 // quantize the image 297 // quantize the image
315 ret = gif_reduce(img_width, img_height, img_data, reduce_data, reduce_cmap->Colors); 298 ret = gif_reduce(img_width, img_height, slice_data, reduce_data, reduce_cmap->Colors);
316 if (ret == GIF_ERROR) { 299 if (ret == GIF_ERROR) {
317 printf("GIF89a: Quantize failed.\n"); 300 printf("GIF89a: Quantize failed.\n");
318 return; 301 return;
319 } 302 }
320 303
340 EGifPutLine(new_gif, reduce_data, img_width * img_height); 323 EGifPutLine(new_gif, reduce_data, img_width * img_height);
341 } 324 }
342 325
343 static uint32_t draw_frame(uint8_t *src[]) 326 static uint32_t draw_frame(uint8_t *src[])
344 { 327 {
345 frame_data = src[0]; 328 return 1;
329 }
330
331 static uint32_t draw_slice(uint8_t *src[], int stride[], int w, int h, int x, int y)
332 {
333 uint8_t *dst, *frm;
334 int i;
335 dst = slice_data + (img_width * y + x) * 3;
336 frm = src[0];
337 for (i = 0; i < h; i++) {
338 memcpy(dst, frm, w * 3);
339 dst += (img_width * 3);
340 frm += stride[0];
341 }
346 return 0; 342 return 0;
347 } 343 }
348 344
349 static uint32_t draw_slice(uint8_t *src[], int stride[], int w, int h, int x, int y)
350 {
351 uint8_t *dst;
352 dst = slice_data + (img_width * y + x) * 3;
353 yuv2rgb(dst, src[0], src[1], src[2], w, h, img_width * 3, stride[0], stride[1]);
354 return 0;
355 }
356
357 static uint32_t query_format(uint32_t format) 345 static uint32_t query_format(uint32_t format)
358 { 346 {
359 switch (format) { 347 if (format == IMGFMT_RGB24)
360 case IMGFMT_YV12: 348 return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_TIMER | VFCAP_ACCEPT_STRIDE;
361 return VFCAP_CSP_SUPPORTED | VFCAP_TIMER | VFCAP_ACCEPT_STRIDE;
362 case IMGFMT_RGB24:
363 return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_TIMER;
364 }
365 return 0; 349 return 0;
366 } 350 }
367 351
368 static uint32_t control(uint32_t request, void *data, ...) 352 static uint32_t control(uint32_t request, void *data, ...)
369 { 353 {
370 if (request == VOCTRL_QUERY_FORMAT) { 354 if (request == VOCTRL_QUERY_FORMAT) {
371 return query_format(*((uint32_t*)data)); 355 return query_format(*((uint32_t*)data));
356 }
357 if (request == VOCTRL_DUPLICATE_FRAME) {
358 flip_page();
359 return VO_TRUE;
372 } 360 }
373 return VO_NOTIMPL; 361 return VO_NOTIMPL;
374 } 362 }
375 363
376 static void uninit(void) 364 static void uninit(void)
395 if (reduce_cmap != NULL) FreeMapObject(reduce_cmap); 383 if (reduce_cmap != NULL) FreeMapObject(reduce_cmap);
396 384
397 // set the pointers back to null. 385 // set the pointers back to null.
398 new_gif = NULL; 386 new_gif = NULL;
399 gif_filename = NULL; 387 gif_filename = NULL;
400 frame_data = NULL;
401 slice_data = NULL; 388 slice_data = NULL;
402 reduce_data = NULL; 389 reduce_data = NULL;
403 reduce_cmap = NULL; 390 reduce_cmap = NULL;
404 } 391 }
405 392