Mercurial > mplayer.hg
annotate libvo/vo_gif89a.c @ 8130:7018fadf1a94
fixing vd_ffmpeg to handle cleaned-up ffmpeg
author | michael |
---|---|
date | Fri, 08 Nov 2002 18:40:39 +0000 |
parents | 9fc45fe0d444 |
children | 5b39e79af5fe |
rev | line source |
---|---|
6053 | 1 /* |
2 * vo_gif89a.c Generate gif89a output in file out.gif | |
3 * | |
4 * Originally based on vo_png.c | |
5 * | |
6 * Stolen (C) 2002 by GifWhore <joey@yunamusic.com> | |
7 * | |
8 */ | |
9 | |
10 #include <stdio.h> | |
11 #include <stdlib.h> | |
12 #include <string.h> | |
13 #include <errno.h> | |
14 | |
15 #include "config.h" | |
16 #include "video_out.h" | |
17 #include "video_out_internal.h" | |
7472
c4434bdf6e51
tons of warning fixes, also some 10l bugfixes, including Dominik's PVA bug
arpi
parents:
7124
diff
changeset
|
18 #include "sub.h" |
6053 | 19 |
20 #include "../postproc/rgb2rgb.h" | |
21 | |
22 #include <gif_lib.h> | |
23 | |
24 #define GIFWHORE_version 0.90 | |
25 | |
26 LIBVO_EXTERN (gif89a) | |
27 | |
28 static vo_info_t vo_info = | |
29 { | |
30 "GIF89a (out.gif)", | |
31 "gif89a", | |
32 "GifWhore <joey@yunamusic.com>", | |
33 "" | |
34 }; | |
35 | |
36 extern int verbose; | |
37 extern int vo_config_count; | |
38 | |
39 static int image_width; | |
40 static int image_height; | |
41 static int image_format; | |
42 static uint8_t *image_data=NULL; | |
43 | |
44 static int reverse_map = 0; | |
45 static unsigned char framenum = 0; | |
46 static int gif_frameskip; | |
47 static int gif_framedelay; | |
48 static int target_fps = 0; | |
49 | |
50 GifFileType *newgif=NULL; | |
51 | |
52 static uint32_t config | |
53 (uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, | |
7124
eca7dbad0166
finally removed query_vaa, bes_da and vo_tune_info - the obsoleted libvo api
alex
parents:
6211
diff
changeset
|
54 uint32_t fullscreen, char *title, uint32_t format) { |
6053 | 55 char filename[] = "out.gif"; |
56 ColorMapObject *Cmap; | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
57 #ifdef HAVE_GIF_4 |
6053 | 58 char LB[] = { |
59 'N','E','T','S', | |
60 'C','A','P','E', | |
61 '2','.','0' }; | |
62 char LB2[] = { 1, 0x00, 0x00 }; | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
63 #endif |
6053 | 64 |
65 if (target_fps == 0) target_fps = 5; | |
66 gif_frameskip = (vo_fps + 0.25) / target_fps; | |
67 gif_framedelay = 100 / target_fps; | |
68 | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
69 image_width = width; |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
70 image_height = height; |
6053 | 71 image_format = format; |
72 | |
73 Cmap = MakeMapObject(256, NULL); | |
74 | |
75 switch(format) { | |
76 case IMGFMT_BGR24: | |
77 reverse_map = 1; | |
78 break; | |
79 case IMGFMT_RGB24: | |
80 break; | |
81 case IMGFMT_YV12: | |
7487
e60109dfc85c
U-V swapping fixed, patch by Joey Parrish <joey@yunamusic.com>
arpi
parents:
7472
diff
changeset
|
82 yuv2rgb_init(24, MODE_BGR); |
6053 | 83 image_data = malloc(image_width*image_height*3); |
84 break; | |
85 default: | |
86 return 1; | |
87 } | |
88 | |
89 if (vo_config_count > 0) | |
90 return 0; | |
91 | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
92 // this line causes crashes in certain earlier versions of libungif. |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
93 // i don't know exactly which, but certainly all those before v4. |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
94 // if you have problems, you need to upgrade your gif library. |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
95 #ifdef HAVE_GIF_4 |
6053 | 96 EGifSetGifVersion("89a"); |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
97 #else |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
98 fprintf(stderr, "vo_gif89a: Your version of libgif/libungif needs to be upgraded.\n"); |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
99 fprintf(stderr, "vo_gif89a: Some functionality has been disabled.\n"); |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
100 #endif |
6053 | 101 newgif = EGifOpenFileName(filename, 0); |
102 if (newgif == NULL) | |
103 { | |
104 fprintf(stderr, "error opening file for output.\n"); | |
105 return(1); | |
106 } | |
107 EGifPutScreenDesc(newgif, image_width, image_height, 256, 0, Cmap); | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
108 #ifdef HAVE_GIF_4 |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
109 // version 3 of libgif/libungif does not support multiple control blocks. |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
110 // for this version, looping will be disabled. |
6053 | 111 EGifPutExtensionFirst(newgif, 0xFF, 11, LB); |
112 EGifPutExtensionLast(newgif, 0, 3, LB2); | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
113 #endif |
6053 | 114 |
115 return 0; | |
116 } | |
117 | |
118 static const vo_info_t* get_info(void) | |
119 { | |
120 return &vo_info; | |
121 } | |
122 | |
8123
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
7487
diff
changeset
|
123 /* forward declaration */ |
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
7487
diff
changeset
|
124 int gif_reduce(int width, int height, unsigned char *source, unsigned char *destination, unsigned char *palette); |
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
7487
diff
changeset
|
125 |
6053 | 126 static uint32_t draw_frame(uint8_t * src[]) |
127 { | |
128 uint8_t *use_data; | |
129 ColorMapObject *Cmap; | |
130 uint8_t Colors[256 * 3]; | |
131 int z; | |
132 char CB[] = { (char)(gif_framedelay >> 8), (char)(gif_framedelay & 0xff), 0, 0}; | |
133 | |
134 if ((framenum++ % gif_frameskip)) return(0); | |
135 | |
136 Cmap = MakeMapObject(256, NULL); | |
137 use_data = (uint8_t *)malloc(image_width * image_height); | |
138 if (gif_reduce(image_width, image_height, src[0], use_data, Colors)) return(0); | |
139 | |
140 if (reverse_map) | |
141 { | |
142 for (z = 0; z < 256; z++) { | |
143 Cmap->Colors[z].Blue = Colors[(z * 3) + 0]; | |
144 Cmap->Colors[z].Green = Colors[(z * 3) + 1]; | |
145 Cmap->Colors[z].Red = Colors[(z * 3) + 2]; | |
146 } | |
147 } | |
148 else | |
149 { | |
150 for (z = 0; z < 256; z++) { | |
151 Cmap->Colors[z].Red = Colors[(z * 3) + 0]; | |
152 Cmap->Colors[z].Green = Colors[(z * 3) + 1]; | |
153 Cmap->Colors[z].Blue = Colors[(z * 3) + 2]; | |
154 } | |
155 } | |
156 | |
157 EGifPutExtension(newgif, 0xF9, 0x04, CB); | |
158 EGifPutImageDesc(newgif, 0, 0, image_width, image_height, 0, Cmap); | |
159 EGifPutLine(newgif, use_data, image_width * image_height); | |
160 FreeMapObject(Cmap); | |
161 free(use_data); | |
162 | |
163 return (0); | |
164 } | |
165 | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
166 #ifdef USE_OSD |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
167 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
168 { |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
169 vo_draw_alpha_rgb24(w, h, src, srca, stride, image_data + 3 * (y0 * image_width + x0), 3 * image_width); |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
170 } |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
171 #endif |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
172 |
6053 | 173 static void draw_osd(void) |
174 { | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
175 #ifdef USE_OSD |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
176 vo_draw_text(image_width, image_height, draw_alpha); |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
177 #endif |
6053 | 178 } |
179 | |
180 static void flip_page (void) | |
181 { | |
182 uint8_t *use_data; | |
183 ColorMapObject *Cmap; | |
184 uint8_t Colors[256 * 3]; | |
185 int z; | |
186 char CB[] = { (char)(gif_framedelay >> 8), (char)(gif_framedelay & 0xff), 0, 0}; | |
187 | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
188 if (image_format == IMGFMT_YV12) { |
6053 | 189 |
190 if ((framenum++ % gif_frameskip)) return; | |
191 | |
192 Cmap = MakeMapObject(256, NULL); | |
193 use_data = (uint8_t *)malloc(image_width * image_height); | |
194 if (gif_reduce(image_width, image_height, image_data, use_data, Colors)) return; | |
195 | |
196 if (reverse_map) | |
197 { | |
198 for (z = 0; z < 256; z++) { | |
199 Cmap->Colors[z].Blue = Colors[(z * 3) + 0]; | |
200 Cmap->Colors[z].Green = Colors[(z * 3) + 1]; | |
201 Cmap->Colors[z].Red = Colors[(z * 3) + 2]; | |
202 } | |
203 } | |
204 else | |
205 { | |
206 for (z = 0; z < 256; z++) { | |
207 Cmap->Colors[z].Red = Colors[(z * 3) + 0]; | |
208 Cmap->Colors[z].Green = Colors[(z * 3) + 1]; | |
209 Cmap->Colors[z].Blue = Colors[(z * 3) + 2]; | |
210 } | |
211 } | |
212 | |
213 EGifPutExtension(newgif, 0xF9, 0x04, CB); | |
214 EGifPutImageDesc(newgif, 0, 0, image_width, image_height, 0, Cmap); | |
215 EGifPutLine(newgif, use_data, image_width * image_height); | |
216 FreeMapObject(Cmap); | |
217 free(use_data); | |
218 } | |
219 } | |
220 | |
221 static uint32_t draw_slice( uint8_t *src[],int stride[],int w,int h,int x,int y ) | |
222 { | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
223 uint8_t *dst = image_data + (image_width * y + x) * 3; |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
224 yuv2rgb(dst,src[0],src[1],src[2],w,h,image_width*3,stride[0],stride[1]); |
6053 | 225 return 0; |
226 } | |
227 | |
228 static uint32_t | |
229 query_format(uint32_t format) | |
230 { | |
231 switch(format){ | |
232 case IMGFMT_YV12: | |
6211 | 233 return VFCAP_CSP_SUPPORTED | VFCAP_TIMER | VFCAP_ACCEPT_STRIDE; |
6053 | 234 case IMGFMT_RGB|24: |
235 case IMGFMT_BGR|24: | |
6211 | 236 return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | VFCAP_TIMER; |
6053 | 237 } |
238 return 0; | |
239 } | |
240 | |
241 static void | |
242 uninit(void) | |
243 { | |
244 char temp[256]; | |
245 | |
246 if (image_data) { free(image_data); image_data=NULL; } | |
247 | |
248 if (vo_config_count > 0) { | |
249 sprintf(temp, "gifwhore v%2.2f (c) %s\r\n", | |
250 GIFWHORE_version, "joey@yunamusic.com"); | |
251 EGifPutComment(newgif, temp); | |
252 EGifCloseFile(newgif); | |
253 } | |
254 } | |
255 | |
256 | |
257 static void check_events(void) | |
258 { | |
259 } | |
260 | |
261 int gif_reduce(int width, int height, | |
262 unsigned char *source, | |
263 unsigned char *destination, | |
264 unsigned char *palette) | |
265 { | |
266 GifColorType cmap[256]; | |
267 unsigned char Ra[width * height]; | |
268 unsigned char Ga[width * height]; | |
269 unsigned char Ba[width * height]; | |
270 unsigned char *R, *G, *B; | |
271 int Size = 256; | |
272 int i; | |
273 | |
274 R = Ra; G = Ga; B = Ba; | |
275 for (i = 0; i < width * height; i++) | |
276 { | |
277 *R++ = *source++; | |
278 *G++ = *source++; | |
279 *B++ = *source++; | |
280 } | |
281 | |
282 R = Ra; G = Ga; B = Ba; | |
283 if (QuantizeBuffer(width, height, &Size, | |
284 R, G, B, | |
285 destination, cmap) == GIF_ERROR) | |
286 { | |
287 fprintf(stderr, "vo_gif89a: Quantize failed!\n"); | |
288 return(-1); | |
289 } | |
290 | |
291 for (i = 0; i < Size; i++) | |
292 { | |
293 *palette++ = cmap[i].Red; | |
294 *palette++ = cmap[i].Green; | |
295 *palette++ = cmap[i].Blue; | |
296 } | |
297 | |
298 return(0); | |
299 } | |
300 | |
301 static uint32_t preinit(const char *arg) | |
302 { | |
303 int i = 0; | |
304 if (arg) i = atoi(arg); | |
305 if (i > vo_fps) i = vo_fps; | |
306 if (i < 1) i = 5; | |
307 target_fps = i; | |
308 return 0; | |
309 } | |
310 | |
311 static uint32_t control(uint32_t request, void *data, ...) | |
312 { | |
313 switch (request) { | |
314 case VOCTRL_QUERY_FORMAT: | |
315 return query_format(*((uint32_t*)data)); | |
316 } | |
317 return VO_NOTIMPL; | |
318 } | |
319 |