CVS: main/libvo vo_dga.c,1.5,1.6
Update of /cvsroot/mplayer/main/libvo In directory usw-pr-cvs1:/tmp/cvs-serv20243 Modified Files: vo_dga.c Log Message: - 32/16 bit mode swtiching with DGA2.0 - now use only DGA2.0 API when DGA2.0 is available Index: vo_dga.c =================================================================== RCS file: /cvsroot/mplayer/main/libvo/vo_dga.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** vo_dga.c 2001/03/30 17:16:56 1.5 --- vo_dga.c 2001/03/30 22:09:38 1.6 *************** *** 16,20 **** --- 16,33 ---- * o covers only common video card formats * o works only on intel architectures + * + * 30/02/2001 * + * o query_format(): with DGA 2.0 it returns all depths it supports + * (even 16 when running 32 and vice versa) + * Checks for (hopefully!) compatible RGBmasks in 15/16 bit modes + * o added some more criterions for resolution switching + * o cleanup + * o with DGA2.0 present, ONLY DGA2.0 functions are used + * o for 15/16 modes ONLY RGB 555 is supported, since the divx-codec + * happens to map the data this way. If your graphics card supports + * this, you're well off and may use these modes; for mpeg + * movies things could be different, but I was too lazy to implement + * it ... */ *************** *** 25,30 **** #include <string.h> - - //#include "linux/keycodes.h" #include "config.h" #include "video_out.h" --- 38,41 ---- *************** *** 32,35 **** --- 43,47 ---- #include "yuv2rgb.h" + LIBVO_EXTERN( dga ) *************** *** 62,65 **** --- 74,78 ---- static int vo_dga_lines; // num of lines to copy static int vo_dga_src_format; + static int vo_dga_planes; // bits per pixel on screen static unsigned char *vo_dga_base; *************** *** 159,170 **** static uint32_t query_format( uint32_t format ) { ! printf("vo_dga: query_format\n"); ! if( !vo_init() ) return 0; // Can't open X11 ! printf("Format: %lx\n", format); if( format==IMGFMT_YV12 ) return 1; if( ( format&IMGFMT_BGR_MASK )==IMGFMT_BGR && ! ( format&0xFF )==vo_depthonscreen ) return 1; return 0; } --- 172,251 ---- static uint32_t query_format( uint32_t format ) { ! ! #ifdef HAVE_DGA2 ! XDGAMode *modelines; ! int modecount; ! Display *qdisp; ! #endif ! ! int i,k,dummy; ! static int dga_depths_init = 0; ! static int dga_depths = 0; // each bit that is set represents ! // a depth the X-Server is capable ! // of displaying ! ! ! if( !vo_init() ) return 0; // Can't open X11 ! ! if(dga_depths_init == 0){ ! #ifdef HAVE_DGA2 ! ! if((qdisp = XOpenDisplay(0))==NULL){ ! printf("vo_dga: Can't open display!\n"); ! return 0; ! } ! modelines=XDGAQueryModes(qdisp, XDefaultScreen(qdisp),&modecount); ! for(i=0; i< modecount; i++){ ! if( ( (modelines[i].bitsPerPixel == 15 || ! modelines[i].bitsPerPixel == 16) && ! modelines[i].redMask == 0x7c00 && ! modelines[i].greenMask == 0x03e0 && ! modelines[i].blueMask == 0x001f ! ) || ! ( modelines[i].bitsPerPixel != 15 && ! modelines[i].bitsPerPixel != 16 ! ) ! ) ! { ! for(k=0, dummy=1; k<modelines[i].bitsPerPixel-1; k++)dummy <<=1; ! dga_depths |= dummy; ! } ! ! } ! XCloseDisplay(qdisp); ! ! #else + for(k=0, dummy=1; k<vo_depthonscreen-1; k++)dummy <<=1; + dga_depths |= dummy; + // hope this shift is ok; heard that on some systems only up to 8 digits + // may be shifted at a time. SIGH! It IS so. + // test for RGB masks !!!! (if depthonscreen != 24 or 32 !!!) + if( !(vo_depthonscreen == 24 || vo_depthonscreen == 32 ) ){ + printf("vo_dga: You're running 15/16 bit X Server; your hardware might use unsuitable RGB-mask!\n"); + } + #endif + dga_depths_init = 1; + + if( dga_depths == 0){ + printf("vo_dga: Sorry, there seems to be no suitable depth available!\n"); + printf(" Try running X in 24 or 32 bit mode!!!\n"); + return 0; + }else{ + for(i=0, dummy=1; i< 32; i++){ + if(dummy& dga_depths){ + printf("vo_dga: may use %2d bits per pixel\n", i+1); + } + dummy <<= 1; + } + } + } if( format==IMGFMT_YV12 ) return 1; + for(k=0, dummy=1; k<(format&0xFF)-1; k++)dummy<<=1; + if( ( format&IMGFMT_BGR_MASK )==IMGFMT_BGR && ! ( dummy & dga_depths )) return 1; ! return 0; } *************** *** 176,244 **** { vo_dga_is_running = 0; printf("vo_dga: in uninit\n"); XUngrabPointer (vo_dga_dpy, CurrentTime); XUngrabKeyboard (vo_dga_dpy, CurrentTime); XF86DGADirectVideo (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0); XCloseDisplay(vo_dga_dpy); } - //--------------------------------------------------------- - - static uint32_t init( uint32_t width, uint32_t height, - uint32_t d_width,uint32_t d_height, - uint32_t fullscreen,char *title,uint32_t format ) - { - - int bank, ram; - int x_off, y_off; - - #ifdef HAVE_DGA2 - // needed to change DGA video mode - int modecount,mX, mY, mVBI, i,j; - int X,Y; - XDGAMode *modelines=NULL; - XDGADevice *dgadevice; - #endif - - if( vo_dga_is_running )return -1; - - if( !vo_init() ){ - printf("vo_dga: vo_init() failed!\n"); - return 0; - } - - if((vo_dga_dpy = XOpenDisplay(0))==NULL) - { - printf ("vo_dga: Can't open display\n"); - return 1; - } ! #ifdef HAVE_DGA2 ! // Code to change the video mode added by Michael Graffam ! // mgraffam@idsi.net ! if (modelines==NULL) ! modelines=XDGAQueryModes(vo_dga_dpy, XDefaultScreen(vo_dga_dpy),&modecount); ! ! mX=modelines[0].imageWidth; ! mY=modelines[0].imageHeight; ! mVBI = modelines[0].verticalRefresh; ! X=d_width; Y=d_height; ! ! printf("vo_dga: Using DGA 2.0 mode changing support\n"); ! j=0; ! // offbyone-error !!! i<=modecount is WRONG !!! ! for (i=1; i<modecount; i++) ! { ! if( modelines[i].bitsPerPixel == vo_depthonscreen && ! modelines[i].maxViewportX) ! { ! printf("vo_dga: (%3d) Trying %4d x %4d @ %3d Hz @ %2d bpp ..", ! i, ! modelines[i].viewportWidth, ! modelines[i].viewportHeight, ! (unsigned int) modelines[i].verticalRefresh, ! modelines[i].bitsPerPixel ); ! if ( (modelines[i].viewportWidth >= X) && --- 257,282 ---- { + #ifdef HAVE_DGA2 + XDGADevice *dgadevice; + #endif + vo_dga_is_running = 0; printf("vo_dga: in uninit\n"); XUngrabPointer (vo_dga_dpy, CurrentTime); XUngrabKeyboard (vo_dga_dpy, CurrentTime); + #ifdef HAVE_DGA2 + dgadevice = XDGASetMode(vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0); + if(dgadevice != NULL){ + XFree(dgadevice); + } + XDGACloseFramebuffer(vo_dga_dpy, XDefaultScreen(vo_dga_dpy)); + #else XF86DGADirectVideo (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0); + #endif XCloseDisplay(vo_dga_dpy); } ! #if 0 if ( (modelines[i].viewportWidth >= X) && *************** *** 291,311 **** printf(".no\n"); } } } - X=(modelines[j].imageWidth-mX)/2; - Y=(modelines[j].imageHeight-mY)/2; printf("vo_dga: Selected video mode %4d x %4d @ %3d Hz for image size %3d x %3d.\n", mX, mY, mVBI, width, height); ! XF86DGASetViewPort (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), X,Y); ! dgadevice=XDGASetMode(vo_dga_dpy, XDefaultScreen(vo_dga_dpy), modelines[j].num); XDGASync(vo_dga_dpy, XDefaultScreen(vo_dga_dpy)); ! XFree(modelines); XFree(dgadevice); ! // end mode change code #else - printf("vo_dga: DGA 1.0 compatibility code\n"); - #endif XF86DGAGetViewPortSize(vo_dga_dpy,XDefaultScreen(vo_dga_dpy), --- 329,535 ---- printf(".no\n"); } + #endif + + + //---------------------------------------------------------- + + int check_mode( int x, int y, + int new_x, int new_y, int new_vbi, + int *old_x, int *old_y, int *old_vbi){ + + if ( + (new_x >= x) && + (new_y >= y) && + ( + // prefer a better resolution either in X or in Y + // as long as the other dimension is at least the same + // + // hmm ... MAYBE it would be more clever to focus on the + // x-resolution; I had 712x400 and 640x480 and the movie + // was 640x360; 640x480 would be the 'right thing' here + // but since 712x400 was queried first I got this one. + // I think there should be a cmd-line switch to let the + // user choose the mode he likes ... (acki2) + + ( + ((new_x < *old_x) && + !(new_y > *old_y)) || + ((new_y < *old_y) && + !(new_x > *old_x)) + ) + // but if we get an identical resolution choose + // the one with the lower refreshrate (saves bandwidth !!!) + // as long as it's above 50 Hz (acki2 on 30/3/2001) + || + ( + (new_x == *old_x) && + (new_y == *old_y) && + ( + ( + new_vbi >= *old_vbi && *old_vbi < 50 + ) + || + ( + *old_vbi >= 50 && + new_vbi < *old_vbi && + new_vbi >= 50 + ) + ) + ) + ) + ) + { + *old_x = new_x; + *old_y = new_y; + *old_vbi = new_vbi; + return 1; + }else{ + return 0; } + } + + + + //--------------------------------------------------------- + + static uint32_t init( uint32_t width, uint32_t height, + uint32_t d_width,uint32_t d_height, + uint32_t fullscreen,char *title,uint32_t format ) + { + + int x_off, y_off; + + #ifdef HAVE_DGA2 + // needed to change DGA video mode + int modecount,mX, mY, mVBI, i,j; + int dga_modenum; + XDGAMode *modelines=NULL; + XDGADevice *dgadevice; + #else + int bank, ram; + #endif + + if( vo_dga_is_running )return -1; + + + if( !vo_init() ){ + printf("vo_dga: vo_init() failed!\n"); + return 0; + } + + if (format == IMGFMT_YV12 ){ + vo_dga_planes = vo_depthonscreen; + vo_dga_planes = vo_dga_planes == 15 ? 16 : vo_dga_planes; + }else{ + vo_dga_planes = (format & 0xff); + + // hack!!! here we should only get what we told in query_format() + // but mplayer is somewhat generous about 15/16bit depth ... + + vo_dga_planes = vo_dga_planes == 15 ? 16 : vo_dga_planes; + } + + if((vo_dga_dpy = XOpenDisplay(0))==NULL) + { + printf ("vo_dga: Can't open display\n"); + return 1; + } + + vo_dga_bpp = (vo_dga_planes+7) >> 3; + + // choose a suitable mode ... + + #ifdef HAVE_DGA2 + // Code to change the video mode added by Michael Graffam + // mgraffam@idsi.net + if (modelines==NULL) + modelines=XDGAQueryModes(vo_dga_dpy, XDefaultScreen(vo_dga_dpy),&modecount); + + mX=modelines[0].imageWidth; + mY=modelines[0].imageHeight; + mVBI = modelines[0].verticalRefresh; + + + printf("vo_dga: Using DGA 2.0 mode changing support\n"); + j=0; + // offbyone-error !!! i<=modecount is WRONG !!! + for (i=1; i<modecount; i++) + { + if( modelines[i].bitsPerPixel == vo_dga_planes) + { + printf("vo_dga: (%3d) Trying %4d x %4d @ %3d Hz @ %2d bpp ..", + i, + modelines[i].viewportWidth, + modelines[i].viewportHeight, + (unsigned int) modelines[i].verticalRefresh, + modelines[i].bitsPerPixel ); + + if ( check_mode(d_width, d_height, + modelines[i].viewportWidth, + modelines[i].viewportHeight, + (unsigned) modelines[i].verticalRefresh, + &mX, &mY, &mVBI )) + { + j = i; + printf(".ok!!\n"); + }else{ + printf(".no\n"); + } + } } printf("vo_dga: Selected video mode %4d x %4d @ %3d Hz for image size %3d x %3d.\n", mX, mY, mVBI, width, height); + + vo_dga_vp_width =mX; + vo_dga_vp_height = mY; + vo_dga_width = modelines[j].bytesPerScanline / vo_dga_bpp; + dga_modenum = modelines[j].num; + + XFree(modelines); + modelines = NULL; + + #else ! printf("vo_dga: DGA 1.0 compatibility code: mode switching not supported (yet)!\n"); ! ! // assume these values are already known at this stage some day ! // so that the following check for video <-> screen size can be done ... ! ! vo_dga_vp_width = 1280; ! vo_dga_vp_height = 1024; ! ! #endif ! ! ! vo_dga_src_format = format; ! vo_dga_src_width = width; ! vo_dga_src_height = height; ! ! if(vo_dga_src_width > vo_dga_vp_width || ! vo_dga_src_height > vo_dga_vp_height) ! { ! printf("vo_dga: Sorry, video larger than viewport is not yet supported!\n"); ! // ugly, do something nicer in the future ... ! return 1; ! } ! ! // now lets start the DGA thing ! ! #ifdef HAVE_DGA2 ! ! if (!XDGAOpenFramebuffer(vo_dga_dpy, XDefaultScreen(vo_dga_dpy))){ ! printf("vo_dga: Framebuffer mapping failed!!!\n"); ! XCloseDisplay(vo_dga_dpy); ! return 1; ! } ! dgadevice=XDGASetMode(vo_dga_dpy, XDefaultScreen(vo_dga_dpy), dga_modenum); XDGASync(vo_dga_dpy, XDefaultScreen(vo_dga_dpy)); ! vo_dga_base = dgadevice->data; XFree(dgadevice); ! ! XDGASetViewport (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0, 0, XDGAFlipRetrace); ! #else XF86DGAGetViewPortSize(vo_dga_dpy,XDefaultScreen(vo_dga_dpy), *************** *** 316,351 **** (char **)&vo_dga_base, &vo_dga_width, &bank, &ram); ! #ifndef HAVE_DGA2 XF86DGASetViewPort (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0, 0); #endif // do some more checkings here ... - if( format==IMGFMT_YV12 ) - yuv2rgb_init( vo_depthonscreen, MODE_RGB ); ! vo_dga_src_format = format; ! vo_dga_src_width = width; ! vo_dga_src_height = height; ! vo_dga_bpp = (vo_depthonscreen+7) >> 3; printf("vo_dga: bytes/line: %d, screen res: %dx%d, depth: %d, base: %08x, bpp: %d\n", vo_dga_width, vo_dga_vp_width, ! vo_dga_vp_height, vo_depthonscreen, vo_dga_base, vo_dga_bpp); - printf("vo_dga: video res: %dx%d\n", vo_dga_src_width, vo_dga_src_height); - if(vo_dga_src_width > vo_dga_vp_width || - vo_dga_src_height > vo_dga_vp_height){ - printf("vo_dga: Sorry, video larger than viewport is not yet supported!\n"); - // ugly, do something nicer in the future ... - return 1; - } - x_off = (vo_dga_vp_width - vo_dga_src_width)>>1; y_off = (vo_dga_vp_height - vo_dga_src_height)>>1; - - vo_dga_bytes_per_line = vo_dga_src_width * vo_dga_bpp; // todo - vo_dga_lines = vo_dga_src_height; // todo vo_dga_src_offset = 0; --- 540,566 ---- (char **)&vo_dga_base, &vo_dga_width, &bank, &ram); ! XF86DGADirectVideo (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), ! XF86DGADirectGraphics | XF86DGADirectMouse | ! XF86DGADirectKeyb); ! XF86DGASetViewPort (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), 0, 0); + #endif // do some more checkings here ... ! if( format==IMGFMT_YV12 ) ! yuv2rgb_init( vo_dga_planes == 16 ? 15 : vo_dga_planes , MODE_RGB ); printf("vo_dga: bytes/line: %d, screen res: %dx%d, depth: %d, base: %08x, bpp: %d\n", vo_dga_width, vo_dga_vp_width, ! vo_dga_vp_height, vo_dga_planes, vo_dga_base, vo_dga_bpp); x_off = (vo_dga_vp_width - vo_dga_src_width)>>1; y_off = (vo_dga_vp_height - vo_dga_src_height)>>1; + vo_dga_bytes_per_line = vo_dga_src_width * vo_dga_bpp; + vo_dga_lines = vo_dga_src_height; vo_dga_src_offset = 0; *************** *** 357,364 **** vo_dga_vp_offset, vo_dga_vp_skip, vo_dga_bytes_per_line); - - XF86DGADirectVideo (vo_dga_dpy, XDefaultScreen(vo_dga_dpy), - XF86DGADirectGraphics | XF86DGADirectMouse | - XF86DGADirectKeyb); XGrabKeyboard (vo_dga_dpy, DefaultRootWindow(vo_dga_dpy), True, --- 572,575 ---- _______________________________________________ Mplayer-cvslog mailing list Mplayer-cvslog@lists.sourceforge.net http://lists.sourceforge.net/lists/listinfo/mplayer-cvslog
participants (1)
-
Andreas Ackermann