Mercurial > sdl-ios-xcode
view src/video/bwindow/SDL_sysyuv.cc @ 1662:782fd950bd46 SDL-1.3
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.
WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.
The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce
The headers are being converted to automatically generate doxygen documentation.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 28 May 2006 13:04:16 +0000 |
parents | 51038e80ae59 |
children | 4da1ee79c9af |
line wrap: on
line source
/* SDL - Simple DirectMedia Layer Copyright (C) 1997-2006 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Sam Lantinga slouken@libsdl.org */ #include "SDL_config.h" /* This is the BeOS version of SDL YUV video overlays */ #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 *) SDL_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 *) SDL_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 *) SDL_calloc (overlay->planes, sizeof (Uint16)); overlay->pixels = (Uint8 **) SDL_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 * src, SDL_Rect * dst) { 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 + dst->x, top + dst->y); } else { bview->MoveTo (dst->x, dst->y); } bview->ResizeTo (dst->w, dst->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; SDL_free (overlay->hwdata); } }; // extern "C" /* vi: set ts=4 sw=4 expandtab: */