Mercurial > mplayer.hg
annotate libvo/vo_svga.c @ 483:92f170c8b9ba
fix to newest revision after cvs rollback
author | atmosfear |
---|---|
date | Tue, 17 Apr 2001 06:22:48 +0000 |
parents | 198b46b739d8 |
children | dfafa47d751d |
rev | line source |
---|---|
285 | 1 /* |
292 | 2 Video driver for SVGAlib - alpha, slow |
285 | 3 by Zoltan Mark Vician <se7en@sch.bme.hu> |
381 | 4 Code started: Mon Apr 1 23:25:47 2001 |
407 | 5 |
6 Uses HW acceleration if your card is supported by SVGAlib. | |
285 | 7 */ |
8 | |
9 #include <stdio.h> | |
10 #include <stdlib.h> | |
11 | |
12 #include <vga.h> | |
13 #include <vgagl.h> | |
14 | |
15 #include "config.h" | |
16 #include "video_out.h" | |
17 #include "video_out_internal.h" | |
18 | |
19 #include "yuv2rgb.h" | |
377 | 20 #include "mmx.h" |
285 | 21 |
407 | 22 extern void rgb15to16_mmx(char* s0,char* d0,int count); |
23 | |
285 | 24 LIBVO_EXTERN(svga) |
25 | |
26 static vo_info_t vo_info = { | |
27 "SVGAlib", | |
28 "svga", | |
29 "Zoltan Mark Vician <se7en@sch.bme.hu>", | |
30 "" | |
31 }; | |
32 | |
33 // SVGAlib definitions | |
34 | |
35 GraphicsContext *screen; | |
36 GraphicsContext *virt; | |
37 | |
407 | 38 static uint8_t *scalebuf = NULL, *yuvbuf = NULL, *bppbuf = NULL; |
285 | 39 |
40 static uint32_t orig_w, orig_h, maxw, maxh; // Width, height | |
377 | 41 static float scaling = 1.0; |
285 | 42 static uint32_t x_pos, y_pos; // Position |
43 | |
483 | 44 // SVGAlib - list of detected modes |
45 typedef struct vga_modelist_s { | |
46 uint16_t modenum; | |
47 vga_modeinfo modeinfo; | |
48 struct vga_modelist_s *next; | |
49 } vga_modelist_t; | |
447 | 50 |
483 | 51 vga_modelist_t *modelist = NULL; |
52 | |
327 | 53 static uint8_t bpp; |
483 | 54 static uint8_t bpp_conv = 0; |
448
198b46b739d8
qrva eletbe nem kene cvs-t elbaszni inkabb ne nyuljatok hozza baz+
arpi_esp
parents:
447
diff
changeset
|
55 static uint32_t pformat; |
447 | 56 |
483 | 57 #define BPP_15 1 |
58 #define BPP_16 2 | |
59 #define BPP_24 4 | |
60 #define BPP_32 8 | |
61 static uint8_t bpp_avail = 0; | |
62 | |
285 | 63 static uint8_t checked = 0; |
483 | 64 |
65 static int add_mode(uint16_t mode, vga_modeinfo minfo) { | |
66 vga_modelist_t *list; | |
285 | 67 |
483 | 68 if (modelist == NULL) { |
69 modelist = malloc(sizeof(vga_modelist_t)); | |
70 modelist->modenum = mode; | |
71 modelist->modeinfo = minfo; | |
72 modelist->next = NULL; | |
73 if (modelist == NULL) { | |
74 printf("vo_svga: add_mode() failed. Not enough memory for modelist."); | |
75 return(1); // error | |
76 } | |
77 } else { | |
78 list = modelist; | |
79 while (list->next != NULL) | |
80 list = list->next; | |
81 list->next = malloc(sizeof(vga_modelist_t)); | |
82 if (list->next == NULL) { | |
83 printf("vo_svga: add_mode() failed. Not enough memory for modelist."); | |
84 return(1); // error | |
85 } | |
86 list = list->next; | |
87 list->modenum = mode; | |
88 list->modeinfo = minfo; | |
89 list->next = NULL; | |
90 } | |
91 } | |
92 | |
93 static int checksupportedmodes() { | |
94 uint16_t i; | |
95 vga_modeinfo *minfo; | |
285 | 96 |
97 checked = 1; | |
98 vga_init(); | |
99 vga_disabledriverreport(); | |
483 | 100 for (i = 1; i < vga_lastmodenumber(); i++) |
101 if (vga_hasmode(i) > 0) { | |
102 minfo = vga_getmodeinfo(i); | |
103 switch (minfo->colors) { | |
104 case 32768: bpp_avail |= BPP_15; break; | |
105 case 65536: bpp_avail |= BPP_16; break; | |
106 } | |
107 switch (minfo->bytesperpixel) { | |
108 case 3: bpp_avail |= BPP_24; break; | |
109 case 4: bpp_avail |= BPP_32; break; | |
110 } | |
111 if (add_mode(i, *minfo)) | |
112 return(1); | |
113 } | |
285 | 114 } |
115 | |
116 static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width, | |
117 uint32_t d_height, uint32_t fullscreen, char *title, | |
118 uint32_t format) { | |
483 | 119 uint32_t req_w = (d_width > 0 ? d_width : width); |
120 uint32_t req_h = (d_height > 0 ? d_height : height); | |
121 uint16_t vid_mode = 0; | |
122 uint8_t widescreen = (((req_w*1.0)/req_h) > (4.0/3)) ? 1 : 0; | |
123 vga_modelist_t *list = modelist; | |
387 | 124 |
285 | 125 if (!checked) { |
483 | 126 if (checksupportedmodes()) // Looking for available video modes |
127 return(1); | |
285 | 128 } |
407 | 129 |
483 | 130 bpp_avail = 0; |
131 while (list != NULL) { | |
132 if ((list->modeinfo.width >= req_w) && (list->modeinfo.height >= req_h)) { | |
133 switch (list->modeinfo.colors) { | |
134 case 32768: bpp_avail |= BPP_15; break; | |
135 case 65536: bpp_avail |= BPP_16; break; | |
136 } | |
137 switch (list->modeinfo.bytesperpixel) { | |
138 case 3: bpp_avail |= BPP_24; break; | |
139 case 4: bpp_avail |= BPP_32; break; | |
140 } | |
141 } | |
142 list = list->next; | |
143 } | |
144 | |
285 | 145 pformat = format; |
411 | 146 |
483 | 147 // bpp check |
148 bpp_conv = 0; | |
411 | 149 if (!vo_dbpp) { |
150 if (format == IMGFMT_YV12) bpp = 32; | |
151 else bpp = format & 255; | |
483 | 152 switch (bpp) { |
153 case 32: if (!(bpp_avail & BPP_32)) { | |
154 printf("vo_svga: Haven't found video mode which fit to: %dx%d %dbpp\n",req_w,req_h,bpp); | |
155 printf("vo_svga: Maybe you should try -bpp\n"); | |
156 return(1); | |
157 } | |
158 break; | |
159 case 24: if (!(bpp_avail & BPP_24)) | |
160 if (!(bpp_avail & BPP_32)) { | |
161 printf("vo_svga: Haven't found video mode which fit to: %dx%d %dbpp\n",req_w,req_h,bpp); | |
162 printf("vo_svga: Maybe you should try -bpp\n"); | |
163 return(1); | |
164 } else { | |
165 bpp = 32; | |
166 bpp_conv = 1; | |
167 } | |
168 break; | |
169 case 16: if (!(bpp_avail & BPP_16)) { | |
170 printf("vo_svga: Haven't found video mode which fit to: %dx%d %dbpp\n",req_w,req_h,bpp); | |
171 printf("vo_svga: Maybe you should try -bpp\n"); | |
172 return(1); | |
173 } | |
174 break; | |
175 case 15: if (!(bpp_avail & BPP_15)) | |
176 if (!(bpp_avail & BPP_16)) { | |
177 printf("vo_svga: Haven't found video mode which fit to: %dx%d %dbpp\n",req_w,req_h,bpp); | |
178 printf("vo_svga: Maybe you should try -bpp\n"); | |
179 return(1); | |
180 } else { | |
181 bpp = 16; | |
182 bpp_conv = 1; | |
183 } | |
184 break; | |
185 } | |
411 | 186 } else { |
187 bpp = vo_dbpp; | |
188 switch (bpp) { | |
483 | 189 case 32: if (!(bpp_avail & BPP_32)) { |
190 printf("vo_svga: %dbpp not supported by HW or SVGAlib\n",bpp); | |
411 | 191 return(1); |
192 } | |
483 | 193 case 24: if (!(bpp_avail & BPP_24)) { |
194 printf("vo_svga: %dbpp not supported by HW or SVGAlib\n",bpp); | |
411 | 195 return(1); |
196 } | |
483 | 197 case 16: if (!(bpp_avail & BPP_16)) { |
198 printf("vo_svga: %dbpp not supported by HW or SVGAlib\n",bpp); | |
411 | 199 return(1); |
200 } | |
483 | 201 case 15: if (!(bpp_avail & BPP_15)) { |
202 printf("vo_svga: %dbpp not supported by HW or SVGAlib\n",bpp); | |
411 | 203 return(1); |
204 } | |
205 } | |
206 } | |
483 | 207 |
208 list = modelist; | |
209 while ((list != NULL) && (!vid_mode)) { | |
210 if ((list->modeinfo.width >= req_w) && (list->modeinfo.height >= req_h)) { | |
285 | 211 switch (bpp) { |
483 | 212 case 32: if (list->modeinfo.bytesperpixel == 4) |
213 vid_mode = list->modenum; | |
214 case 24: if (list->modeinfo.bytesperpixel == 3) | |
215 vid_mode = list->modenum; | |
216 case 16: if (list->modeinfo.colors == 65536) | |
217 vid_mode = list->modenum; | |
218 case 15: if (list->modeinfo.colors == 32768) | |
219 vid_mode = list->modenum; | |
285 | 220 } |
483 | 221 } |
222 list = list->next; | |
407 | 223 } |
483 | 224 |
407 | 225 vga_setlinearaddressing(); |
286 | 226 if (vga_setmode(vid_mode) == -1){ |
227 printf("vo_svga: vga_setmode(%d) failed.\n",vid_mode); | |
483 | 228 uninit(); |
285 | 229 return(1); // error |
286 | 230 } |
231 if (gl_setcontextvga(vid_mode)){ | |
232 printf("vo_svga: gl_setcontextvga(%d) failed.\n",vid_mode); | |
483 | 233 uninit(); |
285 | 234 return(1); // error |
286 | 235 } |
285 | 236 screen = gl_allocatecontext(); |
237 gl_getcontext(screen); | |
286 | 238 if (gl_setcontextvgavirtual(vid_mode)){ |
239 printf("vo_svga: gl_setcontextvgavirtual(%d) failed.\n",vid_mode); | |
483 | 240 uninit(); |
285 | 241 return(1); // error |
286 | 242 } |
285 | 243 virt = gl_allocatecontext(); |
244 gl_getcontext(virt); | |
245 gl_setcontext(virt); | |
246 gl_clearscreen(0); | |
247 | |
483 | 248 if (bpp_conv) |
249 bppbuf = malloc(maxw * maxh * BYTESPERPIXEL); | |
250 if (bppbuf == NULL) { | |
251 printf("vo_svga: Not enough memory for buffering!\n"); | |
252 uninit(); | |
253 return (1); | |
254 } | |
255 | |
285 | 256 orig_w = width; |
257 orig_h = height; | |
343 | 258 if ((fullscreen & 0x04) && (WIDTH != orig_w)) { |
483 | 259 if (!widescreen) { |
292 | 260 maxh = HEIGHT; |
261 scaling = maxh / (orig_h * 1.0); | |
262 maxw = (uint32_t) (orig_w * scaling); | |
263 scalebuf = malloc(maxw * maxh * BYTESPERPIXEL); | |
483 | 264 if (scalebuf == NULL) { |
265 printf("vo_svga: Not enough memory for buffering!\n"); | |
407 | 266 uninit(); |
267 return (1); | |
268 } | |
292 | 269 } else { |
270 maxw = WIDTH; | |
271 scaling = maxw / (orig_w * 1.0); | |
272 maxh = (uint32_t) (orig_h * scaling); | |
273 scalebuf = malloc(maxw * maxh * BYTESPERPIXEL); | |
483 | 274 if (scalebuf == NULL) { |
275 printf("vo_svga: Not enough memory for buffering!\n"); | |
407 | 276 uninit(); |
277 return (1); | |
278 } | |
292 | 279 } |
285 | 280 } else { |
281 maxw = orig_w; | |
282 maxh = orig_h; | |
283 } | |
284 x_pos = (WIDTH - maxw) / 2; | |
285 y_pos = (HEIGHT - maxh) / 2; | |
286 | |
287 if (pformat == IMGFMT_YV12) { | |
288 yuv2rgb_init(bpp, MODE_RGB); | |
289 yuvbuf = malloc(maxw * maxh * BYTESPERPIXEL); | |
483 | 290 if (yuvbuf == NULL) { |
291 printf("vo_svga: Not enough memory for buffering!\n"); | |
407 | 292 uninit(); |
293 return (1); | |
294 } | |
285 | 295 } |
377 | 296 |
292 | 297 printf("SVGAlib resolution: %dx%d %dbpp - ", WIDTH, HEIGHT, bpp); |
293 | 298 if (maxw != orig_w || maxh != orig_h) printf("Video scaled to: %dx%d\n",maxw,maxh); |
285 | 299 else printf("No video scaling\n"); |
300 | |
301 return (0); | |
302 } | |
303 | |
304 static uint32_t query_format(uint32_t format) { | |
407 | 305 uint8_t res = 0; |
306 | |
483 | 307 if (!checked) { |
308 if (checksupportedmodes()) // Looking for available video modes | |
309 return(0); | |
310 } | |
407 | 311 switch (format) { |
312 case IMGFMT_RGB32: | |
313 case IMGFMT_BGR|32: { | |
483 | 314 return ((bpp_avail & BPP_32) ? 1 : 0); |
407 | 315 } |
316 case IMGFMT_RGB24: | |
317 case IMGFMT_BGR|24: { | |
483 | 318 res = (bpp_avail & BPP_24) ? 1 : 0; |
407 | 319 if (!res) { |
483 | 320 res = (bpp_avail & BPP_32) ? 1 : 0; |
407 | 321 bpp_conv = 1; |
285 | 322 } |
407 | 323 return (res); |
324 } | |
325 case IMGFMT_RGB16: | |
326 case IMGFMT_BGR|16: { | |
483 | 327 return ((bpp_avail & BPP_16) ? 1 : 0); |
407 | 328 } |
329 case IMGFMT_RGB15: | |
330 case IMGFMT_BGR|15: { | |
483 | 331 res = (bpp_avail & BPP_15) ? 1 : 0; |
407 | 332 if (!res) { |
483 | 333 res = (bpp_avail & BPP_16) ? 1 : 0; |
407 | 334 bpp_conv = 1; |
285 | 335 } |
407 | 336 return (res); |
285 | 337 } |
407 | 338 case IMGFMT_YV12: return (1); |
339 } | |
285 | 340 return (0); |
341 } | |
342 | |
343 static const vo_info_t* get_info(void) { | |
344 return (&vo_info); | |
345 } | |
346 | |
347 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, | |
348 unsigned char *srca, int stride) { | |
327 | 349 switch (bpp) { |
350 case 32: | |
351 vo_draw_alpha_rgb32(w, h, src, srca, stride, virt->vbuf+4*(y0*WIDTH+x0), 4*WIDTH); | |
352 break; | |
353 case 24: | |
354 vo_draw_alpha_rgb24(w, h, src, srca, stride, virt->vbuf+3*(y0*WIDTH+x0), 3*WIDTH); | |
355 break; | |
356 case 16: | |
357 vo_draw_alpha_rgb16(w, h, src, srca, stride, virt->vbuf+2*(y0*WIDTH+x0), 2*WIDTH); | |
358 break; | |
359 case 15: | |
360 vo_draw_alpha_rgb15(w, h, src, srca, stride, virt->vbuf+2*(y0*WIDTH+x0), 2*WIDTH); | |
361 break; | |
362 } | |
285 | 363 } |
364 | |
365 static uint32_t draw_frame(uint8_t *src[]) { | |
366 if (pformat == IMGFMT_YV12) { | |
367 yuv2rgb(yuvbuf, src[0], src[1], src[2], orig_w, orig_h, orig_w * BYTESPERPIXEL, orig_w, orig_w / 2); | |
368 src[0] = yuvbuf; | |
369 } | |
483 | 370 if (scalebuf != NULL) { |
285 | 371 gl_scalebox(orig_w, orig_h, src[0], maxw, maxh, scalebuf); |
372 src[0] = scalebuf; | |
373 } | |
407 | 374 if (bpp_conv) { |
375 uint16_t *src = (uint16_t *) src[0]; | |
376 uint16_t *dest = (uint16_t *) bppbuf; | |
377 uint16_t *end; | |
378 | |
379 switch(bpp) { | |
380 case 32: | |
381 end = src + (maxw * maxh * 2); | |
382 while (src < end) { | |
383 *dest++ = *src++; | |
384 (uint8_t *)dest = (uint8_t *)src; | |
385 *(((uint8_t *)dest)+1) = 0; | |
386 dest++; | |
387 src++; | |
388 } | |
389 case 16: | |
390 #ifdef HAVE_MMX | |
391 rgb15to16_mmx(src[0],bppbuf,maxw * maxh * 2); | |
392 #else | |
393 register uint16_t srcdata; | |
394 | |
395 end = src + (maxw * maxh); | |
396 while (src < end) { | |
397 srcdata = *src++; | |
398 *dest++ = (srcdata & 0x1f) | ((srcdata & 0x7fe0) << 1); | |
399 } | |
400 #endif | |
401 } | |
402 src[0] = bppbuf; | |
403 } | |
285 | 404 gl_putbox(x_pos, y_pos, maxw, maxh, src[0]); |
405 } | |
406 | |
407 static uint32_t draw_slice(uint8_t *image[], int stride[], | |
408 int w, int h, int x, int y) { | |
409 uint8_t *src = yuvbuf; | |
377 | 410 uint32_t sw, sh; |
411 | |
412 emms(); | |
413 sw = (uint32_t) (w * scaling); | |
414 sh = (uint32_t) (h * scaling); | |
285 | 415 yuv2rgb(yuvbuf, image[0], image[1], image[2], w, h, orig_w * BYTESPERPIXEL, stride[0], stride[1]); |
483 | 416 if (scalebuf != NULL) { |
377 | 417 gl_scalebox(w, h, yuvbuf, sw, sh, scalebuf); |
285 | 418 src = scalebuf; |
419 } | |
377 | 420 gl_putbox((int)(x * scaling) + x_pos, (int)(y * scaling) + y_pos, sw, sh, src); |
285 | 421 } |
422 | |
423 static void flip_page(void) { | |
292 | 424 if (y_pos) { |
425 gl_fillbox(0, 0, WIDTH, y_pos, 0); | |
426 gl_fillbox(0, HEIGHT - y_pos, WIDTH, y_pos, 0); | |
427 } else { | |
428 gl_fillbox(0, 0, x_pos, HEIGHT, 0); | |
429 gl_fillbox(WIDTH - x_pos, 0, x_pos, HEIGHT, 0); | |
327 | 430 } |
285 | 431 vo_draw_text(WIDTH, HEIGHT, draw_alpha); |
432 gl_copyscreen(screen); | |
433 } | |
434 | |
435 static void check_events(void) { | |
436 } | |
437 | |
438 static void uninit(void) { | |
483 | 439 vga_modelist_t *list = modelist; |
440 | |
285 | 441 gl_freecontext(screen); |
442 gl_freecontext(virt); | |
443 vga_setmode(TEXT); | |
483 | 444 if (bppbuf != NULL) |
407 | 445 free(bppbuf); |
483 | 446 if (scalebuf != NULL) |
285 | 447 free(scalebuf); |
483 | 448 if (yuvbuf != NULL) |
285 | 449 free(yuvbuf); |
483 | 450 if (modelist != NULL) { |
451 while (modelist->next != NULL) { | |
452 list = modelist; | |
453 while (list->next != NULL) | |
454 list = list->next; | |
455 free(list); | |
456 } | |
457 free(modelist); | |
458 } | |
285 | 459 } |
460 |