Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
330 lines (261 loc) · 9.37 KB

SDL_QuartzYUV.m

File metadata and controls

330 lines (261 loc) · 9.37 KB
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2003 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
Feb 21, 2006
Feb 21, 2006
22
#include "SDL_config.h"
23
24
25
#include "SDL_QuartzVideo.h"
#include "SDL_QuartzWindow.h"
Feb 16, 2006
Feb 16, 2006
26
#include "../SDL_yuvfuncs.h"
27
28
29
30
31
32
33
34
35
36
37
38
39
#define yuv_idh (this->hidden->yuv_idh)
#define yuv_matrix (this->hidden->yuv_matrix)
#define yuv_codec (this->hidden->yuv_codec)
#define yuv_seq (this->hidden->yuv_seq)
#define yuv_pixmap (this->hidden->yuv_pixmap)
#define yuv_data (this->hidden->yuv_data)
#define yuv_width (this->hidden->yuv_width)
#define yuv_height (this->hidden->yuv_height)
#define yuv_port (this->hidden->yuv_port)
Jul 10, 2006
Jul 10, 2006
40
41
42
static int
QZ_LockYUV (_THIS, SDL_Overlay * overlay)
{
43
44
45
46
return 0;
}
Jul 10, 2006
Jul 10, 2006
47
48
49
static void
QZ_UnlockYUV (_THIS, SDL_Overlay * overlay)
{
50
51
52
53
;
}
Jul 10, 2006
Jul 10, 2006
54
55
56
static int
QZ_DisplayYUV (_THIS, SDL_Overlay * overlay, SDL_Rect * src, SDL_Rect * dst)
{
57
58
59
60
OSErr err;
CodecFlags flags;
Apr 22, 2006
Apr 22, 2006
61
if (dst->x != 0 || dst->y != 0) {
62
Apr 22, 2006
Apr 22, 2006
63
SDL_SetError ("Need a dst at (0,0)");
64
65
66
return -1;
}
Apr 22, 2006
Apr 22, 2006
67
if (dst->w != yuv_width || dst->h != yuv_height) {
68
69
70
Fixed scale_x, scale_y;
Jul 10, 2006
Jul 10, 2006
71
72
scale_x = FixDiv (Long2Fix (dst->w), Long2Fix (overlay->w));
scale_y = FixDiv (Long2Fix (dst->h), Long2Fix (overlay->h));
73
74
SetIdentityMatrix (yuv_matrix);
Jul 10, 2006
Jul 10, 2006
75
76
ScaleMatrix (yuv_matrix, scale_x, scale_y, Long2Fix (0),
Long2Fix (0));
77
78
79
SetDSequenceMatrix (yuv_seq, yuv_matrix);
Apr 22, 2006
Apr 22, 2006
80
81
yuv_width = dst->w;
yuv_height = dst->h;
82
83
}
Jul 10, 2006
Jul 10, 2006
84
85
if ((err = DecompressSequenceFrameS (yuv_seq,
(void *) yuv_pixmap,
86
sizeof (PlanarPixmapInfoYUV420),
Jul 10, 2006
Jul 10, 2006
87
88
codecFlagUseImageBuffer, &flags,
nil) != noErr)) {
89
90
91
SDL_SetError ("DecompressSequenceFrameS failed");
}
Mar 15, 2006
Mar 15, 2006
92
return err != noErr;
93
94
}
Jul 10, 2006
Jul 10, 2006
95
96
97
static void
QZ_FreeHWYUV (_THIS, SDL_Overlay * overlay)
{
98
99
CDSequenceEnd (yuv_seq);
Jul 10, 2006
Jul 10, 2006
100
ExitMovies ();
101
May 1, 2006
May 1, 2006
102
103
104
SDL_free (overlay->hwfuncs);
SDL_free (overlay->pitches);
SDL_free (overlay->pixels);
105
106
if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {
Jul 10, 2006
Jul 10, 2006
107
[qz_window close];
108
109
110
qz_window = nil;
}
May 1, 2006
May 1, 2006
111
SDL_free (yuv_matrix);
Jul 10, 2006
Jul 10, 2006
112
DisposeHandle ((Handle) yuv_idh);
113
114
115
116
117
118
119
120
}
/* check for 16 byte alignment, bail otherwise */
#define CHECK_ALIGN(x) do { if ((Uint32)x & 15) { SDL_SetError("Alignment error"); return NULL; } } while(0)
/* align a byte offset, return how much to add to make it a multiple of 16 */
#define ALIGN(x) ((16 - (x & 15)) & 15)
Jul 10, 2006
Jul 10, 2006
121
122
123
124
SDL_Overlay *
QZ_CreateYUVOverlay (_THIS, int width, int height,
Uint32 format, SDL_Surface * display)
{
125
126
127
128
129
130
Uint32 codec;
OSStatus err;
CGrafPtr port;
SDL_Overlay *overlay;
Jul 10, 2006
Jul 10, 2006
131
if (format == SDL_YV12_OVERLAY || format == SDL_IYUV_OVERLAY) {
132
133
codec = kYUV420CodecType;
Jul 10, 2006
Jul 10, 2006
134
} else {
135
136
137
138
SDL_SetError ("Hardware: unsupported video format");
return NULL;
}
Jul 10, 2006
Jul 10, 2006
139
140
yuv_idh =
(ImageDescriptionHandle) NewHandleClear (sizeof (ImageDescription));
141
if (yuv_idh == NULL) {
Jul 10, 2006
Jul 10, 2006
142
SDL_OutOfMemory ();
143
144
145
return NULL;
}
Jul 10, 2006
Jul 10, 2006
146
yuv_matrix = (MatrixRecordPtr) SDL_malloc (sizeof (MatrixRecord));
147
if (yuv_matrix == NULL) {
Jul 10, 2006
Jul 10, 2006
148
SDL_OutOfMemory ();
149
150
151
return NULL;
}
Jul 10, 2006
Jul 10, 2006
152
if (EnterMovies () != noErr) {
153
154
155
156
157
158
159
160
161
162
163
164
165
SDL_SetError ("Could not init QuickTime for YUV playback");
return NULL;
}
err = FindCodec (codec, bestSpeedCodec, nil, &yuv_codec);
if (err != noErr) {
SDL_SetError ("Could not find QuickTime codec for format");
return NULL;
}
if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {
/*
Jul 10, 2006
Jul 10, 2006
166
167
168
169
170
Acceleration requires a window to be present.
A CGrafPtr that points to the screen isn't good enough
*/
NSRect content =
NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
171
Jul 10, 2006
Jul 10, 2006
172
qz_window =[[SDL_QuartzWindow alloc] initWithContentRect: content styleMask: NSBorderlessWindowMask backing: NSBackingStoreBuffered defer:NO];
173
174
175
176
177
178
if (qz_window == nil) {
SDL_SetError ("Could not create the Cocoa window");
return NULL;
}
Jul 10, 2006
Jul 10, 2006
179
180
181
182
183
184
[qz_window setContentView:[[NSQuickDrawView alloc] init]];
[qz_window setReleasedWhenClosed:YES];
[qz_window center];
[qz_window setAcceptsMouseMovedEvents:YES];
[qz_window setLevel:CGShieldingWindowLevel ()];
[qz_window makeKeyAndOrderFront:nil];
185
Jul 10, 2006
Jul 10, 2006
186
port =[[qz_window contentView] qdPort];
187
SetPort (port);
Jul 10, 2006
Jul 10, 2006
188
189
/*
Jul 10, 2006
Jul 10, 2006
190
191
192
193
194
195
196
197
198
199
BUG: would like to remove white flash when window kicks in
{
Rect r;
SetRect (&r, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
PaintRect (&r);
QDFlushPortBuffer (port, nil);
}
*/
} else {
port =[window_view qdPort];
200
201
SetPort (port);
}
Jul 10, 2006
Jul 10, 2006
202
203
SetIdentityMatrix (yuv_matrix);
Jul 10, 2006
Jul 10, 2006
204
205
206
207
208
HLock ((Handle) yuv_idh);
(**yuv_idh).idSize = sizeof (ImageDescription);
(**yuv_idh).cType = codec;
209
210
211
212
(**yuv_idh).version = 1;
(**yuv_idh).revisionLevel = 0;
(**yuv_idh).width = width;
(**yuv_idh).height = height;
Jul 10, 2006
Jul 10, 2006
213
214
(**yuv_idh).hRes = Long2Fix (72);
(**yuv_idh).vRes = Long2Fix (72);
215
216
217
218
219
(**yuv_idh).spatialQuality = codecLosslessQuality;
(**yuv_idh).frameCount = 1;
(**yuv_idh).clutID = -1;
(**yuv_idh).dataSize = 0;
(**yuv_idh).depth = 24;
Jul 10, 2006
Jul 10, 2006
220
221
222
223
HUnlock ((Handle) yuv_idh);
err = DecompressSequenceBeginS (&yuv_seq,
224
225
226
227
228
229
230
231
232
233
yuv_idh,
NULL,
0,
port,
NULL,
NULL,
yuv_matrix,
0,
NULL,
codecFlagUseImageBuffer,
Jul 10, 2006
Jul 10, 2006
234
235
codecLosslessQuality, yuv_codec);
236
237
238
239
if (err != noErr) {
SDL_SetError ("Error trying to start YUV codec.");
return NULL;
}
Jul 10, 2006
Jul 10, 2006
240
241
overlay = (SDL_Overlay *) SDL_malloc (sizeof (*overlay));
242
if (overlay == NULL) {
Jul 10, 2006
Jul 10, 2006
243
SDL_OutOfMemory ();
244
245
return NULL;
}
Jul 10, 2006
Jul 10, 2006
246
247
248
249
250
251
overlay->format = format;
overlay->w = width;
overlay->h = height;
overlay->planes = 3;
overlay->hw_overlay = 1;
252
{
Jul 10, 2006
Jul 10, 2006
253
254
255
256
int offset;
Uint8 **pixels;
Uint16 *pitches;
int plane2, plane3;
257
258
259
if (format == SDL_IYUV_OVERLAY) {
Jul 10, 2006
Jul 10, 2006
260
plane2 = 1; /* Native codec format */
261
plane3 = 2;
Jul 10, 2006
Jul 10, 2006
262
} else if (format == SDL_YV12_OVERLAY) {
263
264
/* switch the U and V planes */
Jul 10, 2006
Jul 10, 2006
265
266
267
268
plane2 = 2; /* U plane maps to plane 3 */
plane3 = 1; /* V plane maps to plane 2 */
} else {
SDL_SetError ("Unsupported YUV format");
269
270
271
return NULL;
}
Jul 10, 2006
Jul 10, 2006
272
273
pixels = (Uint8 **) SDL_malloc (sizeof (*pixels) * 3);
pitches = (Uint16 *) SDL_malloc (sizeof (*pitches) * 3);
274
if (pixels == NULL || pitches == NULL) {
Jul 10, 2006
Jul 10, 2006
275
SDL_OutOfMemory ();
276
277
278
return NULL;
}
Jul 10, 2006
Jul 10, 2006
279
280
281
yuv_pixmap = (PlanarPixmapInfoYUV420 *)
SDL_malloc (sizeof (PlanarPixmapInfoYUV420) +
(width * height * 2));
282
283
284
285
286
287
if (yuv_pixmap == NULL) {
SDL_OutOfMemory ();
return NULL;
}
/* CHECK_ALIGN(yuv_pixmap); */
Jul 10, 2006
Jul 10, 2006
288
offset = sizeof (PlanarPixmapInfoYUV420);
289
290
291
/* offset += ALIGN(offset); */
/* CHECK_ALIGN(offset); */
Jul 10, 2006
Jul 10, 2006
292
pixels[0] = (Uint8 *) yuv_pixmap + offset;
293
294
295
296
297
298
299
/* CHECK_ALIGN(pixels[0]); */
pitches[0] = width;
yuv_pixmap->componentInfoY.offset = offset;
yuv_pixmap->componentInfoY.rowBytes = width;
offset += width * height;
Jul 10, 2006
Jul 10, 2006
300
pixels[plane2] = (Uint8 *) yuv_pixmap + offset;
301
302
303
304
305
pitches[plane2] = width / 2;
yuv_pixmap->componentInfoCb.offset = offset;
yuv_pixmap->componentInfoCb.rowBytes = width / 2;
offset += (width * height / 4);
Jul 10, 2006
Jul 10, 2006
306
pixels[plane3] = (Uint8 *) yuv_pixmap + offset;
307
308
309
310
311
312
313
314
pitches[plane3] = width / 2;
yuv_pixmap->componentInfoCr.offset = offset;
yuv_pixmap->componentInfoCr.rowBytes = width / 2;
overlay->pixels = pixels;
overlay->pitches = pitches;
}
Jul 10, 2006
Jul 10, 2006
315
overlay->hwfuncs = SDL_malloc (sizeof (*overlay->hwfuncs));
316
if (overlay->hwfuncs == NULL) {
Jul 10, 2006
Jul 10, 2006
317
SDL_OutOfMemory ();
318
319
return NULL;
}
Jul 10, 2006
Jul 10, 2006
320
321
322
overlay->hwfuncs->Lock = QZ_LockYUV;
overlay->hwfuncs->Unlock = QZ_UnlockYUV;
323
overlay->hwfuncs->Display = QZ_DisplayYUV;
Jul 10, 2006
Jul 10, 2006
324
overlay->hwfuncs->FreeHW = QZ_FreeHWYUV;
325
326
327
yuv_width = overlay->w;
yuv_height = overlay->h;
Jul 10, 2006
Jul 10, 2006
328
329
330
return overlay;
}