Mercurial > sdl-ios-xcode
annotate src/video/windx5/SDL_dx5yuv.c @ 571:8e3ce997621c
Date: Thu, 16 Jan 2003 13:48:31 +0200
From: "Mike Gorchak"
Subject: All QNX patches
whole patches concerning QNX. Almost all code has been rewritten by Julian
and me. Added initial support for hw overlays in QNX and many many others
fixes.
P.S. This patches has been reviewed by Dave Rempel from QSSL and included in
SDL 1.2.5 distribution, which coming on 3rd party CD for newest 6.2.1
version of QNX, which will be available soon.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 20 Jan 2003 01:38:37 +0000 |
parents | f6ffac90895c |
children | b8d311d90021 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
297
f6ffac90895c
Updated copyright information for 2002
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
33
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* This is the DirectDraw implementation of YUV video overlays */ | |
29 | |
30 #include <stdlib.h> | |
31 #include <string.h> | |
32 | |
33 #include "SDL_error.h" | |
34 #include "SDL_video.h" | |
35 #include "SDL_dx5yuv_c.h" | |
36 #include "SDL_yuvfuncs.h" | |
37 | |
38 #define USE_DIRECTX_OVERLAY | |
39 | |
40 /* The functions used to manipulate software video overlays */ | |
41 static struct private_yuvhwfuncs dx5_yuvfuncs = { | |
42 DX5_LockYUVOverlay, | |
43 DX5_UnlockYUVOverlay, | |
44 DX5_DisplayYUVOverlay, | |
45 DX5_FreeYUVOverlay | |
46 }; | |
47 | |
48 struct private_yuvhwdata { | |
49 LPDIRECTDRAWSURFACE3 surface; | |
50 | |
51 /* These are just so we don't have to allocate them separately */ | |
52 Uint16 pitches[3]; | |
53 Uint8 *planes[3]; | |
54 }; | |
55 | |
56 | |
57 static LPDIRECTDRAWSURFACE3 CreateYUVSurface(_THIS, | |
58 int width, int height, Uint32 format) | |
59 { | |
60 HRESULT result; | |
61 LPDIRECTDRAWSURFACE dd_surface1; | |
62 LPDIRECTDRAWSURFACE3 dd_surface3; | |
63 DDSURFACEDESC ddsd; | |
64 | |
65 /* Set up the surface description */ | |
66 memset(&ddsd, 0, sizeof(ddsd)); | |
67 ddsd.dwSize = sizeof(ddsd); | |
68 ddsd.dwFlags = (DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|DDSD_PIXELFORMAT); | |
69 ddsd.dwWidth = width; | |
70 ddsd.dwHeight= height; | |
71 #ifdef USE_DIRECTX_OVERLAY | |
72 ddsd.ddsCaps.dwCaps = (DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY); | |
73 #else | |
74 ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY); | |
75 #endif | |
76 ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat); | |
77 ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC; | |
78 ddsd.ddpfPixelFormat.dwFourCC = format; | |
79 | |
80 /* Create the DirectDraw video surface */ | |
81 result = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &dd_surface1, NULL); | |
82 if ( result != DD_OK ) { | |
83 SetDDerror("DirectDraw2::CreateSurface", result); | |
84 return(NULL); | |
85 } | |
86 result = IDirectDrawSurface_QueryInterface(dd_surface1, | |
87 &IID_IDirectDrawSurface3, (LPVOID *)&dd_surface3); | |
88 IDirectDrawSurface_Release(dd_surface1); | |
89 if ( result != DD_OK ) { | |
90 SetDDerror("DirectDrawSurface::QueryInterface", result); | |
91 return(NULL); | |
92 } | |
93 | |
94 /* Make sure the surface format was set properly */ | |
95 memset(&ddsd, 0, sizeof(ddsd)); | |
96 ddsd.dwSize = sizeof(ddsd); | |
97 result = IDirectDrawSurface3_Lock(dd_surface3, NULL, | |
98 &ddsd, DDLOCK_NOSYSLOCK, NULL); | |
99 if ( result != DD_OK ) { | |
100 SetDDerror("DirectDrawSurface3::Lock", result); | |
101 IDirectDrawSurface_Release(dd_surface3); | |
102 return(NULL); | |
103 } | |
104 IDirectDrawSurface3_Unlock(dd_surface3, NULL); | |
105 | |
106 if ( !(ddsd.ddpfPixelFormat.dwFlags & DDPF_FOURCC) || | |
107 (ddsd.ddpfPixelFormat.dwFourCC != format) ) { | |
108 SDL_SetError("DDraw didn't use requested FourCC format"); | |
109 IDirectDrawSurface_Release(dd_surface3); | |
110 return(NULL); | |
111 } | |
112 | |
113 /* We're ready to go! */ | |
114 return(dd_surface3); | |
115 } | |
116 | |
117 #ifdef DEBUG_YUV | |
118 static char *PrintFOURCC(Uint32 code) | |
119 { | |
120 static char buf[5]; | |
121 | |
122 buf[3] = code >> 24; | |
123 buf[2] = (code >> 16) & 0xFF; | |
124 buf[1] = (code >> 8) & 0xFF; | |
125 buf[0] = (code & 0xFF); | |
126 return(buf); | |
127 } | |
128 #endif | |
129 | |
130 SDL_Overlay *DX5_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) | |
131 { | |
132 SDL_Overlay *overlay; | |
133 struct private_yuvhwdata *hwdata; | |
134 | |
135 #ifdef DEBUG_YUV | |
136 DWORD numcodes; | |
137 DWORD *codes; | |
138 | |
139 printf("FOURCC format requested: 0x%x\n", PrintFOURCC(format)); | |
140 IDirectDraw2_GetFourCCCodes(ddraw2, &numcodes, NULL); | |
141 if ( numcodes ) { | |
142 DWORD i; | |
143 codes = malloc(numcodes*sizeof(*codes)); | |
144 if ( codes ) { | |
145 IDirectDraw2_GetFourCCCodes(ddraw2, &numcodes, codes); | |
146 for ( i=0; i<numcodes; ++i ) { | |
147 fprintf(stderr, "Code %d: 0x%x\n", i, PrintFOURCC(codes[i])); | |
148 } | |
149 free(codes); | |
150 } | |
151 } else { | |
152 fprintf(stderr, "No FOURCC codes supported\n"); | |
153 } | |
154 #endif | |
155 | |
156 /* Create the overlay structure */ | |
157 overlay = (SDL_Overlay *)malloc(sizeof *overlay); | |
158 if ( overlay == NULL ) { | |
159 SDL_OutOfMemory(); | |
160 return(NULL); | |
161 } | |
162 memset(overlay, 0, (sizeof *overlay)); | |
163 | |
164 /* Fill in the basic members */ | |
165 overlay->format = format; | |
166 overlay->w = width; | |
167 overlay->h = height; | |
168 | |
169 /* Set up the YUV surface function structure */ | |
170 overlay->hwfuncs = &dx5_yuvfuncs; | |
171 | |
172 /* Create the pixel data and lookup tables */ | |
173 hwdata = (struct private_yuvhwdata *)malloc(sizeof *hwdata); | |
174 overlay->hwdata = hwdata; | |
175 if ( hwdata == NULL ) { | |
176 SDL_OutOfMemory(); | |
177 SDL_FreeYUVOverlay(overlay); | |
178 return(NULL); | |
179 } | |
180 hwdata->surface = CreateYUVSurface(this, width, height, format); | |
181 if ( hwdata->surface == NULL ) { | |
182 SDL_FreeYUVOverlay(overlay); | |
183 return(NULL); | |
184 } | |
185 overlay->hw_overlay = 1; | |
186 | |
187 /* Set up the plane pointers */ | |
188 overlay->pitches = hwdata->pitches; | |
189 overlay->pixels = hwdata->planes; | |
190 switch (format) { | |
191 case SDL_YV12_OVERLAY: | |
192 case SDL_IYUV_OVERLAY: | |
193 overlay->planes = 3; | |
33
81a7158fa836
Silly bug fix from Billy Biggs
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
194 break; |
0 | 195 default: |
196 overlay->planes = 1; | |
197 break; | |
198 } | |
199 | |
200 /* We're all done.. */ | |
201 return(overlay); | |
202 } | |
203 | |
204 int DX5_LockYUVOverlay(_THIS, SDL_Overlay *overlay) | |
205 { | |
206 HRESULT result; | |
207 LPDIRECTDRAWSURFACE3 surface; | |
208 DDSURFACEDESC ddsd; | |
209 | |
210 surface = overlay->hwdata->surface; | |
211 memset(&ddsd, 0, sizeof(ddsd)); | |
212 ddsd.dwSize = sizeof(ddsd); | |
213 result = IDirectDrawSurface3_Lock(surface, NULL, | |
214 &ddsd, DDLOCK_NOSYSLOCK, NULL); | |
215 if ( result == DDERR_SURFACELOST ) { | |
216 result = IDirectDrawSurface3_Restore(surface); | |
217 result = IDirectDrawSurface3_Lock(surface, NULL, &ddsd, | |
218 (DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL); | |
219 } | |
220 if ( result != DD_OK ) { | |
221 SetDDerror("DirectDrawSurface3::Lock", result); | |
222 return(-1); | |
223 } | |
224 | |
225 /* Find the pitch and offset values for the overlay */ | |
226 #if defined(NONAMELESSUNION) | |
227 overlay->pitches[0] = (Uint16)ddsd.u1.lPitch; | |
228 #else | |
229 overlay->pitches[0] = (Uint16)ddsd.lPitch; | |
230 #endif | |
231 overlay->pixels[0] = (Uint8 *)ddsd.lpSurface; | |
232 switch (overlay->format) { | |
233 case SDL_YV12_OVERLAY: | |
234 case SDL_IYUV_OVERLAY: | |
235 /* Add the two extra planes */ | |
236 overlay->pitches[1] = overlay->pitches[0] / 2; | |
237 overlay->pitches[2] = overlay->pitches[0] / 2; | |
238 overlay->pixels[1] = overlay->pixels[0] + | |
239 overlay->pitches[0] * overlay->h; | |
240 overlay->pixels[2] = overlay->pixels[1] + | |
241 overlay->pitches[1] * overlay->h / 2; | |
242 break; | |
243 default: | |
244 /* Only one plane, no worries */ | |
245 break; | |
246 } | |
247 return(0); | |
248 } | |
249 | |
250 void DX5_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay) | |
251 { | |
252 LPDIRECTDRAWSURFACE3 surface; | |
253 | |
254 surface = overlay->hwdata->surface; | |
255 IDirectDrawSurface3_Unlock(surface, NULL); | |
256 } | |
257 | |
258 int DX5_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) | |
259 { | |
260 HRESULT result; | |
261 LPDIRECTDRAWSURFACE3 surface; | |
262 RECT src, dst; | |
263 | |
264 surface = overlay->hwdata->surface; | |
265 src.top = 0; | |
266 src.bottom = overlay->h; | |
267 src.left = 0; | |
268 src.right = overlay->w; | |
269 dst.top = SDL_bounds.top+dstrect->y; | |
270 dst.left = SDL_bounds.left+dstrect->x; | |
271 dst.bottom = dst.top+dstrect->h; | |
272 dst.right = dst.left+dstrect->w; | |
273 #ifdef USE_DIRECTX_OVERLAY | |
274 result = IDirectDrawSurface3_UpdateOverlay(surface, &src, | |
275 SDL_primary, &dst, DDOVER_SHOW, NULL); | |
276 if ( result != DD_OK ) { | |
277 SetDDerror("DirectDrawSurface3::UpdateOverlay", result); | |
278 return(-1); | |
279 } | |
280 #else | |
281 result = IDirectDrawSurface3_Blt(SDL_primary, &dst, surface, &src, | |
282 DDBLT_WAIT, NULL); | |
283 if ( result != DD_OK ) { | |
284 SetDDerror("DirectDrawSurface3::Blt", result); | |
285 return(-1); | |
286 } | |
287 #endif | |
288 return(0); | |
289 } | |
290 | |
291 void DX5_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) | |
292 { | |
293 struct private_yuvhwdata *hwdata; | |
294 | |
295 hwdata = overlay->hwdata; | |
296 if ( hwdata ) { | |
297 if ( hwdata->surface ) { | |
298 IDirectDrawSurface_Release(hwdata->surface); | |
299 } | |
300 free(hwdata); | |
301 } | |
302 } | |
303 |