comparison src/video/windx5/SDL_dx5yuv.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 51038e80ae59
children 4da1ee79c9af
comparison
equal deleted inserted replaced
1661:281d3f4870e5 1662:782fd950bd46
29 29
30 //#define USE_DIRECTX_OVERLAY 30 //#define USE_DIRECTX_OVERLAY
31 31
32 /* The functions used to manipulate software video overlays */ 32 /* The functions used to manipulate software video overlays */
33 static struct private_yuvhwfuncs dx5_yuvfuncs = { 33 static struct private_yuvhwfuncs dx5_yuvfuncs = {
34 DX5_LockYUVOverlay, 34 DX5_LockYUVOverlay,
35 DX5_UnlockYUVOverlay, 35 DX5_UnlockYUVOverlay,
36 DX5_DisplayYUVOverlay, 36 DX5_DisplayYUVOverlay,
37 DX5_FreeYUVOverlay 37 DX5_FreeYUVOverlay
38 }; 38 };
39 39
40 struct private_yuvhwdata { 40 struct private_yuvhwdata
41 LPDIRECTDRAWSURFACE3 surface; 41 {
42 42 LPDIRECTDRAWSURFACE3 surface;
43 /* These are just so we don't have to allocate them separately */ 43
44 Uint16 pitches[3]; 44 /* These are just so we don't have to allocate them separately */
45 Uint8 *planes[3]; 45 Uint16 pitches[3];
46 Uint8 *planes[3];
46 }; 47 };
47 48
48 49
49 static LPDIRECTDRAWSURFACE3 CreateYUVSurface(_THIS, 50 static LPDIRECTDRAWSURFACE3
50 int width, int height, Uint32 format) 51 CreateYUVSurface (_THIS, int width, int height, Uint32 format)
51 { 52 {
52 HRESULT result; 53 HRESULT result;
53 LPDIRECTDRAWSURFACE dd_surface1; 54 LPDIRECTDRAWSURFACE dd_surface1;
54 LPDIRECTDRAWSURFACE3 dd_surface3; 55 LPDIRECTDRAWSURFACE3 dd_surface3;
55 DDSURFACEDESC ddsd; 56 DDSURFACEDESC ddsd;
56 57
57 /* Set up the surface description */ 58 /* Set up the surface description */
58 SDL_memset(&ddsd, 0, sizeof(ddsd)); 59 SDL_memset (&ddsd, 0, sizeof (ddsd));
59 ddsd.dwSize = sizeof(ddsd); 60 ddsd.dwSize = sizeof (ddsd);
60 ddsd.dwFlags = (DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|DDSD_PIXELFORMAT); 61 ddsd.dwFlags = (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT);
61 ddsd.dwWidth = width; 62 ddsd.dwWidth = width;
62 ddsd.dwHeight= height; 63 ddsd.dwHeight = height;
63 #ifdef USE_DIRECTX_OVERLAY 64 #ifdef USE_DIRECTX_OVERLAY
64 ddsd.ddsCaps.dwCaps = (DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY); 65 ddsd.ddsCaps.dwCaps = (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY);
65 #else 66 #else
66 ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY); 67 ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY);
67 #endif 68 #endif
68 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat); 69 ddsd.ddpfPixelFormat.dwSize = sizeof (ddsd.ddpfPixelFormat);
69 ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC; 70 ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
70 ddsd.ddpfPixelFormat.dwFourCC = format; 71 ddsd.ddpfPixelFormat.dwFourCC = format;
71 72
72 /* Create the DirectDraw video surface */ 73 /* Create the DirectDraw video surface */
73 result = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &dd_surface1, NULL); 74 result = IDirectDraw2_CreateSurface (ddraw2, &ddsd, &dd_surface1, NULL);
74 if ( result != DD_OK ) { 75 if (result != DD_OK) {
75 SetDDerror("DirectDraw2::CreateSurface", result); 76 SetDDerror ("DirectDraw2::CreateSurface", result);
76 return(NULL); 77 return (NULL);
77 } 78 }
78 result = IDirectDrawSurface_QueryInterface(dd_surface1, 79 result = IDirectDrawSurface_QueryInterface (dd_surface1,
79 &IID_IDirectDrawSurface3, (LPVOID *)&dd_surface3); 80 &IID_IDirectDrawSurface3,
80 IDirectDrawSurface_Release(dd_surface1); 81 (LPVOID *) & dd_surface3);
81 if ( result != DD_OK ) { 82 IDirectDrawSurface_Release (dd_surface1);
82 SetDDerror("DirectDrawSurface::QueryInterface", result); 83 if (result != DD_OK) {
83 return(NULL); 84 SetDDerror ("DirectDrawSurface::QueryInterface", result);
84 } 85 return (NULL);
85 86 }
86 /* Make sure the surface format was set properly */ 87
87 SDL_memset(&ddsd, 0, sizeof(ddsd)); 88 /* Make sure the surface format was set properly */
88 ddsd.dwSize = sizeof(ddsd); 89 SDL_memset (&ddsd, 0, sizeof (ddsd));
89 result = IDirectDrawSurface3_Lock(dd_surface3, NULL, 90 ddsd.dwSize = sizeof (ddsd);
90 &ddsd, DDLOCK_NOSYSLOCK, NULL); 91 result = IDirectDrawSurface3_Lock (dd_surface3, NULL,
91 if ( result != DD_OK ) { 92 &ddsd, DDLOCK_NOSYSLOCK, NULL);
92 SetDDerror("DirectDrawSurface3::Lock", result); 93 if (result != DD_OK) {
93 IDirectDrawSurface_Release(dd_surface3); 94 SetDDerror ("DirectDrawSurface3::Lock", result);
94 return(NULL); 95 IDirectDrawSurface_Release (dd_surface3);
95 } 96 return (NULL);
96 IDirectDrawSurface3_Unlock(dd_surface3, NULL); 97 }
97 98 IDirectDrawSurface3_Unlock (dd_surface3, NULL);
98 if ( !(ddsd.ddpfPixelFormat.dwFlags & DDPF_FOURCC) || 99
99 (ddsd.ddpfPixelFormat.dwFourCC != format) ) { 100 if (!(ddsd.ddpfPixelFormat.dwFlags & DDPF_FOURCC) ||
100 SDL_SetError("DDraw didn't use requested FourCC format"); 101 (ddsd.ddpfPixelFormat.dwFourCC != format)) {
101 IDirectDrawSurface_Release(dd_surface3); 102 SDL_SetError ("DDraw didn't use requested FourCC format");
102 return(NULL); 103 IDirectDrawSurface_Release (dd_surface3);
103 } 104 return (NULL);
104 105 }
105 /* We're ready to go! */ 106
106 return(dd_surface3); 107 /* We're ready to go! */
108 return (dd_surface3);
107 } 109 }
108 110
109 #ifdef DEBUG_YUV 111 #ifdef DEBUG_YUV
110 static char *PrintFOURCC(Uint32 code) 112 static char *
111 { 113 PrintFOURCC (Uint32 code)
112 static char buf[5]; 114 {
113 115 static char buf[5];
114 buf[3] = code >> 24; 116
115 buf[2] = (code >> 16) & 0xFF; 117 buf[3] = code >> 24;
116 buf[1] = (code >> 8) & 0xFF; 118 buf[2] = (code >> 16) & 0xFF;
117 buf[0] = (code & 0xFF); 119 buf[1] = (code >> 8) & 0xFF;
118 return(buf); 120 buf[0] = (code & 0xFF);
119 } 121 return (buf);
120 #endif 122 }
121 123 #endif
122 SDL_Overlay *DX5_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) 124
123 { 125 SDL_Overlay *
124 SDL_Overlay *overlay; 126 DX5_CreateYUVOverlay (_THIS, int width, int height, Uint32 format,
125 struct private_yuvhwdata *hwdata; 127 SDL_Surface * display)
128 {
129 SDL_Overlay *overlay;
130 struct private_yuvhwdata *hwdata;
126 131
127 #ifdef DEBUG_YUV 132 #ifdef DEBUG_YUV
128 DWORD numcodes; 133 DWORD numcodes;
129 DWORD *codes; 134 DWORD *codes;
130 135
131 printf("FOURCC format requested: 0x%x\n", PrintFOURCC(format)); 136 printf ("FOURCC format requested: 0x%x\n", PrintFOURCC (format));
132 IDirectDraw2_GetFourCCCodes(ddraw2, &numcodes, NULL); 137 IDirectDraw2_GetFourCCCodes (ddraw2, &numcodes, NULL);
133 if ( numcodes ) { 138 if (numcodes) {
134 DWORD i; 139 DWORD i;
135 codes = SDL_malloc(numcodes*sizeof(*codes)); 140 codes = SDL_malloc (numcodes * sizeof (*codes));
136 if ( codes ) { 141 if (codes) {
137 IDirectDraw2_GetFourCCCodes(ddraw2, &numcodes, codes); 142 IDirectDraw2_GetFourCCCodes (ddraw2, &numcodes, codes);
138 for ( i=0; i<numcodes; ++i ) { 143 for (i = 0; i < numcodes; ++i) {
139 fprintf(stderr, "Code %d: 0x%x\n", i, PrintFOURCC(codes[i])); 144 fprintf (stderr, "Code %d: 0x%x\n", i,
140 } 145 PrintFOURCC (codes[i]));
141 SDL_free(codes); 146 }
142 } 147 SDL_free (codes);
143 } else { 148 }
144 fprintf(stderr, "No FOURCC codes supported\n"); 149 } else {
145 } 150 fprintf (stderr, "No FOURCC codes supported\n");
146 #endif 151 }
147 152 #endif
148 /* Create the overlay structure */ 153
149 overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay); 154 /* Create the overlay structure */
150 if ( overlay == NULL ) { 155 overlay = (SDL_Overlay *) SDL_malloc (sizeof *overlay);
151 SDL_OutOfMemory(); 156 if (overlay == NULL) {
152 return(NULL); 157 SDL_OutOfMemory ();
153 } 158 return (NULL);
154 SDL_memset(overlay, 0, (sizeof *overlay)); 159 }
155 160 SDL_memset (overlay, 0, (sizeof *overlay));
156 /* Fill in the basic members */ 161
157 overlay->format = format; 162 /* Fill in the basic members */
158 overlay->w = width; 163 overlay->format = format;
159 overlay->h = height; 164 overlay->w = width;
160 165 overlay->h = height;
161 /* Set up the YUV surface function structure */ 166
162 overlay->hwfuncs = &dx5_yuvfuncs; 167 /* Set up the YUV surface function structure */
163 168 overlay->hwfuncs = &dx5_yuvfuncs;
164 /* Create the pixel data and lookup tables */ 169
165 hwdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *hwdata); 170 /* Create the pixel data and lookup tables */
166 overlay->hwdata = hwdata; 171 hwdata = (struct private_yuvhwdata *) SDL_malloc (sizeof *hwdata);
167 if ( hwdata == NULL ) { 172 overlay->hwdata = hwdata;
168 SDL_OutOfMemory(); 173 if (hwdata == NULL) {
169 SDL_FreeYUVOverlay(overlay); 174 SDL_OutOfMemory ();
170 return(NULL); 175 SDL_FreeYUVOverlay (overlay);
171 } 176 return (NULL);
172 hwdata->surface = CreateYUVSurface(this, width, height, format); 177 }
173 if ( hwdata->surface == NULL ) { 178 hwdata->surface = CreateYUVSurface (this, width, height, format);
174 SDL_FreeYUVOverlay(overlay); 179 if (hwdata->surface == NULL) {
175 return(NULL); 180 SDL_FreeYUVOverlay (overlay);
176 } 181 return (NULL);
177 overlay->hw_overlay = 1; 182 }
178 183 overlay->hw_overlay = 1;
179 /* Set up the plane pointers */ 184
180 overlay->pitches = hwdata->pitches; 185 /* Set up the plane pointers */
181 overlay->pixels = hwdata->planes; 186 overlay->pitches = hwdata->pitches;
182 switch (format) { 187 overlay->pixels = hwdata->planes;
183 case SDL_YV12_OVERLAY: 188 switch (format) {
184 case SDL_IYUV_OVERLAY: 189 case SDL_YV12_OVERLAY:
185 overlay->planes = 3; 190 case SDL_IYUV_OVERLAY:
186 break; 191 overlay->planes = 3;
187 default: 192 break;
188 overlay->planes = 1; 193 default:
189 break; 194 overlay->planes = 1;
190 } 195 break;
191 196 }
192 /* We're all done.. */ 197
193 return(overlay); 198 /* We're all done.. */
194 } 199 return (overlay);
195 200 }
196 int DX5_LockYUVOverlay(_THIS, SDL_Overlay *overlay) 201
197 { 202 int
198 HRESULT result; 203 DX5_LockYUVOverlay (_THIS, SDL_Overlay * overlay)
199 LPDIRECTDRAWSURFACE3 surface; 204 {
200 DDSURFACEDESC ddsd; 205 HRESULT result;
201 206 LPDIRECTDRAWSURFACE3 surface;
202 surface = overlay->hwdata->surface; 207 DDSURFACEDESC ddsd;
203 SDL_memset(&ddsd, 0, sizeof(ddsd)); 208
204 ddsd.dwSize = sizeof(ddsd); 209 surface = overlay->hwdata->surface;
205 result = IDirectDrawSurface3_Lock(surface, NULL, 210 SDL_memset (&ddsd, 0, sizeof (ddsd));
206 &ddsd, DDLOCK_NOSYSLOCK, NULL); 211 ddsd.dwSize = sizeof (ddsd);
207 if ( result == DDERR_SURFACELOST ) { 212 result = IDirectDrawSurface3_Lock (surface, NULL,
208 result = IDirectDrawSurface3_Restore(surface); 213 &ddsd, DDLOCK_NOSYSLOCK, NULL);
209 result = IDirectDrawSurface3_Lock(surface, NULL, &ddsd, 214 if (result == DDERR_SURFACELOST) {
210 (DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL); 215 result = IDirectDrawSurface3_Restore (surface);
211 } 216 result = IDirectDrawSurface3_Lock (surface, NULL, &ddsd,
212 if ( result != DD_OK ) { 217 (DDLOCK_NOSYSLOCK | DDLOCK_WAIT),
213 SetDDerror("DirectDrawSurface3::Lock", result); 218 NULL);
214 return(-1); 219 }
215 } 220 if (result != DD_OK) {
216 221 SetDDerror ("DirectDrawSurface3::Lock", result);
217 /* Find the pitch and offset values for the overlay */ 222 return (-1);
223 }
224
225 /* Find the pitch and offset values for the overlay */
218 #if defined(NONAMELESSUNION) 226 #if defined(NONAMELESSUNION)
219 overlay->pitches[0] = (Uint16)ddsd.u1.lPitch; 227 overlay->pitches[0] = (Uint16) ddsd.u1.lPitch;
220 #else 228 #else
221 overlay->pitches[0] = (Uint16)ddsd.lPitch; 229 overlay->pitches[0] = (Uint16) ddsd.lPitch;
222 #endif 230 #endif
223 overlay->pixels[0] = (Uint8 *)ddsd.lpSurface; 231 overlay->pixels[0] = (Uint8 *) ddsd.lpSurface;
224 switch (overlay->format) { 232 switch (overlay->format) {
225 case SDL_YV12_OVERLAY: 233 case SDL_YV12_OVERLAY:
226 case SDL_IYUV_OVERLAY: 234 case SDL_IYUV_OVERLAY:
227 /* Add the two extra planes */ 235 /* Add the two extra planes */
228 overlay->pitches[1] = overlay->pitches[0] / 2; 236 overlay->pitches[1] = overlay->pitches[0] / 2;
229 overlay->pitches[2] = overlay->pitches[0] / 2; 237 overlay->pitches[2] = overlay->pitches[0] / 2;
230 overlay->pixels[1] = overlay->pixels[0] + 238 overlay->pixels[1] = overlay->pixels[0] +
231 overlay->pitches[0] * overlay->h; 239 overlay->pitches[0] * overlay->h;
232 overlay->pixels[2] = overlay->pixels[1] + 240 overlay->pixels[2] = overlay->pixels[1] +
233 overlay->pitches[1] * overlay->h / 2; 241 overlay->pitches[1] * overlay->h / 2;
234 break; 242 break;
235 default: 243 default:
236 /* Only one plane, no worries */ 244 /* Only one plane, no worries */
237 break; 245 break;
238 } 246 }
239 return(0); 247 return (0);
240 } 248 }
241 249
242 void DX5_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay) 250 void
243 { 251 DX5_UnlockYUVOverlay (_THIS, SDL_Overlay * overlay)
244 LPDIRECTDRAWSURFACE3 surface; 252 {
245 253 LPDIRECTDRAWSURFACE3 surface;
246 surface = overlay->hwdata->surface; 254
247 IDirectDrawSurface3_Unlock(surface, NULL); 255 surface = overlay->hwdata->surface;
248 } 256 IDirectDrawSurface3_Unlock (surface, NULL);
249 257 }
250 int DX5_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst) 258
251 { 259 int
252 HRESULT result; 260 DX5_DisplayYUVOverlay (_THIS, SDL_Overlay * overlay, SDL_Rect * src,
253 LPDIRECTDRAWSURFACE3 surface; 261 SDL_Rect * dst)
254 RECT srcrect, dstrect; 262 {
255 263 HRESULT result;
256 surface = overlay->hwdata->surface; 264 LPDIRECTDRAWSURFACE3 surface;
257 srcrect.top = src->y; 265 RECT srcrect, dstrect;
258 srcrect.bottom = srcrect.top+src->h; 266
259 srcrect.left = src->x; 267 surface = overlay->hwdata->surface;
260 srcrect.right = srcrect.left+src->w; 268 srcrect.top = src->y;
261 dstrect.top = SDL_bounds.top+dst->y; 269 srcrect.bottom = srcrect.top + src->h;
262 dstrect.left = SDL_bounds.left+dst->x; 270 srcrect.left = src->x;
263 dstrect.bottom = dstrect.top+dst->h; 271 srcrect.right = srcrect.left + src->w;
264 dstrect.right = dstrect.left+dst->w; 272 dstrect.top = SDL_bounds.top + dst->y;
273 dstrect.left = SDL_bounds.left + dst->x;
274 dstrect.bottom = dstrect.top + dst->h;
275 dstrect.right = dstrect.left + dst->w;
265 #ifdef USE_DIRECTX_OVERLAY 276 #ifdef USE_DIRECTX_OVERLAY
266 result = IDirectDrawSurface3_UpdateOverlay(surface, &srcrect, 277 result = IDirectDrawSurface3_UpdateOverlay (surface, &srcrect,
267 SDL_primary, &dstrect, DDOVER_SHOW, NULL); 278 SDL_primary, &dstrect,
268 if ( result != DD_OK ) { 279 DDOVER_SHOW, NULL);
269 SetDDerror("DirectDrawSurface3::UpdateOverlay", result); 280 if (result != DD_OK) {
270 return(-1); 281 SetDDerror ("DirectDrawSurface3::UpdateOverlay", result);
271 } 282 return (-1);
283 }
272 #else 284 #else
273 result = IDirectDrawSurface3_Blt(SDL_primary, &dstrect, surface, &srcrect, 285 result =
274 DDBLT_WAIT, NULL); 286 IDirectDrawSurface3_Blt (SDL_primary, &dstrect, surface, &srcrect,
275 if ( result != DD_OK ) { 287 DDBLT_WAIT, NULL);
276 SetDDerror("DirectDrawSurface3::Blt", result); 288 if (result != DD_OK) {
277 return(-1); 289 SetDDerror ("DirectDrawSurface3::Blt", result);
278 } 290 return (-1);
279 #endif 291 }
280 return(0); 292 #endif
281 } 293 return (0);
282 294 }
283 void DX5_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) 295
284 { 296 void
285 struct private_yuvhwdata *hwdata; 297 DX5_FreeYUVOverlay (_THIS, SDL_Overlay * overlay)
286 298 {
287 hwdata = overlay->hwdata; 299 struct private_yuvhwdata *hwdata;
288 if ( hwdata ) { 300
289 if ( hwdata->surface ) { 301 hwdata = overlay->hwdata;
290 IDirectDrawSurface_Release(hwdata->surface); 302 if (hwdata) {
291 } 303 if (hwdata->surface) {
292 SDL_free(hwdata); 304 IDirectDrawSurface_Release (hwdata->surface);
293 } 305 }
294 } 306 SDL_free (hwdata);
295 307 }
308 }
309
310 /* vi: set ts=4 sw=4 expandtab: */