comparison src/video/directfb/SDL_DirectFB_yuv.c @ 478:f8482d7c9595

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.
author Sam Lantinga <slouken@libsdl.org>
date Sat, 31 Aug 2002 04:13:28 +0000
parents
children b8d311d90021
comparison
equal deleted inserted replaced
477:22581630aab7 478:f8482d7c9595
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21 */
22
23 #ifdef SAVE_RCSID
24 static char rcsid =
25 "@(#) $Id$";
26 #endif
27
28 /* This is the DirectFB implementation of YUV video overlays */
29
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "SDL_error.h"
34 #include "SDL_video.h"
35 #include "SDL_DirectFB_yuv.h"
36 #include "SDL_yuvfuncs.h"
37
38
39 /* The functions used to manipulate software video overlays */
40 static struct private_yuvhwfuncs directfb_yuvfuncs = {
41 DirectFB_LockYUVOverlay,
42 DirectFB_UnlockYUVOverlay,
43 DirectFB_DisplayYUVOverlay,
44 DirectFB_FreeYUVOverlay
45 };
46
47 struct private_yuvhwdata {
48 DFBDisplayLayerID layer_id;
49
50 IDirectFBDisplayLayer *layer;
51 IDirectFBSurface *surface;
52
53 /* These are just so we don't have to allocate them separately */
54 Uint16 pitches[3];
55 Uint8 *planes[3];
56 };
57
58 static DFBEnumerationResult
59 enum_layers_callback( DFBDisplayLayerID id,
60 DFBDisplayLayerDescription desc,
61 void *data )
62 {
63 struct private_yuvhwdata *hwdata = (struct private_yuvhwdata *) data;
64
65 /* we don't want the primary */
66 if (id == DLID_PRIMARY)
67 return DFENUM_OK;
68
69 /* take the one with a surface for video */
70 if ((desc.caps & DLCAPS_SURFACE) && (desc.type & DLTF_VIDEO))
71 {
72 hwdata->layer_id = id;
73
74 return DFENUM_CANCEL;
75 }
76
77 return DFENUM_OK;
78 }
79
80
81 static DFBResult CreateYUVSurface(_THIS, struct private_yuvhwdata *hwdata,
82 int width, int height, Uint32 format)
83 {
84 DFBResult ret;
85 IDirectFB *dfb = HIDDEN->dfb;
86 IDirectFBDisplayLayer *layer;
87 DFBDisplayLayerConfig conf;
88
89 ret = dfb->EnumDisplayLayers (dfb, enum_layers_callback, hwdata);
90 if (ret)
91 {
92 SetDirectFBerror("IDirectFB::EnumDisplayLayers", ret);
93 return ret;
94 }
95
96 if (!hwdata->layer_id)
97 return DFB_UNSUPPORTED;
98
99 ret = dfb->GetDisplayLayer (dfb, hwdata->layer_id, &layer);
100 if (ret)
101 {
102 SetDirectFBerror("IDirectFB::GetDisplayLayer", ret);
103 return ret;
104 }
105
106 conf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
107 conf.width = width;
108 conf.height = height;
109
110 switch (format)
111 {
112 case SDL_YV12_OVERLAY:
113 conf.pixelformat = DSPF_YV12;
114 break;
115 case SDL_IYUV_OVERLAY:
116 conf.pixelformat = DSPF_I420;
117 break;
118 case SDL_YUY2_OVERLAY:
119 conf.pixelformat = DSPF_YUY2;
120 break;
121 case SDL_UYVY_OVERLAY:
122 conf.pixelformat = DSPF_UYVY;
123 break;
124 default:
125 fprintf (stderr, "SDL_DirectFB: Unsupported YUV format (0x%08x)!\n", format);
126 break;
127 }
128
129 ret = layer->SetConfiguration (layer, &conf);
130 if (ret)
131 {
132 SetDirectFBerror("IDirectFBDisplayLayer::SetConfiguration", ret);
133 layer->Release (layer);
134 return ret;
135 }
136
137 ret = layer->GetSurface (layer, &hwdata->surface);
138 if (ret)
139 {
140 SetDirectFBerror("IDirectFBDisplayLayer::GetSurface", ret);
141 layer->Release (layer);
142 return ret;
143 }
144
145 hwdata->layer = layer;
146
147 return DFB_OK;
148 }
149
150 SDL_Overlay *DirectFB_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
151 {
152 SDL_Overlay *overlay;
153 struct private_yuvhwdata *hwdata;
154
155 /* Create the overlay structure */
156 overlay = calloc (1, sizeof(SDL_Overlay));
157 if (!overlay)
158 {
159 SDL_OutOfMemory();
160 return NULL;
161 }
162
163 /* Fill in the basic members */
164 overlay->format = format;
165 overlay->w = width;
166 overlay->h = height;
167
168 /* Set up the YUV surface function structure */
169 overlay->hwfuncs = &directfb_yuvfuncs;
170
171 /* Create the pixel data and lookup tables */
172 hwdata = calloc(1, sizeof(struct private_yuvhwdata));
173 overlay->hwdata = hwdata;
174 if (!hwdata)
175 {
176 SDL_OutOfMemory();
177 SDL_FreeYUVOverlay (overlay);
178 return NULL;
179 }
180
181 if (CreateYUVSurface (this, hwdata, width, height, format))
182 {
183 SDL_FreeYUVOverlay (overlay);
184 return NULL;
185 }
186
187 overlay->hw_overlay = 1;
188
189 /* Set up the plane pointers */
190 overlay->pitches = hwdata->pitches;
191 overlay->pixels = hwdata->planes;
192 switch (format)
193 {
194 case SDL_YV12_OVERLAY:
195 case SDL_IYUV_OVERLAY:
196 overlay->planes = 3;
197 break;
198 default:
199 overlay->planes = 1;
200 break;
201 }
202
203 /* We're all done.. */
204 return overlay;
205 }
206
207 int DirectFB_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
208 {
209 DFBResult ret;
210 void *data;
211 unsigned int pitch;
212 IDirectFBSurface *surface = overlay->hwdata->surface;
213
214 ret = surface->Lock (surface, DSLF_READ | DSLF_WRITE, &data, &pitch);
215 if (ret)
216 {
217 SetDirectFBerror("IDirectFBSurface::Lock", ret);
218 return -1;
219 }
220
221 /* Find the pitch and offset values for the overlay */
222 overlay->pitches[0] = (Uint16) pitch;
223 overlay->pixels[0] = (Uint8*) data;
224
225 switch (overlay->format)
226 {
227 case SDL_YV12_OVERLAY:
228 case SDL_IYUV_OVERLAY:
229 /* Add the two extra planes */
230 overlay->pitches[1] = overlay->pitches[0] / 2;
231 overlay->pitches[2] = overlay->pitches[0] / 2;
232 overlay->pixels[1] = overlay->pixels[0] + overlay->pitches[0] * overlay->h;
233 overlay->pixels[2] = overlay->pixels[1] + overlay->pitches[1] * overlay->h / 2;
234 break;
235 default:
236 /* Only one plane, no worries */
237 break;
238 }
239
240 return 0;
241 }
242
243 void DirectFB_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
244 {
245 IDirectFBSurface *surface = overlay->hwdata->surface;
246
247 overlay->pixels[0] = overlay->pixels[1] = overlay->pixels[2] = NULL;
248
249 surface->Unlock (surface);
250 }
251
252 int DirectFB_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dst)
253 {
254 DFBResult ret;
255 DFBDisplayLayerConfig conf;
256 IDirectFBDisplayLayer *primary = HIDDEN->layer;
257 IDirectFBDisplayLayer *layer = overlay->hwdata->layer;
258
259 primary->GetConfiguration (primary, &conf);
260
261 ret = layer->SetScreenLocation (layer,
262 dst->x / (float) conf.width, dst->y / (float) conf.height,
263 dst->w / (float) conf.width, dst->h / (float) conf.height );
264 if (ret)
265 {
266 SetDirectFBerror("IDirectFBDisplayLayer::SetScreenLocation", ret);
267 return -1;
268 }
269
270 return 0;
271 }
272
273 void DirectFB_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
274 {
275 struct private_yuvhwdata *hwdata;
276
277 hwdata = overlay->hwdata;
278 if (hwdata)
279 {
280 if (hwdata->surface)
281 hwdata->surface->Release (hwdata->surface);
282
283 if (hwdata->layer)
284 hwdata->layer->Release (hwdata->layer);
285
286 free (hwdata);
287 }
288 }
289