# HG changeset patch # User Sam Lantinga # Date 1030767208 0 # Node ID f8482d7c959566ccdf9ec2f94ba2d7e8fcbbcba8 # Parent 22581630aab7e859d5c82f03bfc7bd8000a0ecbb Date: Tue, 27 Aug 2002 19:07:38 +0200 From: Denis Oliver Kropp Subject: YUV support I just added YUV overlay support to the DirectFB backend. diff -r 22581630aab7 -r f8482d7c9595 src/video/directfb/Makefile.am --- a/src/video/directfb/Makefile.am Sat Aug 31 04:06:37 2002 +0000 +++ b/src/video/directfb/Makefile.am Sat Aug 31 04:13:28 2002 +0000 @@ -12,4 +12,6 @@ SDL_DirectFB_events.c \ SDL_DirectFB_events.h \ SDL_DirectFB_video.c \ - SDL_DirectFB_video.h + SDL_DirectFB_video.h \ + SDL_DirectFB_yuv.c \ + SDL_DirectFB_yuv.h diff -r 22581630aab7 -r f8482d7c9595 src/video/directfb/SDL_DirectFB_video.c --- a/src/video/directfb/SDL_DirectFB_video.c Sat Aug 31 04:06:37 2002 +0000 +++ b/src/video/directfb/SDL_DirectFB_video.c Sat Aug 31 04:13:28 2002 +0000 @@ -46,6 +46,7 @@ #include "SDL_events_c.h" #include "SDL_DirectFB_video.h" #include "SDL_DirectFB_events.h" +#include "SDL_DirectFB_yuv.h" /* Initialization/Query functions */ @@ -123,6 +124,7 @@ device->SetVideoMode = DirectFB_SetVideoMode; device->SetColors = DirectFB_SetColors; device->UpdateRects = NULL; + device->CreateYUVOverlay = DirectFB_CreateYUVOverlay; device->VideoQuit = DirectFB_VideoQuit; device->AllocHWSurface = DirectFB_AllocHWSurface; device->CheckHWBlit = DirectFB_CheckHWBlit; diff -r 22581630aab7 -r f8482d7c9595 src/video/directfb/SDL_DirectFB_video.h --- a/src/video/directfb/SDL_DirectFB_video.h Sat Aug 31 04:06:37 2002 +0000 +++ b/src/video/directfb/SDL_DirectFB_video.h Sat Aug 31 04:13:28 2002 +0000 @@ -51,4 +51,6 @@ #define HIDDEN (this->hidden) +void SetDirectFBerror (const char *function, DFBResult code); + #endif /* _SDL_DirectFB_video_h */ diff -r 22581630aab7 -r f8482d7c9595 src/video/directfb/SDL_DirectFB_yuv.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/directfb/SDL_DirectFB_yuv.c Sat Aug 31 04:13:28 2002 +0000 @@ -0,0 +1,289 @@ +/* + 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 DirectFB implementation of YUV video overlays */ + +#include +#include + +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_DirectFB_yuv.h" +#include "SDL_yuvfuncs.h" + + +/* The functions used to manipulate software video overlays */ +static struct private_yuvhwfuncs directfb_yuvfuncs = { + DirectFB_LockYUVOverlay, + DirectFB_UnlockYUVOverlay, + DirectFB_DisplayYUVOverlay, + DirectFB_FreeYUVOverlay +}; + +struct private_yuvhwdata { + DFBDisplayLayerID layer_id; + + IDirectFBDisplayLayer *layer; + IDirectFBSurface *surface; + + /* These are just so we don't have to allocate them separately */ + Uint16 pitches[3]; + Uint8 *planes[3]; +}; + +static DFBEnumerationResult +enum_layers_callback( DFBDisplayLayerID id, + DFBDisplayLayerDescription desc, + void *data ) +{ + struct private_yuvhwdata *hwdata = (struct private_yuvhwdata *) data; + + /* we don't want the primary */ + if (id == DLID_PRIMARY) + return DFENUM_OK; + + /* take the one with a surface for video */ + if ((desc.caps & DLCAPS_SURFACE) && (desc.type & DLTF_VIDEO)) + { + hwdata->layer_id = id; + + return DFENUM_CANCEL; + } + + return DFENUM_OK; +} + + +static DFBResult CreateYUVSurface(_THIS, struct private_yuvhwdata *hwdata, + int width, int height, Uint32 format) +{ + DFBResult ret; + IDirectFB *dfb = HIDDEN->dfb; + IDirectFBDisplayLayer *layer; + DFBDisplayLayerConfig conf; + + ret = dfb->EnumDisplayLayers (dfb, enum_layers_callback, hwdata); + if (ret) + { + SetDirectFBerror("IDirectFB::EnumDisplayLayers", ret); + return ret; + } + + if (!hwdata->layer_id) + return DFB_UNSUPPORTED; + + ret = dfb->GetDisplayLayer (dfb, hwdata->layer_id, &layer); + if (ret) + { + SetDirectFBerror("IDirectFB::GetDisplayLayer", ret); + return ret; + } + + conf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT; + conf.width = width; + conf.height = height; + + switch (format) + { + case SDL_YV12_OVERLAY: + conf.pixelformat = DSPF_YV12; + break; + case SDL_IYUV_OVERLAY: + conf.pixelformat = DSPF_I420; + break; + case SDL_YUY2_OVERLAY: + conf.pixelformat = DSPF_YUY2; + break; + case SDL_UYVY_OVERLAY: + conf.pixelformat = DSPF_UYVY; + break; + default: + fprintf (stderr, "SDL_DirectFB: Unsupported YUV format (0x%08x)!\n", format); + break; + } + + ret = layer->SetConfiguration (layer, &conf); + if (ret) + { + SetDirectFBerror("IDirectFBDisplayLayer::SetConfiguration", ret); + layer->Release (layer); + return ret; + } + + ret = layer->GetSurface (layer, &hwdata->surface); + if (ret) + { + SetDirectFBerror("IDirectFBDisplayLayer::GetSurface", ret); + layer->Release (layer); + return ret; + } + + hwdata->layer = layer; + + return DFB_OK; +} + +SDL_Overlay *DirectFB_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) +{ + SDL_Overlay *overlay; + struct private_yuvhwdata *hwdata; + + /* Create the overlay structure */ + overlay = calloc (1, sizeof(SDL_Overlay)); + if (!overlay) + { + SDL_OutOfMemory(); + return NULL; + } + + /* Fill in the basic members */ + overlay->format = format; + overlay->w = width; + overlay->h = height; + + /* Set up the YUV surface function structure */ + overlay->hwfuncs = &directfb_yuvfuncs; + + /* Create the pixel data and lookup tables */ + hwdata = calloc(1, sizeof(struct private_yuvhwdata)); + overlay->hwdata = hwdata; + if (!hwdata) + { + SDL_OutOfMemory(); + SDL_FreeYUVOverlay (overlay); + return NULL; + } + + if (CreateYUVSurface (this, hwdata, width, height, format)) + { + SDL_FreeYUVOverlay (overlay); + return NULL; + } + + overlay->hw_overlay = 1; + + /* Set up the plane pointers */ + overlay->pitches = hwdata->pitches; + overlay->pixels = hwdata->planes; + switch (format) + { + case SDL_YV12_OVERLAY: + case SDL_IYUV_OVERLAY: + overlay->planes = 3; + break; + default: + overlay->planes = 1; + break; + } + + /* We're all done.. */ + return overlay; +} + +int DirectFB_LockYUVOverlay(_THIS, SDL_Overlay *overlay) +{ + DFBResult ret; + void *data; + unsigned int pitch; + IDirectFBSurface *surface = overlay->hwdata->surface; + + ret = surface->Lock (surface, DSLF_READ | DSLF_WRITE, &data, &pitch); + if (ret) + { + SetDirectFBerror("IDirectFBSurface::Lock", ret); + return -1; + } + + /* Find the pitch and offset values for the overlay */ + overlay->pitches[0] = (Uint16) pitch; + overlay->pixels[0] = (Uint8*) data; + + switch (overlay->format) + { + case SDL_YV12_OVERLAY: + case SDL_IYUV_OVERLAY: + /* Add the two extra planes */ + overlay->pitches[1] = overlay->pitches[0] / 2; + overlay->pitches[2] = overlay->pitches[0] / 2; + overlay->pixels[1] = overlay->pixels[0] + overlay->pitches[0] * overlay->h; + overlay->pixels[2] = overlay->pixels[1] + overlay->pitches[1] * overlay->h / 2; + break; + default: + /* Only one plane, no worries */ + break; + } + + return 0; +} + +void DirectFB_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay) +{ + IDirectFBSurface *surface = overlay->hwdata->surface; + + overlay->pixels[0] = overlay->pixels[1] = overlay->pixels[2] = NULL; + + surface->Unlock (surface); +} + +int DirectFB_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dst) +{ + DFBResult ret; + DFBDisplayLayerConfig conf; + IDirectFBDisplayLayer *primary = HIDDEN->layer; + IDirectFBDisplayLayer *layer = overlay->hwdata->layer; + + primary->GetConfiguration (primary, &conf); + + ret = layer->SetScreenLocation (layer, + dst->x / (float) conf.width, dst->y / (float) conf.height, + dst->w / (float) conf.width, dst->h / (float) conf.height ); + if (ret) + { + SetDirectFBerror("IDirectFBDisplayLayer::SetScreenLocation", ret); + return -1; + } + + return 0; +} + +void DirectFB_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) +{ + struct private_yuvhwdata *hwdata; + + hwdata = overlay->hwdata; + if (hwdata) + { + if (hwdata->surface) + hwdata->surface->Release (hwdata->surface); + + if (hwdata->layer) + hwdata->layer->Release (hwdata->layer); + + free (hwdata); + } +} + diff -r 22581630aab7 -r f8482d7c9595 src/video/directfb/SDL_DirectFB_yuv.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/directfb/SDL_DirectFB_yuv.h Sat Aug 31 04:13:28 2002 +0000 @@ -0,0 +1,42 @@ +/* + 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 DirectFB implementation of YUV video overlays */ + +#include "SDL_video.h" +#include "SDL_DirectFB_video.h" + +extern SDL_Overlay *DirectFB_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display); + +extern int DirectFB_LockYUVOverlay(_THIS, SDL_Overlay *overlay); + +extern void DirectFB_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay); + +extern int DirectFB_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect); + +extern void DirectFB_FreeYUVOverlay(_THIS, SDL_Overlay *overlay); +