Mercurial > mplayer.hg
annotate libvo/vo_fsdga.c @ 6719:5291d74a60c9
xv support under cygwin - patch by Sycotic Smith <sycotic at linuxmail.org>
author | alex |
---|---|
date | Fri, 12 Jul 2002 17:09:53 +0000 |
parents | 2001affedb75 |
children | eca7dbad0166 |
rev | line source |
---|---|
38 | 1 |
2 /* | |
3 * video_out_dga.c, X11 interface | |
4 * | |
5 * | |
6 * Copyright ( C ) 2001, Andreas Ackermann. All Rights Reserved. | |
7 * | |
8 * <acki@acki-netz.de> | |
9 * | |
10 * note well: | |
11 * | |
12 * o this is alpha | |
13 * o covers only common video card formats | |
14 * o works only on intel architectures | |
15 * | |
16 */ | |
17 | |
18 | |
19 | |
20 #include <stdio.h> | |
21 #include <stdlib.h> | |
22 #include <string.h> | |
4737
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
23 #include <errno.h> |
38 | 24 |
354 | 25 //#include "fastmemcpy.h" |
38 | 26 |
27 #include "linux/keycodes.h" | |
28 #include "config.h" | |
29 #include "video_out.h" | |
30 #include "video_out_internal.h" | |
2732 | 31 #include "../postproc/rgb2rgb.h" |
38 | 32 |
33 LIBVO_EXTERN( fsdga ) | |
34 | |
35 #include <X11/Xlib.h> | |
36 #include <X11/extensions/xf86dga.h> | |
37 | |
38 #include "x11_common.h" | |
39 | |
40 static vo_info_t vo_info = | |
41 { | |
42 "FullScreen DGA ( Direct Graphic Access )", | |
43 "fsdga", | |
44 "A'rpi/ESP-team & Andreas Ackermann <acki@acki-netz.de>", | |
45 "" | |
46 }; | |
47 | |
48 static int vo_dga_width; // bytes per line in framebuffer | |
49 static int vo_dga_vp_width; // visible pixels per line in framebuffer | |
50 static int vo_dga_vp_height; // visible lines in framebuffer | |
51 static int vo_dga_is_running = 0; | |
52 static int vo_dga_src_width; // width of video in pixels | |
53 static int vo_dga_src_height; // height of video in pixels | |
54 static int vo_dga_bpp; // bytes per pixel in framebuffer | |
55 static int vo_dga_src_offset=0; // offset in src | |
56 static int vo_dga_vp_offset=0; // offset in dest | |
57 static int vo_dga_bytes_per_line; // longwords per line to copy | |
58 static int vo_dga_src_skip; // bytes to skip after copying one line | |
59 // (not supported yet) in src | |
60 static int vo_dga_vp_skip; // dto. for dest | |
61 static int vo_dga_lines; // num of lines to copy | |
62 static int vo_dga_src_format; | |
63 | |
64 static unsigned char *vo_dga_base; | |
65 static Display *vo_dga_dpy; | |
66 | |
67 | |
68 #if defined (HAVE_SSE) || defined (HAVE_3DNOW) | |
69 #define movntq "movntq" // use this for processors that have SSE or 3Dnow | |
70 #else | |
71 #define movntq "movq" // for MMX-only processors | |
72 #endif | |
73 | |
74 | |
75 #define rep_movsl(dest, src, numwords, d_add, count) \ | |
76 __asm__ __volatile__( \ | |
77 " \ | |
78 xfer: \n\t\ | |
79 movl %%edx, %%ecx \n\t \ | |
80 cld\n\t \ | |
81 rep\n\t \ | |
82 movsl \n\t\ | |
83 add %%eax, %%edi \n\t\ | |
84 dec %%ebx \n\t\ | |
85 jnz xfer \n\t\ | |
86 " \ | |
87 : \ | |
88 : "a" (d_add), "b" (count), "S" (src), "D" (dest), "d" (numwords) \ | |
89 : "memory" ) | |
90 | |
91 #if 0 | |
92 : "S" (src), "D" (dest), "c" (numwords) \ | |
93 movq (%%eax), %%mm0 \n\t \ | |
94 add $64, %%edx \n\t \ | |
95 movq 8(%%eax), %%mm1 \n\t \ | |
96 add $64, %%eax \n\t \ | |
97 movq -48(%%eax), %%mm2 \n\t \ | |
98 movq %%mm0, -64(%%edx) \n\t \ | |
99 movq -40(%%eax), %%mm3 \n\t \ | |
100 movq %%mm1, -56(%%edx) \n\t \ | |
101 movq -32(%%eax), %%mm4 \n\t \ | |
102 movq %%mm2, -48(%%edx) \n\t \ | |
103 movq -24(%%eax), %%mm5 \n\t \ | |
104 movq %%mm3, -40(%%edx) \n\t \ | |
105 movq -16(%%eax), %%mm6 \n\t \ | |
106 movq %%mm4, -32(%%edx) \n\t \ | |
107 movq -8(%%eax), %%mm7 \n\t \ | |
108 movq %%mm5, -24(%%edx) \n\t \ | |
109 movq %%mm6, -16(%%edx) \n\t \ | |
110 dec %%ecx \n\t \ | |
111 movq %%mm7, -8(%%edx) \n\t \ | |
112 jnz xfer \n\t \ | |
113 | |
114 #endif | |
115 | |
116 #define mmx_movsl(dest, src, numwords) \ | |
117 __asm__ __volatile__( \ | |
118 " \ | |
119 \n\t \ | |
120 xfer: \n\t \ | |
121 movq (%%eax), %%mm0 \n\t \ | |
122 add $64, %%edx \n\t \ | |
123 movq 8(%%eax), %%mm1 \n\t \ | |
124 add $64, %%eax \n\t \ | |
125 movq -48(%%eax), %%mm2 \n\t \ | |
126 movq %%mm0, -64(%%edx) \n\t \ | |
127 movq -40(%%eax), %%mm3 \n\t \ | |
128 movq %%mm1, -56(%%edx) \n\t \ | |
129 movq -32(%%eax), %%mm4 \n\t \ | |
130 movq %%mm2, -48(%%edx) \n\t \ | |
131 movq -24(%%eax), %%mm5 \n\t \ | |
132 movq %%mm3, -40(%%edx) \n\t \ | |
133 movq -16(%%eax), %%mm6 \n\t \ | |
134 movq %%mm4, -32(%%edx) \n\t \ | |
135 movq -8(%%eax), %%mm7 \n\t \ | |
136 movq %%mm5, -24(%%edx) \n\t \ | |
137 movq %%mm6, -16(%%edx) \n\t \ | |
138 dec %%ecx \n\t \ | |
139 movq %%mm7, -8(%%edx) \n\t \ | |
140 jnz xfer \n\t \ | |
141 \ | |
142 " \ | |
143 : \ | |
144 : "a" (src), "d" (dest), "c" (numwords) \ | |
145 : "memory" ) | |
146 | |
147 // src <= eax | |
148 // dst <= edx | |
149 // num <= ecx | |
150 | |
151 static uint32_t draw_frame( uint8_t *src[] ){ | |
152 | |
153 int vp_skip = vo_dga_vp_skip; | |
154 int lpl = vo_dga_bytes_per_line >> 2; | |
155 int numlines = vo_dga_lines; | |
156 | |
157 char *s, *d; | |
158 | |
159 if( vo_dga_src_format==IMGFMT_YV12 ){ | |
160 // We'll never reach this point, because YV12 codecs always calls draw_slice | |
161 printf("vo_dga: draw_frame() doesn't support IMGFMT_YV12 (yet?)\n"); | |
162 }else{ | |
163 s = *src; | |
164 d = (&((char *)vo_dga_base)[vo_dga_vp_offset]); | |
165 rep_movsl(d, s, lpl, vo_dga_vp_skip, numlines ); | |
166 } | |
167 | |
168 return 0; | |
169 } | |
170 | |
171 static void check_events(void) | |
172 { | |
173 int e=vo_x11_check_events(vo_dga_dpy); | |
174 } | |
175 | |
1501
d40f2b686846
changes according to -utf8 option, draw_osd() function added
atlka
parents:
612
diff
changeset
|
176 static void draw_osd(void) |
d40f2b686846
changes according to -utf8 option, draw_osd() function added
atlka
parents:
612
diff
changeset
|
177 { |
d40f2b686846
changes according to -utf8 option, draw_osd() function added
atlka
parents:
612
diff
changeset
|
178 } |
d40f2b686846
changes according to -utf8 option, draw_osd() function added
atlka
parents:
612
diff
changeset
|
179 |
38 | 180 static void flip_page( void ){ |
181 // printf("vo_dga: In flippage\n"); | |
182 } | |
183 | |
184 static unsigned int pix_buf_y[4][2048]; | |
185 static unsigned int pix_buf_uv[2][2048*2]; | |
186 static int dga_srcypos=0; | |
187 static int dga_ypos=0; | |
188 static int dga_last_ypos=-1; | |
189 static unsigned int dga_xinc,dga_yinc,dga_xinc2; | |
190 | |
191 static unsigned char clip_table[768]; | |
192 | |
193 static int yuvtab_2568[256]; | |
194 static int yuvtab_3343[256]; | |
195 static int yuvtab_0c92[256]; | |
196 static int yuvtab_1a1e[256]; | |
197 static int yuvtab_40cf[256]; | |
198 | |
199 | |
200 static uint32_t draw_slice( uint8_t *srcptr[],int stride[], | |
201 int w,int h,int x,int y ) | |
202 { | |
203 | |
204 if(y==0){ | |
205 dga_srcypos=-2*dga_yinc; | |
206 dga_ypos=-2; | |
207 dga_last_ypos=-2; | |
208 } // reset counters | |
209 | |
210 while(1){ | |
211 unsigned char *dest=vo_dga_base+(vo_dga_width * dga_ypos)*vo_dga_bpp; | |
212 int y0=2+(dga_srcypos>>16); | |
213 int y1=1+(dga_srcypos>>17); | |
214 int yalpha=(dga_srcypos&0xFFFF)>>8; | |
215 int yalpha1=yalpha^255; | |
216 int uvalpha=((dga_srcypos>>1)&0xFFFF)>>8; | |
217 int uvalpha1=uvalpha^255; | |
218 unsigned int *buf0=pix_buf_y[y0&3]; | |
219 unsigned int *buf1=pix_buf_y[((y0+1)&3)]; | |
220 unsigned int *uvbuf0=pix_buf_uv[y1&1]; | |
221 unsigned int *uvbuf1=pix_buf_uv[(y1&1)^1]; | |
222 int i; | |
223 | |
224 if(y0>=y+h) break; | |
225 | |
226 dga_ypos++; dga_srcypos+=dga_yinc; | |
227 | |
228 if(dga_last_ypos!=y0){ | |
229 unsigned char *src=srcptr[0]+(y0-y)*stride[0]; | |
230 unsigned int xpos=0; | |
231 dga_last_ypos=y0; | |
232 // this loop should be rewritten in MMX assembly!!!! | |
233 for(i=0;i<vo_dga_vp_width;i++){ | |
234 register unsigned int xx=xpos>>8; | |
235 register unsigned int xalpha=xpos&0xFF; | |
236 buf1[i]=(src[xx]*(xalpha^255)+src[xx+1]*xalpha); | |
237 xpos+=dga_xinc; | |
238 } | |
239 if(!(y0&1)){ | |
240 unsigned char *src1=srcptr[1]+(y1-y/2)*stride[1]; | |
241 unsigned char *src2=srcptr[2]+(y1-y/2)*stride[2]; | |
242 xpos=0; | |
243 // this loop should be rewritten in MMX assembly!!!! | |
244 for(i=0;i<vo_dga_vp_width;i++){ | |
245 register unsigned int xx=xpos>>8; | |
246 register unsigned int xalpha=xpos&0xFF; | |
247 uvbuf1[i]=(src1[xx]*(xalpha^255)+src1[xx+1]*xalpha); | |
248 uvbuf1[i+2048]=(src2[xx]*(xalpha^255)+src2[xx+1]*xalpha); | |
249 xpos+=dga_xinc2; | |
250 } | |
251 } | |
252 if(!y0) continue; | |
253 } | |
254 | |
255 // this loop should be rewritten in MMX assembly!!!! | |
256 for(i=0;i<vo_dga_vp_width;i++){ | |
257 // linear interpolation && yuv2rgb in a single step: | |
258 int Y=yuvtab_2568[((buf0[i]*yalpha1+buf1[i]*yalpha)>>16)]; | |
259 int U=((uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>16); | |
260 int V=((uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>16); | |
261 dest[0]=clip_table[((Y + yuvtab_3343[U]) >>13)]; | |
262 dest[1]=clip_table[((Y + yuvtab_0c92[V] + yuvtab_1a1e[U]) >>13)]; | |
263 dest[2]=clip_table[((Y + yuvtab_40cf[V]) >>13)]; | |
264 dest+=vo_dga_bpp; | |
265 } | |
266 | |
267 } | |
268 | |
269 | |
270 return 0; | |
271 }; | |
272 | |
273 static const vo_info_t* get_info( void ) | |
274 { return &vo_info; } | |
275 | |
276 static uint32_t query_format( uint32_t format ) | |
277 { | |
278 printf("vo_dga: query_format\n"); | |
279 | |
280 if( !vo_init() ) return 0; // Can't open X11 | |
612 | 281 printf("Format: %lx\n", (unsigned long) format); |
38 | 282 |
6212 | 283 if( format==IMGFMT_YV12 ) return VFCAP_CSP_SUPPORTED; |
38 | 284 if( ( format&IMGFMT_BGR_MASK )==IMGFMT_BGR && |
6212 | 285 ( format&0xFF )==vo_depthonscreen ) return VFCAP_CSP_SUPPORTED|VFCAP_CSP_SUPPORTED_BY_HW; |
38 | 286 return 0; |
287 } | |
288 | |
289 | |
290 static void | |
291 uninit(void) | |
292 { | |
293 vo_dga_is_running = 0; | |
294 XUngrabPointer (vo_dga_dpy, CurrentTime); | |
295 XUngrabKeyboard (vo_dga_dpy, CurrentTime); | |
296 XF86DGADirectVideo (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0); | |
297 XCloseDisplay(vo_dga_dpy); | |
298 } | |
299 | |
300 | |
301 | |
302 | |
4433 | 303 static uint32_t config( uint32_t width, uint32_t height, |
38 | 304 uint32_t d_width,uint32_t d_height, |
4433 | 305 uint32_t fullscreen,char *title,uint32_t format,const vo_tune_info_t *info ) |
38 | 306 { |
307 | |
308 int bank, ram; | |
309 int x_off, y_off; | |
310 | |
311 if( vo_dga_is_running )return -1; | |
312 | |
313 if( !vo_init() ){ | |
314 printf("vo_dga: vo_init() failed!\n"); | |
315 return 0; | |
316 } | |
317 | |
318 if((vo_dga_dpy = XOpenDisplay(0))==NULL) | |
319 { | |
320 printf ("vo_dga: Can't open display\n"); | |
321 return 1; | |
322 } | |
323 | |
324 XF86DGAGetVideo (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), | |
325 (char **)&vo_dga_base, &vo_dga_width, &bank, &ram); | |
326 XF86DGAGetViewPortSize (vo_dga_dpy, XDefaultScreen (vo_dga_dpy), | |
327 &vo_dga_vp_width, &vo_dga_vp_height); | |
328 | |
329 | |
330 // do some more checkings here ... | |
331 if( format==IMGFMT_YV12 ) | |
332 yuv2rgb_init( vo_depthonscreen, MODE_RGB ); | |
333 | |
334 vo_dga_src_format = format; | |
335 vo_dga_src_width = width; | |
336 vo_dga_src_height = height; | |
337 vo_dga_bpp = (vo_depthonscreen+7) >> 3; | |
338 | |
612 | 339 printf("vo_dga: bytes/line: %d, screen res: %dx%d, depth: %d, base: %p, bpp: %d\n", |
38 | 340 vo_dga_width, vo_dga_vp_width, |
341 vo_dga_vp_height, vo_depthonscreen, vo_dga_base, | |
342 vo_dga_bpp); | |
343 printf("vo_dga: video res: %dx%d\n", vo_dga_src_width, vo_dga_src_height); | |
344 | |
345 if(vo_dga_src_width > vo_dga_vp_width || | |
346 vo_dga_src_height > vo_dga_vp_height){ | |
347 printf("vo_dga: Sorry, video larger than viewport is not yet supported!\n"); | |
348 // ugly, do something nicer in the future ... | |
349 return 1; | |
350 } | |
351 | |
352 x_off = (vo_dga_vp_width - vo_dga_src_width)>>1; | |
353 y_off = (vo_dga_vp_height - vo_dga_src_height)>>1; | |
354 | |
355 vo_dga_bytes_per_line = vo_dga_src_width * vo_dga_bpp; // todo | |
356 vo_dga_lines = vo_dga_src_height; // todo | |
357 | |
358 | |
359 vo_dga_src_offset = 0; | |
360 vo_dga_vp_offset = (y_off * vo_dga_width + x_off ) * vo_dga_bpp; | |
361 | |
362 vo_dga_vp_skip = (vo_dga_width - vo_dga_src_width) * vo_dga_bpp; // todo | |
363 | |
364 printf("vo_dga: vp_off=%d, vp_skip=%d, bpl=%d\n", | |
365 vo_dga_vp_offset, vo_dga_vp_skip, vo_dga_bytes_per_line); | |
366 | |
367 | |
368 | |
369 XF86DGASetViewPort (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0, 0); | |
370 XF86DGADirectVideo (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), | |
371 XF86DGADirectGraphics | XF86DGADirectMouse | | |
372 XF86DGADirectKeyb); | |
373 | |
374 XGrabKeyboard (vo_dga_dpy, DefaultRootWindow(vo_dga_dpy), True, | |
375 GrabModeAsync,GrabModeAsync, CurrentTime); | |
376 XGrabPointer (vo_dga_dpy, DefaultRootWindow(vo_dga_dpy), True, | |
377 ButtonPressMask,GrabModeAsync, GrabModeAsync, | |
378 None, None, CurrentTime); | |
379 | |
380 // now clear screen | |
381 | |
382 memset(vo_dga_base, 0, vo_dga_width * vo_dga_vp_height * vo_dga_bpp); | |
383 | |
384 dga_yinc=(vo_dga_src_height<<16)/vo_dga_vp_height; | |
385 dga_xinc=(vo_dga_src_width<<8)/vo_dga_vp_width; | |
386 dga_xinc2=dga_xinc>>1; | |
387 | |
388 { int i; | |
389 for(i=0;i<256;i++){ | |
390 clip_table[i]=0; | |
391 clip_table[i+256]=i; | |
392 clip_table[i+512]=255; | |
393 yuvtab_2568[i]=(0x2568*(i-16))+(256<<13); | |
394 yuvtab_3343[i]=0x3343*(i-128); | |
395 yuvtab_0c92[i]=-0x0c92*(i-128); | |
396 yuvtab_1a1e[i]=-0x1a1e*(i-128); | |
397 yuvtab_40cf[i]=0x40cf*(i-128); | |
398 } | |
399 } | |
400 | |
401 vo_dga_is_running = 1; | |
402 return 0; | |
403 } | |
404 | |
405 #if 0 | |
406 int vo_dga_query_event(void){ | |
407 | |
408 XEvent myevent; | |
409 char text[10]; | |
410 KeySym mykey; | |
411 int retval = 0; | |
412 int i; | |
413 | |
414 if( vo_dga_is_running ){ | |
415 if(XPending(vo_dga_dpy)>0) | |
416 { | |
417 XNextEvent(vo_dga_dpy, &myevent); | |
418 switch (myevent.type) | |
419 { | |
420 case ButtonPress: | |
421 /* Reaktion auf Knopfdruck ---> Textausgabe an der | |
422 Mauscursorposition */ | |
423 | |
424 retval = 'q'; | |
425 break; | |
426 case KeyPress: | |
427 /* Reaktion auf Tastendruck --> Testen ob Taste == "q", | |
428 falls ja: Programmende */ | |
429 i=XLookupString(&myevent, text, 10, &mykey, 0); | |
430 | |
431 if (mykey&0xff00 != 0) mykey=mykey&0x00ff + 256; | |
432 | |
433 switch ( mykey ) | |
434 { | |
435 case wsLeft: retval=KEY_LEFT; break; | |
436 case wsRight: retval=KEY_RIGHT; break; | |
437 case wsUp: retval=KEY_UP; break; | |
438 case wsDown: retval=KEY_DOWN; break; | |
439 case wsSpace: retval=' '; break; | |
440 case wsEscape: retval=KEY_ESC; break; | |
441 case wsEnter: retval=KEY_ENTER; break; | |
442 case wsq: | |
443 case wsQ: retval='q'; break; | |
444 case wsp: | |
445 case wsP: retval='p'; break; | |
446 case wsMinus: | |
447 case wsGrayMinus: retval='-'; break; | |
448 case wsPlus: | |
449 case wsGrayPlus: retval='+'; break; | |
450 } | |
451 break; | |
452 } | |
453 } | |
454 } | |
455 return retval; | |
456 } | |
457 #endif | |
458 | |
4352 | 459 static uint32_t preinit(const char *arg) |
460 { | |
4737
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
461 if(arg) |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
462 { |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
463 printf("vo_fsdga: Unknown subdevice: %s\n",arg); |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
464 return ENOSYS; |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
465 } |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
466 return 0; |
4352 | 467 } |
38 | 468 |
4596 | 469 static uint32_t control(uint32_t request, void *data, ...) |
4352 | 470 { |
4592
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4439
diff
changeset
|
471 switch (request) { |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4439
diff
changeset
|
472 case VOCTRL_QUERY_FORMAT: |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4439
diff
changeset
|
473 return query_format(*((uint32_t*)data)); |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4439
diff
changeset
|
474 } |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4439
diff
changeset
|
475 return VO_NOTIMPL; |
4352 | 476 } |