comparison src/video/directfb/SDL_DirectFB_yuv.c @ 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 14717b52abc0
children 4da1ee79c9af
comparison
equal deleted inserted replaced
1661:281d3f4870e5 1662:782fd950bd46
28 #include "../SDL_yuvfuncs.h" 28 #include "../SDL_yuvfuncs.h"
29 29
30 30
31 /* The functions used to manipulate software video overlays */ 31 /* The functions used to manipulate software video overlays */
32 static struct private_yuvhwfuncs directfb_yuvfuncs = { 32 static struct private_yuvhwfuncs directfb_yuvfuncs = {
33 DirectFB_LockYUVOverlay, 33 DirectFB_LockYUVOverlay,
34 DirectFB_UnlockYUVOverlay, 34 DirectFB_UnlockYUVOverlay,
35 DirectFB_DisplayYUVOverlay, 35 DirectFB_DisplayYUVOverlay,
36 DirectFB_FreeYUVOverlay 36 DirectFB_FreeYUVOverlay
37 }; 37 };
38 38
39 struct private_yuvhwdata { 39 struct private_yuvhwdata
40 DFBDisplayLayerID layer_id; 40 {
41 41 DFBDisplayLayerID layer_id;
42 IDirectFBDisplayLayer *layer; 42
43 IDirectFBSurface *surface; 43 IDirectFBDisplayLayer *layer;
44 44 IDirectFBSurface *surface;
45 /* These are just so we don't have to allocate them separately */ 45
46 Uint16 pitches[3]; 46 /* These are just so we don't have to allocate them separately */
47 Uint8 *planes[3]; 47 Uint16 pitches[3];
48 Uint8 *planes[3];
48 }; 49 };
49 50
50 static DFBEnumerationResult 51 static DFBEnumerationResult
51 enum_layers_callback( DFBDisplayLayerID id, 52 enum_layers_callback (DFBDisplayLayerID id,
52 DFBDisplayLayerDescription desc, 53 DFBDisplayLayerDescription desc, void *data)
53 void *data ) 54 {
54 { 55 struct private_yuvhwdata *hwdata = (struct private_yuvhwdata *) data;
55 struct private_yuvhwdata *hwdata = (struct private_yuvhwdata *) data; 56
56 57 /* we don't want the primary */
57 /* we don't want the primary */ 58 if (id == DLID_PRIMARY)
58 if (id == DLID_PRIMARY) 59 return DFENUM_OK;
60
61 /* take the one with a surface for video */
62 if ((desc.caps & DLCAPS_SURFACE) && (desc.type & DLTF_VIDEO)) {
63 hwdata->layer_id = id;
64
65 return DFENUM_CANCEL;
66 }
67
59 return DFENUM_OK; 68 return DFENUM_OK;
60 69 }
61 /* take the one with a surface for video */ 70
62 if ((desc.caps & DLCAPS_SURFACE) && (desc.type & DLTF_VIDEO)) 71
63 { 72 static DFBResult
64 hwdata->layer_id = id; 73 CreateYUVSurface (_THIS, struct private_yuvhwdata *hwdata,
65 74 int width, int height, Uint32 format)
66 return DFENUM_CANCEL; 75 {
67 } 76 DFBResult ret;
68 77 IDirectFB *dfb = HIDDEN->dfb;
69 return DFENUM_OK; 78 IDirectFBDisplayLayer *layer;
70 } 79 DFBDisplayLayerConfig conf;
71 80
72 81 ret = dfb->EnumDisplayLayers (dfb, enum_layers_callback, hwdata);
73 static DFBResult CreateYUVSurface(_THIS, struct private_yuvhwdata *hwdata, 82 if (ret) {
74 int width, int height, Uint32 format) 83 SetDirectFBerror ("IDirectFB::EnumDisplayLayers", ret);
75 { 84 return ret;
76 DFBResult ret; 85 }
77 IDirectFB *dfb = HIDDEN->dfb; 86
78 IDirectFBDisplayLayer *layer; 87 if (!hwdata->layer_id)
79 DFBDisplayLayerConfig conf; 88 return DFB_UNSUPPORTED;
80 89
81 ret = dfb->EnumDisplayLayers (dfb, enum_layers_callback, hwdata); 90 ret = dfb->GetDisplayLayer (dfb, hwdata->layer_id, &layer);
82 if (ret) 91 if (ret) {
83 { 92 SetDirectFBerror ("IDirectFB::GetDisplayLayer", ret);
84 SetDirectFBerror("IDirectFB::EnumDisplayLayers", ret); 93 return ret;
85 return ret; 94 }
86 } 95
87 96 conf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
88 if (!hwdata->layer_id) 97 conf.width = width;
89 return DFB_UNSUPPORTED; 98 conf.height = height;
90 99
91 ret = dfb->GetDisplayLayer (dfb, hwdata->layer_id, &layer); 100 switch (format) {
92 if (ret)
93 {
94 SetDirectFBerror("IDirectFB::GetDisplayLayer", ret);
95 return ret;
96 }
97
98 conf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
99 conf.width = width;
100 conf.height = height;
101
102 switch (format)
103 {
104 case SDL_YV12_OVERLAY: 101 case SDL_YV12_OVERLAY:
105 conf.pixelformat = DSPF_YV12; 102 conf.pixelformat = DSPF_YV12;
106 break; 103 break;
107 case SDL_IYUV_OVERLAY: 104 case SDL_IYUV_OVERLAY:
108 conf.pixelformat = DSPF_I420; 105 conf.pixelformat = DSPF_I420;
109 break; 106 break;
110 case SDL_YUY2_OVERLAY: 107 case SDL_YUY2_OVERLAY:
111 conf.pixelformat = DSPF_YUY2; 108 conf.pixelformat = DSPF_YUY2;
112 break; 109 break;
113 case SDL_UYVY_OVERLAY: 110 case SDL_UYVY_OVERLAY:
114 conf.pixelformat = DSPF_UYVY; 111 conf.pixelformat = DSPF_UYVY;
115 break; 112 break;
116 default: 113 default:
117 fprintf (stderr, "SDL_DirectFB: Unsupported YUV format (0x%08x)!\n", format); 114 fprintf (stderr, "SDL_DirectFB: Unsupported YUV format (0x%08x)!\n",
118 break; 115 format);
119 } 116 break;
120 117 }
121 ret = layer->SetConfiguration (layer, &conf); 118
122 if (ret) 119 ret = layer->SetConfiguration (layer, &conf);
123 { 120 if (ret) {
124 SetDirectFBerror("IDirectFBDisplayLayer::SetConfiguration", ret); 121 SetDirectFBerror ("IDirectFBDisplayLayer::SetConfiguration", ret);
125 layer->Release (layer); 122 layer->Release (layer);
126 return ret; 123 return ret;
127 } 124 }
128 125
129 ret = layer->GetSurface (layer, &hwdata->surface); 126 ret = layer->GetSurface (layer, &hwdata->surface);
130 if (ret) 127 if (ret) {
131 { 128 SetDirectFBerror ("IDirectFBDisplayLayer::GetSurface", ret);
132 SetDirectFBerror("IDirectFBDisplayLayer::GetSurface", ret); 129 layer->Release (layer);
133 layer->Release (layer); 130 return ret;
134 return ret; 131 }
135 } 132
136 133 hwdata->layer = layer;
137 hwdata->layer = layer; 134
138 135 return DFB_OK;
139 return DFB_OK; 136 }
140 } 137
141 138 SDL_Overlay *
142 SDL_Overlay *DirectFB_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) 139 DirectFB_CreateYUVOverlay (_THIS, int width, int height, Uint32 format,
143 { 140 SDL_Surface * display)
144 SDL_Overlay *overlay; 141 {
145 struct private_yuvhwdata *hwdata; 142 SDL_Overlay *overlay;
146 143 struct private_yuvhwdata *hwdata;
147 /* Create the overlay structure */ 144
148 overlay = SDL_calloc (1, sizeof(SDL_Overlay)); 145 /* Create the overlay structure */
149 if (!overlay) 146 overlay = SDL_calloc (1, sizeof (SDL_Overlay));
150 { 147 if (!overlay) {
151 SDL_OutOfMemory(); 148 SDL_OutOfMemory ();
152 return NULL; 149 return NULL;
153 } 150 }
154 151
155 /* Fill in the basic members */ 152 /* Fill in the basic members */
156 overlay->format = format; 153 overlay->format = format;
157 overlay->w = width; 154 overlay->w = width;
158 overlay->h = height; 155 overlay->h = height;
159 156
160 /* Set up the YUV surface function structure */ 157 /* Set up the YUV surface function structure */
161 overlay->hwfuncs = &directfb_yuvfuncs; 158 overlay->hwfuncs = &directfb_yuvfuncs;
162 159
163 /* Create the pixel data and lookup tables */ 160 /* Create the pixel data and lookup tables */
164 hwdata = SDL_calloc(1, sizeof(struct private_yuvhwdata)); 161 hwdata = SDL_calloc (1, sizeof (struct private_yuvhwdata));
165 overlay->hwdata = hwdata; 162 overlay->hwdata = hwdata;
166 if (!hwdata) 163 if (!hwdata) {
167 { 164 SDL_OutOfMemory ();
168 SDL_OutOfMemory(); 165 SDL_FreeYUVOverlay (overlay);
169 SDL_FreeYUVOverlay (overlay); 166 return NULL;
170 return NULL; 167 }
171 } 168
172 169 if (CreateYUVSurface (this, hwdata, width, height, format)) {
173 if (CreateYUVSurface (this, hwdata, width, height, format)) 170 SDL_FreeYUVOverlay (overlay);
174 { 171 return NULL;
175 SDL_FreeYUVOverlay (overlay); 172 }
176 return NULL; 173
177 } 174 overlay->hw_overlay = 1;
178 175
179 overlay->hw_overlay = 1; 176 /* Set up the plane pointers */
180 177 overlay->pitches = hwdata->pitches;
181 /* Set up the plane pointers */ 178 overlay->pixels = hwdata->planes;
182 overlay->pitches = hwdata->pitches; 179 switch (format) {
183 overlay->pixels = hwdata->planes;
184 switch (format)
185 {
186 case SDL_YV12_OVERLAY: 180 case SDL_YV12_OVERLAY:
187 case SDL_IYUV_OVERLAY: 181 case SDL_IYUV_OVERLAY:
188 overlay->planes = 3; 182 overlay->planes = 3;
189 break; 183 break;
190 default: 184 default:
191 overlay->planes = 1; 185 overlay->planes = 1;
192 break; 186 break;
193 } 187 }
194 188
195 /* We're all done.. */ 189 /* We're all done.. */
196 return overlay; 190 return overlay;
197 } 191 }
198 192
199 int DirectFB_LockYUVOverlay(_THIS, SDL_Overlay *overlay) 193 int
200 { 194 DirectFB_LockYUVOverlay (_THIS, SDL_Overlay * overlay)
201 DFBResult ret; 195 {
202 void *data; 196 DFBResult ret;
203 int pitch; 197 void *data;
204 IDirectFBSurface *surface = overlay->hwdata->surface; 198 int pitch;
205 199 IDirectFBSurface *surface = overlay->hwdata->surface;
206 ret = surface->Lock (surface, DSLF_READ | DSLF_WRITE, &data, &pitch); 200
207 if (ret) 201 ret = surface->Lock (surface, DSLF_READ | DSLF_WRITE, &data, &pitch);
208 { 202 if (ret) {
209 SetDirectFBerror("IDirectFBSurface::Lock", ret); 203 SetDirectFBerror ("IDirectFBSurface::Lock", ret);
210 return -1; 204 return -1;
211 } 205 }
212 206
213 /* Find the pitch and offset values for the overlay */ 207 /* Find the pitch and offset values for the overlay */
214 overlay->pitches[0] = (Uint16) pitch; 208 overlay->pitches[0] = (Uint16) pitch;
215 overlay->pixels[0] = (Uint8*) data; 209 overlay->pixels[0] = (Uint8 *) data;
216 210
217 switch (overlay->format) 211 switch (overlay->format) {
218 {
219 case SDL_YV12_OVERLAY: 212 case SDL_YV12_OVERLAY:
220 case SDL_IYUV_OVERLAY: 213 case SDL_IYUV_OVERLAY:
221 /* Add the two extra planes */ 214 /* Add the two extra planes */
222 overlay->pitches[1] = overlay->pitches[0] / 2; 215 overlay->pitches[1] = overlay->pitches[0] / 2;
223 overlay->pitches[2] = overlay->pitches[0] / 2; 216 overlay->pitches[2] = overlay->pitches[0] / 2;
224 overlay->pixels[1] = overlay->pixels[0] + overlay->pitches[0] * overlay->h; 217 overlay->pixels[1] =
225 overlay->pixels[2] = overlay->pixels[1] + overlay->pitches[1] * overlay->h / 2; 218 overlay->pixels[0] + overlay->pitches[0] * overlay->h;
226 break; 219 overlay->pixels[2] =
220 overlay->pixels[1] + overlay->pitches[1] * overlay->h / 2;
221 break;
227 default: 222 default:
228 /* Only one plane, no worries */ 223 /* Only one plane, no worries */
229 break; 224 break;
230 } 225 }
231 226
232 return 0; 227 return 0;
233 } 228 }
234 229
235 void DirectFB_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay) 230 void
236 { 231 DirectFB_UnlockYUVOverlay (_THIS, SDL_Overlay * overlay)
237 IDirectFBSurface *surface = overlay->hwdata->surface; 232 {
238 233 IDirectFBSurface *surface = overlay->hwdata->surface;
239 overlay->pixels[0] = overlay->pixels[1] = overlay->pixels[2] = NULL; 234
240 235 overlay->pixels[0] = overlay->pixels[1] = overlay->pixels[2] = NULL;
241 surface->Unlock (surface); 236
242 } 237 surface->Unlock (surface);
243 238 }
244 int DirectFB_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst) 239
245 { 240 int
246 DFBResult ret; 241 DirectFB_DisplayYUVOverlay (_THIS, SDL_Overlay * overlay, SDL_Rect * src,
247 DFBDisplayLayerConfig conf; 242 SDL_Rect * dst)
248 IDirectFBDisplayLayer *primary = HIDDEN->layer; 243 {
249 IDirectFBDisplayLayer *layer = overlay->hwdata->layer; 244 DFBResult ret;
250 245 DFBDisplayLayerConfig conf;
251 primary->GetConfiguration (primary, &conf); 246 IDirectFBDisplayLayer *primary = HIDDEN->layer;
252 247 IDirectFBDisplayLayer *layer = overlay->hwdata->layer;
253 ret = layer->SetScreenLocation (layer, 248
254 dst->x / (float) conf.width, dst->y / (float) conf.height, 249 primary->GetConfiguration (primary, &conf);
255 dst->w / (float) conf.width, dst->h / (float) conf.height ); 250
256 if (ret) 251 ret = layer->SetScreenLocation (layer,
257 { 252 dst->x / (float) conf.width,
258 SetDirectFBerror("IDirectFBDisplayLayer::SetScreenLocation", ret); 253 dst->y / (float) conf.height,
259 return -1; 254 dst->w / (float) conf.width,
260 } 255 dst->h / (float) conf.height);
261 256 if (ret) {
262 return 0; 257 SetDirectFBerror ("IDirectFBDisplayLayer::SetScreenLocation", ret);
263 } 258 return -1;
264 259 }
265 void DirectFB_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) 260
266 { 261 return 0;
267 struct private_yuvhwdata *hwdata; 262 }
268 263
269 hwdata = overlay->hwdata; 264 void
270 if (hwdata) 265 DirectFB_FreeYUVOverlay (_THIS, SDL_Overlay * overlay)
271 { 266 {
272 if (hwdata->surface) 267 struct private_yuvhwdata *hwdata;
273 hwdata->surface->Release (hwdata->surface); 268
274 269 hwdata = overlay->hwdata;
275 if (hwdata->layer) 270 if (hwdata) {
276 hwdata->layer->Release (hwdata->layer); 271 if (hwdata->surface)
277 272 hwdata->surface->Release (hwdata->surface);
278 free (hwdata); 273
279 } 274 if (hwdata->layer)
280 } 275 hwdata->layer->Release (hwdata->layer);
281 276
277 free (hwdata);
278 }
279 }
280
281 /* vi: set ts=4 sw=4 expandtab: */