Date: Tue, 27 Aug 2002 19:07:38 +0200
authorSam Lantinga <slouken@libsdl.org>
Sat, 31 Aug 2002 04:13:28 +0000
changeset 478f8482d7c9595
parent 477 22581630aab7
child 479 c0a1744bc2cf
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.
src/video/directfb/Makefile.am
src/video/directfb/SDL_DirectFB_video.c
src/video/directfb/SDL_DirectFB_video.h
src/video/directfb/SDL_DirectFB_yuv.c
src/video/directfb/SDL_DirectFB_yuv.h
     1.1 --- a/src/video/directfb/Makefile.am	Sat Aug 31 04:06:37 2002 +0000
     1.2 +++ b/src/video/directfb/Makefile.am	Sat Aug 31 04:13:28 2002 +0000
     1.3 @@ -12,4 +12,6 @@
     1.4  	SDL_DirectFB_events.c	\
     1.5  	SDL_DirectFB_events.h	\
     1.6  	SDL_DirectFB_video.c	\
     1.7 -	SDL_DirectFB_video.h
     1.8 +	SDL_DirectFB_video.h	\
     1.9 +	SDL_DirectFB_yuv.c	\
    1.10 +	SDL_DirectFB_yuv.h
     2.1 --- a/src/video/directfb/SDL_DirectFB_video.c	Sat Aug 31 04:06:37 2002 +0000
     2.2 +++ b/src/video/directfb/SDL_DirectFB_video.c	Sat Aug 31 04:13:28 2002 +0000
     2.3 @@ -46,6 +46,7 @@
     2.4  #include "SDL_events_c.h"
     2.5  #include "SDL_DirectFB_video.h"
     2.6  #include "SDL_DirectFB_events.h"
     2.7 +#include "SDL_DirectFB_yuv.h"
     2.8  
     2.9  
    2.10  /* Initialization/Query functions */
    2.11 @@ -123,6 +124,7 @@
    2.12    device->SetVideoMode = DirectFB_SetVideoMode;
    2.13    device->SetColors = DirectFB_SetColors;
    2.14    device->UpdateRects = NULL;
    2.15 +  device->CreateYUVOverlay = DirectFB_CreateYUVOverlay;
    2.16    device->VideoQuit = DirectFB_VideoQuit;
    2.17    device->AllocHWSurface = DirectFB_AllocHWSurface;
    2.18    device->CheckHWBlit = DirectFB_CheckHWBlit;
     3.1 --- a/src/video/directfb/SDL_DirectFB_video.h	Sat Aug 31 04:06:37 2002 +0000
     3.2 +++ b/src/video/directfb/SDL_DirectFB_video.h	Sat Aug 31 04:13:28 2002 +0000
     3.3 @@ -51,4 +51,6 @@
     3.4  
     3.5  #define HIDDEN (this->hidden)
     3.6  
     3.7 +void SetDirectFBerror (const char *function, DFBResult code);
     3.8 +
     3.9  #endif /* _SDL_DirectFB_video_h */
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/video/directfb/SDL_DirectFB_yuv.c	Sat Aug 31 04:13:28 2002 +0000
     4.3 @@ -0,0 +1,289 @@
     4.4 +/*
     4.5 +    SDL - Simple DirectMedia Layer
     4.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
     4.7 +
     4.8 +    This library is free software; you can redistribute it and/or
     4.9 +    modify it under the terms of the GNU Library General Public
    4.10 +    License as published by the Free Software Foundation; either
    4.11 +    version 2 of the License, or (at your option) any later version.
    4.12 +
    4.13 +    This library is distributed in the hope that it will be useful,
    4.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    4.16 +    Library General Public License for more details.
    4.17 +
    4.18 +    You should have received a copy of the GNU Library General Public
    4.19 +    License along with this library; if not, write to the Free
    4.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    4.21 +
    4.22 +    Sam Lantinga
    4.23 +    slouken@libsdl.org
    4.24 +*/
    4.25 +
    4.26 +#ifdef SAVE_RCSID
    4.27 +static char rcsid =
    4.28 + "@(#) $Id$";
    4.29 +#endif
    4.30 +
    4.31 +/* This is the DirectFB implementation of YUV video overlays */
    4.32 +
    4.33 +#include <stdlib.h>
    4.34 +#include <string.h>
    4.35 +
    4.36 +#include "SDL_error.h"
    4.37 +#include "SDL_video.h"
    4.38 +#include "SDL_DirectFB_yuv.h"
    4.39 +#include "SDL_yuvfuncs.h"
    4.40 +
    4.41 +
    4.42 +/* The functions used to manipulate software video overlays */
    4.43 +static struct private_yuvhwfuncs directfb_yuvfuncs = {
    4.44 +  DirectFB_LockYUVOverlay,
    4.45 +  DirectFB_UnlockYUVOverlay,
    4.46 +  DirectFB_DisplayYUVOverlay,
    4.47 +  DirectFB_FreeYUVOverlay
    4.48 +};
    4.49 +
    4.50 +struct private_yuvhwdata {
    4.51 +  DFBDisplayLayerID      layer_id;
    4.52 +
    4.53 +  IDirectFBDisplayLayer *layer;
    4.54 +  IDirectFBSurface      *surface;
    4.55 +
    4.56 +  /* These are just so we don't have to allocate them separately */
    4.57 +  Uint16 pitches[3];
    4.58 +  Uint8 *planes[3];
    4.59 +};
    4.60 +
    4.61 +static DFBEnumerationResult
    4.62 +enum_layers_callback( DFBDisplayLayerID            id,
    4.63 +                      DFBDisplayLayerDescription   desc,
    4.64 +                      void                        *data )
    4.65 +{
    4.66 +  struct private_yuvhwdata *hwdata = (struct private_yuvhwdata *) data;
    4.67 +
    4.68 +  /* we don't want the primary */
    4.69 +  if (id == DLID_PRIMARY)
    4.70 +    return DFENUM_OK;
    4.71 +
    4.72 +  /* take the one with a surface for video */
    4.73 +  if ((desc.caps & DLCAPS_SURFACE) && (desc.type & DLTF_VIDEO))
    4.74 +    {
    4.75 +      hwdata->layer_id = id;
    4.76 +
    4.77 +      return DFENUM_CANCEL;
    4.78 +    }
    4.79 +
    4.80 +  return DFENUM_OK;
    4.81 +}
    4.82 +
    4.83 +
    4.84 +static DFBResult CreateYUVSurface(_THIS, struct private_yuvhwdata *hwdata,
    4.85 +                                  int width, int height, Uint32 format)
    4.86 +{
    4.87 +  DFBResult              ret;
    4.88 +  IDirectFB             *dfb = HIDDEN->dfb;
    4.89 +  IDirectFBDisplayLayer *layer;
    4.90 +  DFBDisplayLayerConfig  conf;
    4.91 +
    4.92 +  ret = dfb->EnumDisplayLayers (dfb, enum_layers_callback, hwdata);
    4.93 +  if (ret)
    4.94 +    {
    4.95 +      SetDirectFBerror("IDirectFB::EnumDisplayLayers", ret);
    4.96 +      return ret;
    4.97 +    }
    4.98 +
    4.99 +  if (!hwdata->layer_id)
   4.100 +    return DFB_UNSUPPORTED;
   4.101 +
   4.102 +  ret = dfb->GetDisplayLayer (dfb, hwdata->layer_id, &layer);
   4.103 +  if (ret)
   4.104 +    {
   4.105 +      SetDirectFBerror("IDirectFB::GetDisplayLayer", ret);
   4.106 +      return ret;
   4.107 +    }
   4.108 +
   4.109 +  conf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
   4.110 +  conf.width = width;
   4.111 +  conf.height = height;
   4.112 +
   4.113 +  switch (format)
   4.114 +    {
   4.115 +    case SDL_YV12_OVERLAY:
   4.116 +      conf.pixelformat = DSPF_YV12;
   4.117 +      break;
   4.118 +    case SDL_IYUV_OVERLAY:
   4.119 +      conf.pixelformat = DSPF_I420;
   4.120 +      break;
   4.121 +    case SDL_YUY2_OVERLAY:
   4.122 +      conf.pixelformat = DSPF_YUY2;
   4.123 +      break;
   4.124 +    case SDL_UYVY_OVERLAY:
   4.125 +      conf.pixelformat = DSPF_UYVY;
   4.126 +      break;
   4.127 +    default:
   4.128 +      fprintf (stderr, "SDL_DirectFB: Unsupported YUV format (0x%08x)!\n", format);
   4.129 +      break;
   4.130 +    }
   4.131 +
   4.132 +  ret = layer->SetConfiguration (layer, &conf);
   4.133 +  if (ret)
   4.134 +    {
   4.135 +      SetDirectFBerror("IDirectFBDisplayLayer::SetConfiguration", ret);
   4.136 +      layer->Release (layer);
   4.137 +      return ret;
   4.138 +    }
   4.139 +
   4.140 +  ret = layer->GetSurface (layer, &hwdata->surface);
   4.141 +  if (ret)
   4.142 +    {
   4.143 +      SetDirectFBerror("IDirectFBDisplayLayer::GetSurface", ret);
   4.144 +      layer->Release (layer);
   4.145 +      return ret;
   4.146 +    }
   4.147 +
   4.148 +  hwdata->layer = layer;
   4.149 +
   4.150 +  return DFB_OK;
   4.151 +}
   4.152 +
   4.153 +SDL_Overlay *DirectFB_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
   4.154 +{
   4.155 +  SDL_Overlay *overlay;
   4.156 +  struct private_yuvhwdata *hwdata;
   4.157 +
   4.158 +  /* Create the overlay structure */
   4.159 +  overlay = calloc (1, sizeof(SDL_Overlay));
   4.160 +  if (!overlay)
   4.161 +    {
   4.162 +      SDL_OutOfMemory();
   4.163 +      return NULL;
   4.164 +    }
   4.165 +	
   4.166 +  /* Fill in the basic members */
   4.167 +  overlay->format = format;
   4.168 +  overlay->w = width;
   4.169 +  overlay->h = height;
   4.170 +
   4.171 +  /* Set up the YUV surface function structure */
   4.172 +  overlay->hwfuncs = &directfb_yuvfuncs;
   4.173 +
   4.174 +  /* Create the pixel data and lookup tables */
   4.175 +  hwdata = calloc(1, sizeof(struct private_yuvhwdata));
   4.176 +  overlay->hwdata = hwdata;
   4.177 +  if (!hwdata)
   4.178 +    {
   4.179 +      SDL_OutOfMemory();
   4.180 +      SDL_FreeYUVOverlay (overlay);
   4.181 +      return NULL;
   4.182 +    }
   4.183 +
   4.184 +  if (CreateYUVSurface (this, hwdata, width, height, format))
   4.185 +    {
   4.186 +      SDL_FreeYUVOverlay (overlay);
   4.187 +      return NULL;
   4.188 +    }
   4.189 +
   4.190 +  overlay->hw_overlay = 1;
   4.191 +
   4.192 +  /* Set up the plane pointers */
   4.193 +  overlay->pitches = hwdata->pitches;
   4.194 +  overlay->pixels = hwdata->planes;
   4.195 +  switch (format)
   4.196 +    {
   4.197 +    case SDL_YV12_OVERLAY:
   4.198 +    case SDL_IYUV_OVERLAY:
   4.199 +      overlay->planes = 3;
   4.200 +      break;
   4.201 +    default:
   4.202 +      overlay->planes = 1;
   4.203 +      break;
   4.204 +    }
   4.205 +
   4.206 +  /* We're all done.. */
   4.207 +  return overlay;
   4.208 +}
   4.209 +
   4.210 +int DirectFB_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
   4.211 +{
   4.212 +  DFBResult         ret;
   4.213 +  void             *data;
   4.214 +  unsigned int      pitch;
   4.215 +  IDirectFBSurface *surface = overlay->hwdata->surface;
   4.216 +
   4.217 +  ret = surface->Lock (surface, DSLF_READ | DSLF_WRITE, &data, &pitch);
   4.218 +  if (ret)
   4.219 +    {
   4.220 +      SetDirectFBerror("IDirectFBSurface::Lock", ret);
   4.221 +      return -1;
   4.222 +    }
   4.223 +
   4.224 +  /* Find the pitch and offset values for the overlay */
   4.225 +  overlay->pitches[0] = (Uint16) pitch;
   4.226 +  overlay->pixels[0]  = (Uint8*) data;
   4.227 +
   4.228 +  switch (overlay->format)
   4.229 +    {
   4.230 +    case SDL_YV12_OVERLAY:
   4.231 +    case SDL_IYUV_OVERLAY:
   4.232 +      /* Add the two extra planes */
   4.233 +      overlay->pitches[1] = overlay->pitches[0] / 2;
   4.234 +      overlay->pitches[2] = overlay->pitches[0] / 2;
   4.235 +      overlay->pixels[1]  = overlay->pixels[0] + overlay->pitches[0] * overlay->h;
   4.236 +      overlay->pixels[2]  = overlay->pixels[1] + overlay->pitches[1] * overlay->h / 2;
   4.237 +      break;
   4.238 +    default:
   4.239 +      /* Only one plane, no worries */
   4.240 +      break;
   4.241 +    }
   4.242 +
   4.243 +  return 0;
   4.244 +}
   4.245 +
   4.246 +void DirectFB_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
   4.247 +{
   4.248 +  IDirectFBSurface *surface = overlay->hwdata->surface;
   4.249 +
   4.250 +  overlay->pixels[0] = overlay->pixels[1] = overlay->pixels[2] = NULL;
   4.251 +
   4.252 +  surface->Unlock (surface);
   4.253 +}
   4.254 +
   4.255 +int DirectFB_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dst)
   4.256 +{
   4.257 +  DFBResult              ret;
   4.258 +  DFBDisplayLayerConfig  conf;
   4.259 +  IDirectFBDisplayLayer *primary = HIDDEN->layer;
   4.260 +  IDirectFBDisplayLayer *layer   = overlay->hwdata->layer;
   4.261 +
   4.262 +  primary->GetConfiguration (primary, &conf);
   4.263 +
   4.264 +  ret = layer->SetScreenLocation (layer,
   4.265 +                                  dst->x / (float) conf.width, dst->y / (float) conf.height,
   4.266 +                                  dst->w / (float) conf.width, dst->h / (float) conf.height );
   4.267 +  if (ret)
   4.268 +    {
   4.269 +      SetDirectFBerror("IDirectFBDisplayLayer::SetScreenLocation", ret);
   4.270 +      return -1;
   4.271 +    }
   4.272 +
   4.273 +  return 0;
   4.274 +}
   4.275 +
   4.276 +void DirectFB_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
   4.277 +{
   4.278 +  struct private_yuvhwdata *hwdata;
   4.279 +
   4.280 +  hwdata = overlay->hwdata;
   4.281 +  if (hwdata)
   4.282 +    {
   4.283 +      if (hwdata->surface)
   4.284 +        hwdata->surface->Release (hwdata->surface);
   4.285 +
   4.286 +      if (hwdata->layer)
   4.287 +        hwdata->layer->Release (hwdata->layer);
   4.288 +
   4.289 +      free (hwdata);
   4.290 +    }
   4.291 +}
   4.292 +
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/video/directfb/SDL_DirectFB_yuv.h	Sat Aug 31 04:13:28 2002 +0000
     5.3 @@ -0,0 +1,42 @@
     5.4 +/*
     5.5 +    SDL - Simple DirectMedia Layer
     5.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
     5.7 +
     5.8 +    This library is free software; you can redistribute it and/or
     5.9 +    modify it under the terms of the GNU Library General Public
    5.10 +    License as published by the Free Software Foundation; either
    5.11 +    version 2 of the License, or (at your option) any later version.
    5.12 +
    5.13 +    This library is distributed in the hope that it will be useful,
    5.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    5.16 +    Library General Public License for more details.
    5.17 +
    5.18 +    You should have received a copy of the GNU Library General Public
    5.19 +    License along with this library; if not, write to the Free
    5.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    5.21 +
    5.22 +    Sam Lantinga
    5.23 +    slouken@libsdl.org
    5.24 +*/
    5.25 +
    5.26 +#ifdef SAVE_RCSID
    5.27 +static char rcsid =
    5.28 + "@(#) $Id$";
    5.29 +#endif
    5.30 +
    5.31 +/* This is the DirectFB implementation of YUV video overlays */
    5.32 +
    5.33 +#include "SDL_video.h"
    5.34 +#include "SDL_DirectFB_video.h"
    5.35 +
    5.36 +extern SDL_Overlay *DirectFB_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display);
    5.37 +
    5.38 +extern int DirectFB_LockYUVOverlay(_THIS, SDL_Overlay *overlay);
    5.39 +
    5.40 +extern void DirectFB_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay);
    5.41 +
    5.42 +extern int DirectFB_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect);
    5.43 +
    5.44 +extern void DirectFB_FreeYUVOverlay(_THIS, SDL_Overlay *overlay);
    5.45 +