diff options
Diffstat (limited to 'distrib/sdl-1.2.15/src/video/bwindow/SDL_sysyuv.cc')
-rw-r--r-- | distrib/sdl-1.2.15/src/video/bwindow/SDL_sysyuv.cc | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysyuv.cc b/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysyuv.cc new file mode 100644 index 0000000..7c71b00 --- /dev/null +++ b/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysyuv.cc @@ -0,0 +1,314 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2012 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 +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" |