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