Mercurial > sdl-ios-xcode
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: */ |