comparison src/video/windx5/SDL_dx5yuv.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents 51038e80ae59
children
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
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, PrintFOURCC(codes[i]));
140 } 145 }
141 SDL_free(codes); 146 SDL_free(codes);
142 } 147 }
143 } else { 148 } else {
144 fprintf(stderr, "No FOURCC codes supported\n"); 149 fprintf(stderr, "No FOURCC codes supported\n");
145 } 150 }
146 #endif 151 #endif
147 152
148 /* Create the overlay structure */ 153 /* Create the overlay structure */
149 overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay); 154 overlay = (SDL_Overlay *) SDL_malloc(sizeof *overlay);
150 if ( overlay == NULL ) { 155 if (overlay == NULL) {
151 SDL_OutOfMemory(); 156 SDL_OutOfMemory();
152 return(NULL); 157 return (NULL);
153 } 158 }
154 SDL_memset(overlay, 0, (sizeof *overlay)); 159 SDL_memset(overlay, 0, (sizeof *overlay));
155 160
156 /* Fill in the basic members */ 161 /* Fill in the basic members */
157 overlay->format = format; 162 overlay->format = format;
158 overlay->w = width; 163 overlay->w = width;
159 overlay->h = height; 164 overlay->h = height;
160 165
161 /* Set up the YUV surface function structure */ 166 /* Set up the YUV surface function structure */
162 overlay->hwfuncs = &dx5_yuvfuncs; 167 overlay->hwfuncs = &dx5_yuvfuncs;
163 168
164 /* Create the pixel data and lookup tables */ 169 /* Create the pixel data and lookup tables */
165 hwdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *hwdata); 170 hwdata = (struct private_yuvhwdata *) SDL_malloc(sizeof *hwdata);
166 overlay->hwdata = hwdata; 171 overlay->hwdata = hwdata;
167 if ( hwdata == NULL ) { 172 if (hwdata == NULL) {
168 SDL_OutOfMemory(); 173 SDL_OutOfMemory();
169 SDL_FreeYUVOverlay(overlay); 174 SDL_FreeYUVOverlay(overlay);
170 return(NULL); 175 return (NULL);
171 } 176 }
172 hwdata->surface = CreateYUVSurface(this, width, height, format); 177 hwdata->surface = CreateYUVSurface(this, width, height, format);
173 if ( hwdata->surface == NULL ) { 178 if (hwdata->surface == NULL) {
174 SDL_FreeYUVOverlay(overlay); 179 SDL_FreeYUVOverlay(overlay);
175 return(NULL); 180 return (NULL);
176 } 181 }
177 overlay->hw_overlay = 1; 182 overlay->hw_overlay = 1;
178 183
179 /* Set up the plane pointers */ 184 /* Set up the plane pointers */
180 overlay->pitches = hwdata->pitches; 185 overlay->pitches = hwdata->pitches;
181 overlay->pixels = hwdata->planes; 186 overlay->pixels = hwdata->planes;
182 switch (format) { 187 switch (format) {
183 case SDL_YV12_OVERLAY: 188 case SDL_YV12_OVERLAY:
184 case SDL_IYUV_OVERLAY: 189 case SDL_IYUV_OVERLAY:
185 overlay->planes = 3; 190 overlay->planes = 3;
186 break; 191 break;
187 default: 192 default:
188 overlay->planes = 1; 193 overlay->planes = 1;
189 break; 194 break;
190 } 195 }
191 196
192 /* We're all done.. */ 197 /* We're all done.. */
193 return(overlay); 198 return (overlay);
194 } 199 }
195 200
196 int DX5_LockYUVOverlay(_THIS, SDL_Overlay *overlay) 201 int
197 { 202 DX5_LockYUVOverlay(_THIS, SDL_Overlay * overlay)
198 HRESULT result; 203 {
199 LPDIRECTDRAWSURFACE3 surface; 204 HRESULT result;
200 DDSURFACEDESC ddsd; 205 LPDIRECTDRAWSURFACE3 surface;
201 206 DDSURFACEDESC ddsd;
202 surface = overlay->hwdata->surface; 207
203 SDL_memset(&ddsd, 0, sizeof(ddsd)); 208 surface = overlay->hwdata->surface;
204 ddsd.dwSize = sizeof(ddsd); 209 SDL_memset(&ddsd, 0, sizeof(ddsd));
205 result = IDirectDrawSurface3_Lock(surface, NULL, 210 ddsd.dwSize = sizeof(ddsd);
206 &ddsd, DDLOCK_NOSYSLOCK, NULL); 211 result = IDirectDrawSurface3_Lock(surface, NULL,
207 if ( result == DDERR_SURFACELOST ) { 212 &ddsd, DDLOCK_NOSYSLOCK, NULL);
208 result = IDirectDrawSurface3_Restore(surface); 213 if (result == DDERR_SURFACELOST) {
209 result = IDirectDrawSurface3_Lock(surface, NULL, &ddsd, 214 result = IDirectDrawSurface3_Restore(surface);
210 (DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL); 215 result = IDirectDrawSurface3_Lock(surface, NULL, &ddsd,
211 } 216 (DDLOCK_NOSYSLOCK | DDLOCK_WAIT),
212 if ( result != DD_OK ) { 217 NULL);
213 SetDDerror("DirectDrawSurface3::Lock", result); 218 }
214 return(-1); 219 if (result != DD_OK) {
215 } 220 SetDDerror("DirectDrawSurface3::Lock", result);
216 221 return (-1);
217 /* Find the pitch and offset values for the overlay */ 222 }
223
224 /* Find the pitch and offset values for the overlay */
218 #if defined(NONAMELESSUNION) 225 #if defined(NONAMELESSUNION)
219 overlay->pitches[0] = (Uint16)ddsd.u1.lPitch; 226 overlay->pitches[0] = (Uint16) ddsd.u1.lPitch;
220 #else 227 #else
221 overlay->pitches[0] = (Uint16)ddsd.lPitch; 228 overlay->pitches[0] = (Uint16) ddsd.lPitch;
222 #endif 229 #endif
223 overlay->pixels[0] = (Uint8 *)ddsd.lpSurface; 230 overlay->pixels[0] = (Uint8 *) ddsd.lpSurface;
224 switch (overlay->format) { 231 switch (overlay->format) {
225 case SDL_YV12_OVERLAY: 232 case SDL_YV12_OVERLAY:
226 case SDL_IYUV_OVERLAY: 233 case SDL_IYUV_OVERLAY:
227 /* Add the two extra planes */ 234 /* Add the two extra planes */
228 overlay->pitches[1] = overlay->pitches[0] / 2; 235 overlay->pitches[1] = overlay->pitches[0] / 2;
229 overlay->pitches[2] = overlay->pitches[0] / 2; 236 overlay->pitches[2] = overlay->pitches[0] / 2;
230 overlay->pixels[1] = overlay->pixels[0] + 237 overlay->pixels[1] = overlay->pixels[0] +
231 overlay->pitches[0] * overlay->h; 238 overlay->pitches[0] * overlay->h;
232 overlay->pixels[2] = overlay->pixels[1] + 239 overlay->pixels[2] = overlay->pixels[1] +
233 overlay->pitches[1] * overlay->h / 2; 240 overlay->pitches[1] * overlay->h / 2;
234 break; 241 break;
235 default: 242 default:
236 /* Only one plane, no worries */ 243 /* Only one plane, no worries */
237 break; 244 break;
238 } 245 }
239 return(0); 246 return (0);
240 } 247 }
241 248
242 void DX5_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay) 249 void
243 { 250 DX5_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay)
244 LPDIRECTDRAWSURFACE3 surface; 251 {
245 252 LPDIRECTDRAWSURFACE3 surface;
246 surface = overlay->hwdata->surface; 253
247 IDirectDrawSurface3_Unlock(surface, NULL); 254 surface = overlay->hwdata->surface;
248 } 255 IDirectDrawSurface3_Unlock(surface, NULL);
249 256 }
250 int DX5_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst) 257
251 { 258 int
252 HRESULT result; 259 DX5_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay, SDL_Rect * src,
253 LPDIRECTDRAWSURFACE3 surface; 260 SDL_Rect * dst)
254 RECT srcrect, dstrect; 261 {
255 262 HRESULT result;
256 surface = overlay->hwdata->surface; 263 LPDIRECTDRAWSURFACE3 surface;
257 srcrect.top = src->y; 264 RECT srcrect, dstrect;
258 srcrect.bottom = srcrect.top+src->h; 265
259 srcrect.left = src->x; 266 surface = overlay->hwdata->surface;
260 srcrect.right = srcrect.left+src->w; 267 srcrect.top = src->y;
261 dstrect.top = SDL_bounds.top+dst->y; 268 srcrect.bottom = srcrect.top + src->h;
262 dstrect.left = SDL_bounds.left+dst->x; 269 srcrect.left = src->x;
263 dstrect.bottom = dstrect.top+dst->h; 270 srcrect.right = srcrect.left + src->w;
264 dstrect.right = dstrect.left+dst->w; 271 dstrect.top = SDL_bounds.top + dst->y;
272 dstrect.left = SDL_bounds.left + dst->x;
273 dstrect.bottom = dstrect.top + dst->h;
274 dstrect.right = dstrect.left + dst->w;
265 #ifdef USE_DIRECTX_OVERLAY 275 #ifdef USE_DIRECTX_OVERLAY
266 result = IDirectDrawSurface3_UpdateOverlay(surface, &srcrect, 276 result = IDirectDrawSurface3_UpdateOverlay(surface, &srcrect,
267 SDL_primary, &dstrect, DDOVER_SHOW, NULL); 277 SDL_primary, &dstrect,
268 if ( result != DD_OK ) { 278 DDOVER_SHOW, NULL);
269 SetDDerror("DirectDrawSurface3::UpdateOverlay", result); 279 if (result != DD_OK) {
270 return(-1); 280 SetDDerror("DirectDrawSurface3::UpdateOverlay", result);
271 } 281 return (-1);
282 }
272 #else 283 #else
273 result = IDirectDrawSurface3_Blt(SDL_primary, &dstrect, surface, &srcrect, 284 result =
274 DDBLT_WAIT, NULL); 285 IDirectDrawSurface3_Blt(SDL_primary, &dstrect, surface, &srcrect,
275 if ( result != DD_OK ) { 286 DDBLT_WAIT, NULL);
276 SetDDerror("DirectDrawSurface3::Blt", result); 287 if (result != DD_OK) {
277 return(-1); 288 SetDDerror("DirectDrawSurface3::Blt", result);
278 } 289 return (-1);
279 #endif 290 }
280 return(0); 291 #endif
281 } 292 return (0);
282 293 }
283 void DX5_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) 294
284 { 295 void
285 struct private_yuvhwdata *hwdata; 296 DX5_FreeYUVOverlay(_THIS, SDL_Overlay * overlay)
286 297 {
287 hwdata = overlay->hwdata; 298 struct private_yuvhwdata *hwdata;
288 if ( hwdata ) { 299
289 if ( hwdata->surface ) { 300 hwdata = overlay->hwdata;
290 IDirectDrawSurface_Release(hwdata->surface); 301 if (hwdata) {
291 } 302 if (hwdata->surface) {
292 SDL_free(hwdata); 303 IDirectDrawSurface_Release(hwdata->surface);
293 } 304 }
294 } 305 SDL_free(hwdata);
295 306 }
307 }
308
309 /* vi: set ts=4 sw=4 expandtab: */