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