Mercurial > sdl-ios-xcode
comparison src/video/quartz/SDL_QuartzYUV.m @ 761:c5b2b6d2d1fe
Date: Wed, 31 Dec 2003 21:55:30 +0100
From: Max Horn
Subject: SDL: video/quartz cleanup
while doing some experimental changes in the quartz code, I was annoyed
by having to recompile that one big .o file over and over again. So I
decided to finally realize one TODO: properly splitting the code over
multiple files :-).
With two exceptions, I didn't make code changes, only rearranged files
and added new headers. Since there are several new files, making a
patch didn't work out so well, so I decided to just send you all the
new & modified files.
The one source change I made is related to showing/hiding the mouse. I
renamed cursor_visible to cursor_should_be_visible and cursor_hidden to
cursor_visible; I think that makes reading the code easier.
Then I added two new functions: QZ_ShowMouse and QZ_HideMouse. They
help manage cursor_visible (the former 'cursor_hidden'). Finally I
replaced the Carbon ShowCursor/HiderCuror calls by [NSCursor hide] and
[NSCursor unhide]. The API docs are not conclusive, but it might be
that with those the "cursor_visible" (former 'cursor_hidden') hack may
not be necessary anymore; however so far I didn't test this hypothesis,
so I left that in.
The other change was to remove in_foreground and use [NSApp isActive]
instead: Manually keeping track of whether we are in the foreground is
error prone. This should work better in some corner cases.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 04 Jan 2004 14:55:35 +0000 |
parents | |
children | 19418e4422cb |
comparison
equal
deleted
inserted
replaced
760:cf9dd3aa6756 | 761:c5b2b6d2d1fe |
---|---|
1 /* | |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997-2003 Sam Lantinga | |
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 | |
20 slouken@libsdl.org | |
21 */ | |
22 | |
23 #include "SDL_QuartzVideo.h" | |
24 #include "SDL_QuartzWindow.h" | |
25 #include "SDL_yuvfuncs.h" | |
26 | |
27 | |
28 #define yuv_idh (this->hidden->yuv_idh) | |
29 #define yuv_matrix (this->hidden->yuv_matrix) | |
30 #define yuv_codec (this->hidden->yuv_codec) | |
31 #define yuv_seq (this->hidden->yuv_seq) | |
32 #define yuv_pixmap (this->hidden->yuv_pixmap) | |
33 #define yuv_data (this->hidden->yuv_data) | |
34 #define yuv_width (this->hidden->yuv_width) | |
35 #define yuv_height (this->hidden->yuv_height) | |
36 #define yuv_port (this->hidden->yuv_port) | |
37 | |
38 | |
39 static int QZ_LockYUV (_THIS, SDL_Overlay *overlay) { | |
40 | |
41 return 0; | |
42 } | |
43 | |
44 static void QZ_UnlockYUV (_THIS, SDL_Overlay *overlay) { | |
45 | |
46 ; | |
47 } | |
48 | |
49 static int QZ_DisplayYUV (_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) { | |
50 | |
51 OSErr err; | |
52 CodecFlags flags; | |
53 | |
54 if (dstrect->x != 0 || dstrect->y != 0) { | |
55 | |
56 SDL_SetError ("Need a dstrect at (0,0)"); | |
57 return -1; | |
58 } | |
59 | |
60 if (dstrect->w != yuv_width || dstrect->h != yuv_height) { | |
61 | |
62 Fixed scale_x, scale_y; | |
63 | |
64 scale_x = FixDiv ( Long2Fix (dstrect->w), Long2Fix (overlay->w) ); | |
65 scale_y = FixDiv ( Long2Fix (dstrect->h), Long2Fix (overlay->h) ); | |
66 | |
67 SetIdentityMatrix (yuv_matrix); | |
68 ScaleMatrix (yuv_matrix, scale_x, scale_y, Long2Fix (0), Long2Fix (0)); | |
69 | |
70 SetDSequenceMatrix (yuv_seq, yuv_matrix); | |
71 | |
72 yuv_width = dstrect->w; | |
73 yuv_height = dstrect->h; | |
74 } | |
75 | |
76 if( ( err = DecompressSequenceFrameS( | |
77 yuv_seq, | |
78 (void*)yuv_pixmap, | |
79 sizeof (PlanarPixmapInfoYUV420), | |
80 codecFlagUseImageBuffer, &flags, nil ) != noErr ) ) | |
81 { | |
82 SDL_SetError ("DecompressSequenceFrameS failed"); | |
83 } | |
84 | |
85 return err == noErr; | |
86 } | |
87 | |
88 static void QZ_FreeHWYUV (_THIS, SDL_Overlay *overlay) { | |
89 | |
90 CDSequenceEnd (yuv_seq); | |
91 ExitMovies(); | |
92 | |
93 free (overlay->hwfuncs); | |
94 free (overlay->pitches); | |
95 free (overlay->pixels); | |
96 | |
97 if (SDL_VideoSurface->flags & SDL_FULLSCREEN) { | |
98 [ qz_window close ]; | |
99 qz_window = nil; | |
100 } | |
101 | |
102 free (yuv_matrix); | |
103 DisposeHandle ((Handle)yuv_idh); | |
104 } | |
105 | |
106 /* check for 16 byte alignment, bail otherwise */ | |
107 #define CHECK_ALIGN(x) do { if ((Uint32)x & 15) { SDL_SetError("Alignment error"); return NULL; } } while(0) | |
108 | |
109 /* align a byte offset, return how much to add to make it a multiple of 16 */ | |
110 #define ALIGN(x) ((16 - (x & 15)) & 15) | |
111 | |
112 SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height, | |
113 Uint32 format, SDL_Surface *display) { | |
114 | |
115 Uint32 codec; | |
116 OSStatus err; | |
117 CGrafPtr port; | |
118 SDL_Overlay *overlay; | |
119 | |
120 if (format == SDL_YV12_OVERLAY || | |
121 format == SDL_IYUV_OVERLAY) { | |
122 | |
123 codec = kYUV420CodecType; | |
124 } | |
125 else { | |
126 SDL_SetError ("Hardware: unsupported video format"); | |
127 return NULL; | |
128 } | |
129 | |
130 yuv_idh = (ImageDescriptionHandle) NewHandleClear (sizeof(ImageDescription)); | |
131 if (yuv_idh == NULL) { | |
132 SDL_OutOfMemory(); | |
133 return NULL; | |
134 } | |
135 | |
136 yuv_matrix = (MatrixRecordPtr) malloc (sizeof(MatrixRecord)); | |
137 if (yuv_matrix == NULL) { | |
138 SDL_OutOfMemory(); | |
139 return NULL; | |
140 } | |
141 | |
142 if ( EnterMovies() != noErr ) { | |
143 SDL_SetError ("Could not init QuickTime for YUV playback"); | |
144 return NULL; | |
145 } | |
146 | |
147 err = FindCodec (codec, bestSpeedCodec, nil, &yuv_codec); | |
148 if (err != noErr) { | |
149 SDL_SetError ("Could not find QuickTime codec for format"); | |
150 return NULL; | |
151 } | |
152 | |
153 if (SDL_VideoSurface->flags & SDL_FULLSCREEN) { | |
154 | |
155 /* | |
156 Acceleration requires a window to be present. | |
157 A CGrafPtr that points to the screen isn't good enough | |
158 */ | |
159 NSRect content = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h); | |
160 | |
161 qz_window = [ [ SDL_QuartzWindow alloc ] | |
162 initWithContentRect:content | |
163 styleMask:NSBorderlessWindowMask | |
164 backing:NSBackingStoreBuffered defer:NO ]; | |
165 | |
166 if (qz_window == nil) { | |
167 SDL_SetError ("Could not create the Cocoa window"); | |
168 return NULL; | |
169 } | |
170 | |
171 [ qz_window setContentView:[ [ NSQuickDrawView alloc ] init ] ]; | |
172 [ qz_window setReleasedWhenClosed:YES ]; | |
173 [ qz_window center ]; | |
174 [ qz_window setAcceptsMouseMovedEvents:YES ]; | |
175 [ qz_window setLevel:CGShieldingWindowLevel() ]; | |
176 [ qz_window makeKeyAndOrderFront:nil ]; | |
177 | |
178 port = [ [ qz_window contentView ] qdPort ]; | |
179 SetPort (port); | |
180 | |
181 /* | |
182 BUG: would like to remove white flash when window kicks in | |
183 { | |
184 Rect r; | |
185 SetRect (&r, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h); | |
186 PaintRect (&r); | |
187 QDFlushPortBuffer (port, nil); | |
188 } | |
189 */ | |
190 } | |
191 else { | |
192 port = [ window_view qdPort ]; | |
193 SetPort (port); | |
194 } | |
195 | |
196 SetIdentityMatrix (yuv_matrix); | |
197 | |
198 HLock ((Handle)yuv_idh); | |
199 | |
200 (**yuv_idh).idSize = sizeof(ImageDescription); | |
201 (**yuv_idh).cType = codec; | |
202 (**yuv_idh).version = 1; | |
203 (**yuv_idh).revisionLevel = 0; | |
204 (**yuv_idh).width = width; | |
205 (**yuv_idh).height = height; | |
206 (**yuv_idh).hRes = Long2Fix(72); | |
207 (**yuv_idh).vRes = Long2Fix(72); | |
208 (**yuv_idh).spatialQuality = codecLosslessQuality; | |
209 (**yuv_idh).frameCount = 1; | |
210 (**yuv_idh).clutID = -1; | |
211 (**yuv_idh).dataSize = 0; | |
212 (**yuv_idh).depth = 24; | |
213 | |
214 HUnlock ((Handle)yuv_idh); | |
215 | |
216 err = DecompressSequenceBeginS ( | |
217 &yuv_seq, | |
218 yuv_idh, | |
219 NULL, | |
220 0, | |
221 port, | |
222 NULL, | |
223 NULL, | |
224 yuv_matrix, | |
225 0, | |
226 NULL, | |
227 codecFlagUseImageBuffer, | |
228 codecLosslessQuality, | |
229 yuv_codec); | |
230 | |
231 if (err != noErr) { | |
232 SDL_SetError ("Error trying to start YUV codec."); | |
233 return NULL; | |
234 } | |
235 | |
236 overlay = (SDL_Overlay*) malloc (sizeof(*overlay)); | |
237 if (overlay == NULL) { | |
238 SDL_OutOfMemory(); | |
239 return NULL; | |
240 } | |
241 | |
242 overlay->format = format; | |
243 overlay->w = width; | |
244 overlay->h = height; | |
245 overlay->planes = 3; | |
246 overlay->hw_overlay = 1; | |
247 { | |
248 int offset; | |
249 Uint8 **pixels; | |
250 Uint16 *pitches; | |
251 int plane2, plane3; | |
252 | |
253 if (format == SDL_IYUV_OVERLAY) { | |
254 | |
255 plane2 = 1; /* Native codec format */ | |
256 plane3 = 2; | |
257 } | |
258 else if (format == SDL_YV12_OVERLAY) { | |
259 | |
260 /* switch the U and V planes */ | |
261 plane2 = 2; /* U plane maps to plane 3 */ | |
262 plane3 = 1; /* V plane maps to plane 2 */ | |
263 } | |
264 else { | |
265 SDL_SetError("Unsupported YUV format"); | |
266 return NULL; | |
267 } | |
268 | |
269 pixels = (Uint8**) malloc (sizeof(*pixels) * 3); | |
270 pitches = (Uint16*) malloc (sizeof(*pitches) * 3); | |
271 if (pixels == NULL || pitches == NULL) { | |
272 SDL_OutOfMemory(); | |
273 return NULL; | |
274 } | |
275 | |
276 yuv_pixmap = (PlanarPixmapInfoYUV420*) | |
277 malloc (sizeof(PlanarPixmapInfoYUV420) + | |
278 (width * height * 2)); | |
279 if (yuv_pixmap == NULL) { | |
280 SDL_OutOfMemory (); | |
281 return NULL; | |
282 } | |
283 | |
284 /* CHECK_ALIGN(yuv_pixmap); */ | |
285 offset = sizeof(PlanarPixmapInfoYUV420); | |
286 /* offset += ALIGN(offset); */ | |
287 /* CHECK_ALIGN(offset); */ | |
288 | |
289 pixels[0] = (Uint8*)yuv_pixmap + offset; | |
290 /* CHECK_ALIGN(pixels[0]); */ | |
291 | |
292 pitches[0] = width; | |
293 yuv_pixmap->componentInfoY.offset = offset; | |
294 yuv_pixmap->componentInfoY.rowBytes = width; | |
295 | |
296 offset += width * height; | |
297 pixels[plane2] = (Uint8*)yuv_pixmap + offset; | |
298 pitches[plane2] = width / 2; | |
299 yuv_pixmap->componentInfoCb.offset = offset; | |
300 yuv_pixmap->componentInfoCb.rowBytes = width / 2; | |
301 | |
302 offset += (width * height / 4); | |
303 pixels[plane3] = (Uint8*)yuv_pixmap + offset; | |
304 pitches[plane3] = width / 2; | |
305 yuv_pixmap->componentInfoCr.offset = offset; | |
306 yuv_pixmap->componentInfoCr.rowBytes = width / 2; | |
307 | |
308 overlay->pixels = pixels; | |
309 overlay->pitches = pitches; | |
310 } | |
311 | |
312 overlay->hwfuncs = malloc (sizeof(*overlay->hwfuncs)); | |
313 if (overlay->hwfuncs == NULL) { | |
314 SDL_OutOfMemory(); | |
315 return NULL; | |
316 } | |
317 | |
318 overlay->hwfuncs->Lock = QZ_LockYUV; | |
319 overlay->hwfuncs->Unlock = QZ_UnlockYUV; | |
320 overlay->hwfuncs->Display = QZ_DisplayYUV; | |
321 overlay->hwfuncs->FreeHW = QZ_FreeHWYUV; | |
322 | |
323 yuv_width = overlay->w; | |
324 yuv_height = overlay->h; | |
325 | |
326 return overlay; | |
327 } |