comparison libvo/vo_sdl.c @ 784:dee122f9cdb9

Added full aspect awareness, rewrote fullscreen handling.
author atmosfear
date Sun, 13 May 2001 16:38:33 +0000
parents e70a52f17f92
children e09c92ca4c45
comparison
equal deleted inserted replaced
783:b03f5689175c 784:dee122f9cdb9
94 /* define to force software-surface (video surface stored in system memory)*/ 94 /* define to force software-surface (video surface stored in system memory)*/
95 #undef SDL_NOHWSURFACE 95 #undef SDL_NOHWSURFACE
96 96
97 //#define BUGGY_SDL //defined by configure 97 //#define BUGGY_SDL //defined by configure
98 98
99 /* MONITOR_ASPECT MUST BE FLOAT */
100 #define MONITOR_ASPECT 4.0/3.0
101
99 #include <stdio.h> 102 #include <stdio.h>
100 #include <stdlib.h> 103 #include <stdlib.h>
101 #include <string.h> 104 #include <string.h>
102 #include <inttypes.h> 105 #include <inttypes.h>
103 106
128 "" 131 ""
129 }; 132 };
130 133
131 #include <SDL/SDL.h> 134 #include <SDL/SDL.h>
132 135
136 #define FS 0x01
137 #define VM 0x02
138 #define ZOOM 0x04
139 #define FLIP 0x08
140
133 /** Private SDL Data structure **/ 141 /** Private SDL Data structure **/
134 142
135 static struct sdl_priv_s { 143 static struct sdl_priv_s {
136 144
137 /* output driver used by sdl */ 145 /* output driver used by sdl */
143 /* SDL RGB surface */ 151 /* SDL RGB surface */
144 SDL_Surface *rgbsurface; 152 SDL_Surface *rgbsurface;
145 153
146 /* SDL YUV overlay */ 154 /* SDL YUV overlay */
147 SDL_Overlay *overlay; 155 SDL_Overlay *overlay;
148
149 /* x,y video position for centering */
150 SDL_Rect vidpos;
151 156
152 /* available fullscreen modes */ 157 /* available fullscreen modes */
153 SDL_Rect **fullmodes; 158 SDL_Rect **fullmodes;
154 159
155 /* surface attributes for fullscreen and windowed mode */ 160 /* surface attributes for fullscreen and windowed mode */
169 174
170 /* current fullscreen mode, 0 = highest available fullscreen mode */ 175 /* current fullscreen mode, 0 = highest available fullscreen mode */
171 int fullmode; 176 int fullmode;
172 177
173 /* YUV ints */ 178 /* YUV ints */
174 int framePlaneY, framePlaneUV; 179 int framePlaneY, framePlaneUV, framePlaneYUY;
175 int stridePlaneY, stridePlaneUV; 180 int stridePlaneY, stridePlaneUV, stridePlaneYUY;
176 181
177 /* RGB ints */ 182 /* RGB ints */
178 int framePlaneRGB; 183 int framePlaneRGB;
179 int stridePlaneRGB; 184 int stridePlaneRGB;
180 185
181 /* Flip image */ 186 /* Flip image */
182 int flip; 187 int flip;
183 188
184 int width,height; 189 /* fullscreen behaviour; see init */
190 int fulltype;
191
192 #ifdef HAVE_X11
193 /* X11 Resolution */
194 int XWidth, XHeight;
195 #endif
196
197 /* original image dimensions */
198 int width, height;
199
200 /* destination dimensions */
201 int dstwidth, dstheight;
202
203 /* source image format (YUV/RGB/...) */
185 int format; 204 int format;
186 } sdl_priv; 205 } sdl_priv;
187 206
188 207
189 /** libvo Plugin functions **/ 208 /** libvo Plugin functions **/
407 if(verbose > 2) printf("SDL: Closed Plugin\n"); 426 if(verbose > 2) printf("SDL: Closed Plugin\n");
408 427
409 return 0; 428 return 0;
410 } 429 }
411 430
431 /**
432 * Do aspect ratio calculations
433 *
434 * params : srcw == sourcewidth
435 * srch == sourceheight
436 * dstw == destinationwidth
437 * dsth == destinationheight
438 *
439 * returns : SDL_Rect structure with new x and y, w and h
440 **/
441
442 static SDL_Rect aspect(int srcw, int srch, int dstw, int dsth) {
443 SDL_Rect newres;
444 if(verbose > 1) printf("SDL Aspect: src: %ix%i dst: %ix%i\n", srcw, srch, dstw, dsth);
445 newres.h = ((float)dstw / (float)srcw * (float)srch) * ((float)dsth/((float)dstw/(MONITOR_ASPECT)));
446 if(newres.h > dsth) {
447 newres.w = ((float)dsth / (float)newres.h) * dstw;
448 newres.h = dsth;
449 newres.x = (dstw - newres.w) / 2;
450 newres.y = 0;
451 }
452 else {
453 newres.w = dstw;
454 newres.x = 0;
455 newres.y = (dsth - newres.h) / 2;
456 }
457
458 if(verbose) printf("SDL Aspect-Destinationres: %ix%i (x: %i, y: %i)\n", newres.w, newres.h, newres.x, newres.y);
459
460 return newres;
461 }
412 462
413 /** 463 /**
414 * Sets the specified fullscreen mode. 464 * Sets the specified fullscreen mode.
415 * 465 *
416 * params : mode == index of the desired fullscreen mode 466 * params : mode == index of the desired fullscreen mode
417 * returns : doesn't return 467 * returns : doesn't return
418 **/ 468 **/
419 469
470 #if 0
420 static void set_fullmode (int mode) 471 static void set_fullmode (int mode)
421 { 472 {
422 struct sdl_priv_s *priv = &sdl_priv; 473 struct sdl_priv_s *priv = &sdl_priv;
423 SDL_Surface *newsurface = NULL; 474 SDL_Surface *newsurface = NULL;
424 int haspect, waspect = 0; 475 int haspect, waspect = 0;
444 if (newsurface) { 495 if (newsurface) {
445 priv->surface = newsurface; 496 priv->surface = newsurface;
446 SDL_ShowCursor(0); 497 SDL_ShowCursor(0);
447 } 498 }
448 //TODO: check if this produces memhole! (no surface freeing) 499 //TODO: check if this produces memhole! (no surface freeing)
449 priv->vidpos.x = (priv->surface->w - priv->width) / 2; 500 }
450 priv->vidpos.y = (priv->surface->h - priv->height) / 2; 501 #endif
451 } 502
452 503 static void set_fullmode (int mode) {
504 struct sdl_priv_s *priv = &sdl_priv;
505 SDL_Surface *newsurface = NULL;
506 SDL_Rect newsize;
507
508 /* if we haven't set a fullmode yet, default to the lowest res fullmode first */
509 if(mode < 0)
510 mode = priv->fullmode = findArrayEnd(priv->fullmodes) - 1;
511
512 /* calculate new video size/aspect */
513 if(priv->fulltype&FS) {
514 newsize = aspect(priv->width, priv->height, priv->XWidth ? priv->XWidth : priv->dstwidth, priv->XHeight ? priv->XHeight : priv->dstheight);
515 } else
516 if(priv->fulltype&VM) {
517 newsize = aspect(priv->dstwidth, priv->dstheight, priv->dstwidth, priv->dstwidth*((float)priv->XHeight / (float)priv->XWidth));
518 }
519 else {
520 newsize = aspect(priv->dstwidth, priv->dstheight, priv->fullmodes[mode]->w, priv->fullmodes[mode]->h);
521 }
522
523 /* try to change to given fullscreenmode */
524 newsurface = SDL_SetVideoMode(newsize.w, newsize.h, priv->bpp, priv->sdlfullflags);
525
526 /* if creation of new surface was successfull, save it and hide mouse cursor */
527 if(newsurface) {
528 priv->surface = newsurface;
529 SDL_ShowCursor(0);
530 }
531 }
532
453 533
454 /** 534 /**
455 * Initialize an SDL surface and an SDL YUV overlay. 535 * Initialize an SDL surface and an SDL YUV overlay.
456 * 536 *
457 * params : width == width of video we'll be displaying. 537 * params : width == width of video we'll be displaying.
465 init(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) 545 init(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format)
466 //static int sdl_setup (int width, int height) 546 //static int sdl_setup (int width, int height)
467 { 547 {
468 struct sdl_priv_s *priv = &sdl_priv; 548 struct sdl_priv_s *priv = &sdl_priv;
469 unsigned int sdl_format; 549 unsigned int sdl_format;
550 SDL_Rect res;
470 #ifdef HAVE_X11 551 #ifdef HAVE_X11
471 static Display *XDisplay; 552 static Display *XDisplay;
553 static int XScreen;
472 #endif 554 #endif
473 555
474 //priv->flip = 1; // debugging only
475
476 sdl_format = format; 556 sdl_format = format;
477 switch(format){ 557 switch(format){
478 case IMGFMT_YV12: 558 case IMGFMT_YV12:
479 if(verbose) printf("SDL: Using 0x%X (YV12) image format\n", format); break; 559 if(verbose) printf("SDL: Using 0x%X (YV12) image format\n", format); break;
480 case IMGFMT_IYUV: 560 case IMGFMT_IYUV:
525 default: 605 default:
526 printf("SDL: Unsupported image format (0x%X)\n",format); 606 printf("SDL: Unsupported image format (0x%X)\n",format);
527 return -1; 607 return -1;
528 } 608 }
529 609
530 sdl_open (NULL, NULL);
531 #ifdef HAVE_X11 610 #ifdef HAVE_X11
532 if(getenv("DISPLAY")) { 611 if(getenv("DISPLAY")) {
533 if(verbose) printf("SDL: deactivating XScreensaver/DPMS\n"); 612 if(verbose) printf("SDL: deactivating XScreensaver/DPMS\n");
534 XDisplay = XOpenDisplay(getenv("DISPLAY")); 613 XDisplay = XOpenDisplay(getenv("DISPLAY"));
614 XScreen = DefaultScreen(XDisplay);
615 priv->XWidth = DisplayWidth(XDisplay, XScreen);
616 priv->XHeight = DisplayHeight(XDisplay, XScreen);
617 if(verbose) printf("SDL: X11 Resolution %ix%i\n", priv->XWidth, priv->XHeight);
535 saver_off(XDisplay); 618 saver_off(XDisplay);
536 XCloseDisplay(XDisplay); 619 XCloseDisplay(XDisplay);
537 } 620 }
538 #endif 621 #endif
622 sdl_open (NULL, NULL);
539 623
540 /* Set output window title */ 624 /* Set output window title */
541 SDL_WM_SetCaption (".: MPlayer : F = Fullscreen/Windowed : C = Cycle Fullscreen Resolutions :.", "SDL Video Out"); 625 SDL_WM_SetCaption (".: MPlayer : F = Fullscreen/Windowed : C = Cycle Fullscreen Resolutions :.", "SDL Video Out");
542 //SDL_WM_SetCaption (title, title); 626 //SDL_WM_SetCaption (title, title);
543 627
544 /* Save the original Image size */ 628 /* Save the original Image size */
545 629
546 //priv->width = d_width ? d_width : width;
547 //priv->height = d_height ? d_height : height;
548 priv->width = width; 630 priv->width = width;
549 priv->height = height; 631 priv->height = height;
632 priv->dstwidth = d_width ? d_width : width;
633 priv->dstheight = d_height ? d_height : height;
634
635 /*priv->width = res.w;
636 priv->height = res.h;*/
550 priv->format = format; 637 priv->format = format;
551 priv->windowsize.w = d_width ? d_width : width; 638 #ifdef HAVE_X11
552 priv->windowsize.h = d_height ? d_height : height; 639 res = aspect(priv->dstwidth, priv->dstheight, priv->dstwidth, priv->dstwidth*((float)priv->XHeight / (float)priv->XWidth));
640 priv->windowsize.w = res.w;
641 priv->windowsize.h = res.h;
642 #else
643 priv->windowsize.w = priv->dstwidth;
644 priv->windowsize.h = priv->dstheight;
645 #endif
553 646
554 /* bit 0 (0x01) means fullscreen (-fs) 647 /* bit 0 (0x01) means fullscreen (-fs)
555 * bit 1 (0x02) means mode switching (-vm) 648 * bit 1 (0x02) means mode switching (-vm)
556 * bit 2 (0x04) enables software scaling (-zoom) 649 * bit 2 (0x04) enables software scaling (-zoom)
557 * bit 3 (0x08) enables flipping (-flip) 650 * bit 3 (0x08) enables flipping (-flip)
558 */ 651 */
559 #define FS 0x01
560 #define VM 0x02
561 #define ZOOM 0x04
562 #define FLIP 0x08
563 // printf("SDL: flags are set to: %i\n", flags); 652 // printf("SDL: flags are set to: %i\n", flags);
564 // printf("SDL: Width: %i Height: %i D_Width %i D_Height: %i\n", width, height, d_width, d_height); 653 // printf("SDL: Width: %i Height: %i D_Width %i D_Height: %i\n", width, height, d_width, d_height);
565 if(flags&FLIP) { // flipping flag set, use it 654 if(flags&FLIP) {
566 if(verbose) printf("SDL: using flipped video (only with RGB/BGR)\n"); 655 if(verbose) printf("SDL: using flipped video (only with RGB/BGR/packed YUV)\n");
567 priv->flip = 1; 656 priv->flip = 1;
568 } 657 }
569 if(flags&FS) { 658 if(flags&FS) {
570 priv->width = width;
571 priv->height = height;
572 if(verbose) printf("SDL: setting zoomed fullscreen without modeswitching\n"); 659 if(verbose) printf("SDL: setting zoomed fullscreen without modeswitching\n");
573 printf("SDL: Info - please use -vm (unscaled) or -zoom (scaled) for best fullscreen experience\n"); 660 printf("SDL: Info - please use -vm (unscaled) or -zoom (scaled) for best fullscreen experience\n");
574 if((priv->surface = SDL_SetVideoMode (d_width, d_height, priv->bpp, priv->sdlfullflags))) 661 priv->surface = NULL;
575 SDL_ShowCursor(0); 662 priv->fulltype = FS;
663 set_fullmode(priv->fullmode);
664 /*if((priv->surface = SDL_SetVideoMode (d_width, d_height, priv->bpp, priv->sdlfullflags)))
665 SDL_ShowCursor(0);*/
576 } else 666 } else
577 if(flags&VM) { 667 if(flags&VM) {
578 if(verbose) printf("SDL: setting nonzoomed fullscreen with modeswitching\n"); 668 if(verbose) printf("SDL: setting nonzoomed fullscreen with modeswitching\n");
579 printf("SDL: Info - please use -zoom switch to scale video\n"); 669 printf("SDL: Info - please use -zoom switch to scale video\n");
580 if((priv->surface = SDL_SetVideoMode (d_width ? d_width : width, d_height ? d_height : height, priv->bpp, priv->sdlfullflags))) 670
581 SDL_ShowCursor(0); 671 priv->surface = NULL;
672 priv->fulltype = VM;
673 set_fullmode(priv->fullmode);
674 /*if((priv->surface = SDL_SetVideoMode (d_width ? d_width : width, d_height ? d_height : height, priv->bpp, priv->sdlfullflags)))
675 SDL_ShowCursor(0);*/
582 } else 676 } else
583 if(flags&ZOOM) { 677 if(flags&ZOOM) {
584 if(verbose) printf("SDL: setting zoomed fullscreen with modeswitching\n"); 678 if(verbose) printf("SDL: setting zoomed fullscreen with modeswitching\n");
585 printf("SDL: Info - please use -vm switch instead if you don't want scaled video\n"); 679 printf("SDL: Info - please use -vm switch instead if you don't want scaled video\n");
586 priv->surface=NULL; 680
587 set_fullmode(priv->fullmode); 681 priv->surface = NULL;
682 priv->fulltype = ZOOM;
683 set_fullmode(priv->fullmode);
588 } 684 }
589 else { 685 else {
590 if(verbose) printf("SDL: setting windowed mode\n"); 686 if(strcmp(priv->driver, "x11") == 0) {
591 if((priv->surface = SDL_SetVideoMode (d_width, d_height, priv->bpp, priv->sdlflags)) 687 if(verbose) printf("SDL: setting windowed mode\n");
592 && (strcmp(priv->driver, "dga") == 0)) SDL_ShowCursor(0); //TODO: other sdl drivers that are fullscreen only? 688 #ifdef HAVE_X11
689 priv->surface = SDL_SetVideoMode (res.w, res.h, priv->bpp, priv->sdlflags);
690 #else
691 priv->surface = SDL_SetVideoMode (priv->dstwidth, priv->dstheight, priv->bpp, priv->sdlflags);
692 #endif
693 }
694 else {
695 if(verbose) printf("SDL: setting nonzoomed fullscreen with modeswitching\n");
696 printf("SDL: Info - please use -zoom switch to scale video\n");
697
698 priv->surface = NULL;
699 priv->fulltype = VM;
700 set_fullmode(priv->fullmode);
701 }
593 } 702 }
594 703
595 if(!priv->surface) { // cannot SetVideoMode 704 if(!priv->surface) { // cannot SetVideoMode
596 printf("SDL: failed to set video mode: %s\n", SDL_GetError()); 705 printf("SDL: failed to set video mode: %s\n", SDL_GetError());
597 return -1; 706 return -1;
660 printf ("SDL: Couldn't create a YUV overlay: %s\n", SDL_GetError()); 769 printf ("SDL: Couldn't create a YUV overlay: %s\n", SDL_GetError());
661 return -1; 770 return -1;
662 } 771 }
663 priv->framePlaneY = width * height; 772 priv->framePlaneY = width * height;
664 priv->framePlaneUV = (width * height) >> 2; 773 priv->framePlaneUV = (width * height) >> 2;
774 priv->framePlaneYUY = width * height * 2;
665 priv->stridePlaneY = width; 775 priv->stridePlaneY = width;
666 priv->stridePlaneUV = width/2; 776 priv->stridePlaneUV = width/2;
777 priv->stridePlaneYUY = width * 2;
667 } 778 }
668 779
669 if(priv->mode) { 780 if(priv->mode) {
670 priv->framePlaneRGB = width * height * priv->rgbsurface->format->BytesPerPixel; 781 priv->framePlaneRGB = width * height * priv->rgbsurface->format->BytesPerPixel;
671 priv->stridePlaneRGB = width * priv->rgbsurface->format->BytesPerPixel; 782 priv->stridePlaneRGB = width * priv->rgbsurface->format->BytesPerPixel;
712 /*if (SDL_LockYUVOverlay (priv->overlay)) { 823 /*if (SDL_LockYUVOverlay (priv->overlay)) {
713 if(verbose) printf("SDL: Couldn't lock YUV overlay\n"); 824 if(verbose) printf("SDL: Couldn't lock YUV overlay\n");
714 return -1; 825 return -1;
715 }*/ 826 }*/
716 dst = (uint8_t *) *(priv->overlay->pixels); 827 dst = (uint8_t *) *(priv->overlay->pixels);
717 memcpy (dst, src[0], priv->width*priv->height*2); 828 if(priv->flip) {
829 mysrc+=priv->framePlaneYUY;
830 for(i = 0; i < priv->height; i++) {
831 mysrc-=priv->stridePlaneYUY;
832 memcpy (dst, mysrc, priv->stridePlaneYUY);
833 dst+=priv->stridePlaneYUY;
834 }
835 }
836 else memcpy (dst, src[0], priv->framePlaneYUY);
718 /*SDL_UnlockYUVOverlay (priv->overlay);*/ 837 /*SDL_UnlockYUVOverlay (priv->overlay);*/
719 break; 838 break;
720 839
721 case IMGFMT_RGB15: 840 case IMGFMT_RGB15:
722 case IMGFMT_BGR15: 841 case IMGFMT_BGR15:
967 case IMGFMT_RGB24: 1086 case IMGFMT_RGB24:
968 case IMGFMT_BGR24: 1087 case IMGFMT_BGR24:
969 case IMGFMT_RGB32: 1088 case IMGFMT_RGB32:
970 case IMGFMT_BGR32: 1089 case IMGFMT_BGR32:
971 /* blit to the RGB surface */ 1090 /* blit to the RGB surface */
972 blitconv = SDL_DisplayFormat(priv->rgbsurface); 1091 blitconv = SDL_DisplayFormat(priv->rgbsurface);
973 if(SDL_BlitSurface (blitconv, NULL, priv->surface, &priv->vidpos)) 1092 if(SDL_BlitSurface (blitconv, NULL, priv->surface, NULL))
974 printf("SDL: Blit failed: %s\n", SDL_GetError()); 1093 printf("SDL: Blit failed: %s\n", SDL_GetError());
975 SDL_FreeSurface(blitconv); 1094 SDL_FreeSurface(blitconv);
976 1095
977 /*if(SDL_MUSTLOCK(priv->surface)) {
978 if (SDL_LockSurface (priv->surface)) {
979 if(verbose) printf("SDL: Couldn't lock RGB surface\n");
980 return;
981 }
982 }*/
983 /* update screen */ 1096 /* update screen */
984 SDL_UpdateRect(priv->surface, priv->vidpos.x, priv->vidpos.y, priv->width, priv->height); 1097 //SDL_UpdateRect(priv->surface, 0, 0, priv->surface->clip_rect.w, priv->surface->clip_rect.h);
985 /*if(SDL_MUSTLOCK(priv->surface)) 1098 SDL_UpdateRects(priv->surface, 1, &priv->surface->clip_rect);
986 SDL_UnlockSurface (priv->surface);*/
987 1099
988 /* check if we have a double buffered surface and flip() if we do. */ 1100 /* check if we have a double buffered surface and flip() if we do. */
989 if ( priv->surface->flags & SDL_DOUBLEBUF ) 1101 if ( priv->surface->flags & SDL_DOUBLEBUF )
990 SDL_Flip(priv->surface); 1102 SDL_Flip(priv->surface);
991 1103