Mercurial > sdl-ios-xcode
changeset 756:10332c6fad2e
te: Mon, 15 Dec 2003 08:25:14 -0800 PST
From: "Andrew Bachmann"
Subject: libSDL patches for beos video
I created some patches to SDL:
1. YUV overlay support
2. maintain high refresh rate when changing resolutions to a lower resolution
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 16 Dec 2003 13:04:44 +0000 |
parents | b1595db396a7 |
children | 4f46fee887fe |
files | src/video/bwindow/Makefile.am src/video/bwindow/SDL_BView.h src/video/bwindow/SDL_lowvideo.h src/video/bwindow/SDL_sysvideo.cc src/video/bwindow/SDL_sysyuv.cc src/video/bwindow/SDL_sysyuv.h |
diffstat | 6 files changed, 430 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/video/bwindow/Makefile.am Sun Dec 14 06:28:07 2003 +0000 +++ b/src/video/bwindow/Makefile.am Tue Dec 16 13:04:44 2003 +0000 @@ -15,5 +15,7 @@ SDL_sysmouse_c.h \ SDL_sysvideo.cc \ SDL_syswm.cc \ - SDL_syswm_c.h + SDL_syswm_c.h \ + SDL_sysyuv.cc \ + SDL_sysyuv.h
--- a/src/video/bwindow/SDL_BView.h Sun Dec 14 06:28:07 2003 +0000 +++ b/src/video/bwindow/SDL_BView.h Tue Dec 16 13:04:44 2003 +0000 @@ -20,6 +20,9 @@ slouken@libsdl.org */ +#ifndef _SDL_BView_h +#define _SDL_BView_h + #ifdef SAVE_RCSID static char rcsid = "@(#) $Id$"; @@ -109,3 +112,5 @@ BBitmap *image; int xoff, yoff; }; + +#endif /* _SDL_BView_h */
--- a/src/video/bwindow/SDL_lowvideo.h Sun Dec 14 06:28:07 2003 +0000 +++ b/src/video/bwindow/SDL_lowvideo.h Tue Dec 16 13:04:44 2003 +0000 @@ -28,6 +28,7 @@ #ifndef _SDL_lowvideo_h #define _SDL_lowvideo_h +#include "SDL_BWin.h" #include "SDL_mouse.h" #include "SDL_sysvideo.h" @@ -55,6 +56,8 @@ /* Keyboard state variables */ int key_flip; struct key_info keyinfo[2]; + + SDL_Overlay *overlay; }; /* Old variable names */ #define SDL_Win (_this->hidden->SDL_Win) @@ -66,5 +69,6 @@ #define last_point (_this->hidden->last_point) #define key_flip (_this->hidden->key_flip) #define keyinfo (_this->hidden->keyinfo) +#define current_overlay (_this->hidden->overlay) #endif /* _SDL_lowvideo_h */
--- a/src/video/bwindow/SDL_sysvideo.cc Sun Dec 14 06:28:07 2003 +0000 +++ b/src/video/bwindow/SDL_sysvideo.cc Tue Dec 16 13:04:44 2003 +0000 @@ -47,6 +47,8 @@ #include "SDL_events_c.h" #include "SDL_syswm_c.h" #include "SDL_lowvideo.h" +#include "SDL_yuvfuncs.h" +#include "SDL_sysyuv.h" #define BEOS_HIDDEN_SIZE 32 /* starting hidden window size */ @@ -65,6 +67,7 @@ static void BE_FreeHWSurface(_THIS, SDL_Surface *surface); static int BE_ToggleFullScreen(_THIS, int fullscreen); +static SDL_Overlay *BE_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display); /* OpenGL functions */ #ifdef HAVE_OPENGL @@ -136,6 +139,7 @@ device->free = BE_DeleteDevice; device->ToggleFullScreen = BE_ToggleFullScreen; + device->CreateYUVOverlay = BE_CreateYUVOverlay; /* Set the driver flags */ device->handles_any_size = 1; @@ -330,6 +334,11 @@ uint32 i, nmodes; SDL_Rect **modes; display_mode *dmodes; + display_mode current; + float current_refresh; + bscreen.GetMode(¤t); + current_refresh = (1000 * current.timing.pixel_clock) / + (current.timing.h_total * current.timing.v_total); modes = SDL_modelist[((bpp+7)/8)-1]; for ( i=0; modes[i] && (modes[i]->w > width) && @@ -351,6 +360,15 @@ } if ( i != nmodes ) { *mode = dmodes[i]; + if ((mode->virtual_width <= current.virtual_width) && + (mode->virtual_height <= current.virtual_height)) { + float new_refresh = (1000 * mode->timing.pixel_clock) / + (mode->timing.h_total * mode->timing.v_total); + if (new_refresh < current_refresh) { + mode->timing.pixel_clock = (uint32)((mode->timing.h_total * mode->timing.v_total) + * current_refresh / 1000); + } + } return true; } else { return false;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/bwindow/SDL_sysyuv.cc Tue Dec 16 13:04:44 2003 +0000 @@ -0,0 +1,323 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* This is the BeOS version of SDL YUV video overlays */ + +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_sysyuv.h" +#include "SDL_yuvfuncs.h" + +extern "C" { + +/* The functions used to manipulate software video overlays */ +static struct private_yuvhwfuncs be_yuvfuncs = +{ + BE_LockYUVOverlay, + BE_UnlockYUVOverlay, + BE_DisplayYUVOverlay, + BE_FreeYUVOverlay +}; + +BBitmap * BE_GetOverlayBitmap(BRect bounds, color_space cs) { + BBitmap *bbitmap; + bbitmap = new BBitmap(bounds,B_BITMAP_WILL_OVERLAY,cs); + if (!bbitmap || bbitmap->InitCheck() != B_OK) { + delete bbitmap; + return 0; + } + overlay_restrictions r; + bbitmap->GetOverlayRestrictions(&r); + uint32 width = bounds.IntegerWidth() + 1; + uint32 height = bounds.IntegerHeight() + 1; + uint32 width_padding = 0; + uint32 height_padding = 0; + if ((r.source.horizontal_alignment != 0) || + (r.source.vertical_alignment != 0)) { + delete bbitmap; + return 0; + } + if (r.source.width_alignment != 0) { + uint32 aligned_width = r.source.width_alignment + 1; + if (width % aligned_width > 0) { + width_padding = aligned_width - width % aligned_width; + } + } + if (r.source.height_alignment != 0) { + uint32 aligned_height = r.source.height_alignment + 1; + if (height % aligned_height > 0) { + fprintf(stderr,"GetOverlayBitmap failed height alignment\n"); + fprintf(stderr,"- height = %lu, aligned_height = %lu\n",height,aligned_height); + delete bbitmap; + return 0; + } + } + if ((r.source.min_width > width) || + (r.source.min_height > height) || + (r.source.max_width < width) || + (r.source.max_height < height)) { + fprintf(stderr,"GetOverlayBitmap failed bounds tests\n"); + delete bbitmap; + return 0; + } + if ((width_padding != 0) || (height_padding != 0)) { + delete bbitmap; + bounds.Set(bounds.left,bounds.top,bounds.right+width_padding,bounds.bottom+height_padding); + bbitmap = new BBitmap(bounds,B_BITMAP_WILL_OVERLAY,cs); + if (!bbitmap || bbitmap->InitCheck() != B_OK) { + fprintf(stderr,"GetOverlayBitmap failed late\n"); + delete bbitmap; + return 0; + } + } + return bbitmap; +} + +// See <GraphicsDefs.h> [btw: Cb=U, Cr=V] +// See also http://www.fourcc.org/indexyuv.htm +enum color_space convert_color_space(Uint32 format) { + switch (format) { + case SDL_YV12_OVERLAY: + return B_YUV9; + case SDL_IYUV_OVERLAY: + return B_YUV12; + case SDL_YUY2_OVERLAY: + return B_YCbCr422; + case SDL_UYVY_OVERLAY: + return B_YUV422; + case SDL_YVYU_OVERLAY: // not supported on beos? + return B_NO_COLOR_SPACE; + default: + return B_NO_COLOR_SPACE; + } +} + +// See SDL_video.h +int count_planes(Uint32 format) { + switch (format) { + case SDL_YV12_OVERLAY: + case SDL_IYUV_OVERLAY: + return 3; + case SDL_YUY2_OVERLAY: + case SDL_UYVY_OVERLAY: + case SDL_YVYU_OVERLAY: + return 1; + default: + return 0; + } +} + +SDL_Overlay *BE_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) { + SDL_Overlay* overlay; + struct private_yuvhwdata* hwdata; + BBitmap *bbitmap; + int planes; + BRect bounds; + color_space cs; + + /* find the appropriate BeOS colorspace descriptor */ + cs = convert_color_space(format); + if (cs == B_NO_COLOR_SPACE) + { + return NULL; + } + + /* count planes */ + planes = count_planes(format); + if (planes == 0) + { + return NULL; + } + /* TODO: figure out planar modes, if anyone cares */ + if (planes == 3) + { + return NULL; + } + + /* Create the overlay structure */ + overlay = (SDL_Overlay*)calloc(1, sizeof(SDL_Overlay)); + + if (overlay == NULL) + { + SDL_OutOfMemory(); + return NULL; + } + + /* Fill in the basic members */ + overlay->format = format; + overlay->w = width; + overlay->h = height; + overlay->hwdata = NULL; + + /* Set up the YUV surface function structure */ + overlay->hwfuncs = &be_yuvfuncs; + + /* Create the pixel data and lookup tables */ + hwdata = (struct private_yuvhwdata*)calloc(1, sizeof(struct private_yuvhwdata)); + + if (hwdata == NULL) + { + SDL_OutOfMemory(); + SDL_FreeYUVOverlay(overlay); + return NULL; + } + + overlay->hwdata = hwdata; + overlay->hwdata->display = display; + overlay->hwdata->bview = NULL; + overlay->hwdata->bbitmap = NULL; + overlay->hwdata->locked = 0; + + /* Create the BBitmap framebuffer */ + bounds.top = 0; bounds.left = 0; + bounds.right = width-1; + bounds.bottom = height-1; + + BView * bview = new BView(bounds,"overlay",B_FOLLOW_NONE,B_WILL_DRAW); + if (!bview) { + SDL_OutOfMemory(); + SDL_FreeYUVOverlay(overlay); + return NULL; + } + overlay->hwdata->bview = bview; + overlay->hwdata->first_display = true; + bview->Hide(); + + bbitmap = BE_GetOverlayBitmap(bounds,cs); + if (!bbitmap) { + overlay->hwdata->bbitmap = NULL; + SDL_FreeYUVOverlay(overlay); + return NULL; + } + overlay->hwdata->bbitmap = bbitmap; + + overlay->planes = planes; + overlay->pitches = (Uint16*)calloc(overlay->planes, sizeof(Uint16)); + overlay->pixels = (Uint8**)calloc(overlay->planes, sizeof(Uint8*)); + if (!overlay->pitches || !overlay->pixels) + { + SDL_OutOfMemory(); + SDL_FreeYUVOverlay(overlay); + return(NULL); + } + + overlay->pitches[0] = bbitmap->BytesPerRow(); + overlay->pixels[0] = (Uint8 *)bbitmap->Bits(); + overlay->hw_overlay = 1; + + if (SDL_Win->LockWithTimeout(1000000) != B_OK) { + SDL_FreeYUVOverlay(overlay); + return(NULL); + } + BView * view = SDL_Win->View(); + view->AddChild(bview); + rgb_color key; + bview->SetViewOverlay(bbitmap,bounds,bview->Bounds(),&key,B_FOLLOW_ALL, + B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL); + bview->SetViewColor(key); + bview->Flush(); + SDL_Win->Unlock(); + + current_overlay=overlay; + + return overlay; +} + +int BE_LockYUVOverlay(_THIS, SDL_Overlay* overlay) +{ + if (overlay == NULL) + { + return 0; + } + + overlay->hwdata->locked = 1; + return 0; +} + +void BE_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay) +{ + if (overlay == NULL) + { + return; + } + + overlay->hwdata->locked = 0; +} + +int BE_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* dstrect) +{ + if ((overlay == NULL) || (overlay->hwdata==NULL) + || (overlay->hwdata->bview==NULL) || (SDL_Win->View() == NULL)) + { + return -1; + } + if (SDL_Win->LockWithTimeout(50000) != B_OK) { + return 0; + } + BView * bview = overlay->hwdata->bview; + if (SDL_Win->IsFullScreen()) { + int left,top; + SDL_Win->GetXYOffset(left,top); + bview->MoveTo(left+dstrect->x,top+dstrect->y); + } else { + bview->MoveTo(dstrect->x,dstrect->y); + } + bview->ResizeTo(dstrect->w,dstrect->h); + bview->Flush(); + if (overlay->hwdata->first_display) { + bview->Show(); + overlay->hwdata->first_display = false; + } + SDL_Win->Unlock(); + + return 0; +} + +void BE_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) +{ + if (overlay == NULL) + { + return; + } + + if (overlay->hwdata == NULL) + { + return; + } + + current_overlay=NULL; + + delete overlay->hwdata->bbitmap; + + free(overlay->hwdata); +} + +}; // extern "C"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/bwindow/SDL_sysyuv.h Tue Dec 16 13:04:44 2003 +0000 @@ -0,0 +1,77 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + + +#ifndef __SDL_SYS_YUV_H__ +#define __SDL_SYS_YUV_H__ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif /* SAVE_RCSID */ + +/* This is the BeOS implementation of YUV video overlays */ + +#include "SDL_video.h" +#include "SDL_lowvideo.h" + +extern "C" { + +struct private_yuvhwdata +{ +/* FRAMEDATA* CurrentFrameData; + FRAMEDATA* FrameData0; + FRAMEDATA* FrameData1; + PgScalerProps_t props; + PgScalerCaps_t caps; + PgVideoChannel_t* channel; + PhArea_t CurrentViewPort; + PhPoint_t CurrentWindowPos; + long format; + int scaler_on; + int current; + long YStride; + long VStride; + long UStride; + int ischromakey; + long chromakey; + int forcedredraw; + unsigned long State; + long flags; +*/ + SDL_Surface *display; + BView *bview; + bool first_display; + BBitmap *bbitmap; + int locked; +}; + +extern BBitmap * BE_GetOverlayBitmap(BRect bounds, color_space cs); +extern SDL_Overlay* BE_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface* display); +extern int BE_LockYUVOverlay(_THIS, SDL_Overlay* overlay); +extern void BE_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay); +extern int BE_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* dstrect); +extern void BE_FreeYUVOverlay(_THIS, SDL_Overlay* overlay); + +}; + +#endif /* __SDL_PH_YUV_H__ */