Mercurial > sdl-ios-xcode
annotate src/video/photon/SDL_phyuv.c @ 563:04dcaf3da918
Massive Quartz input enhancements from Darrell Walisser. His email:
Enclosed is a patch that addresses the following:
--Various minor cleanups.
Removed dead/obsolete code, made some style cleanups
--Mouse Events
Now keep track of what button(s) were pressed so we know when to send
the mouse up event. This fixes the case where the mouse is dragged
outside of the game window and released (in which case we want to send
the mouse up event even though the mouse is outside the game window).
--Input Grabbing
Here is my take on the grabbing situation, which is the basis for the
new implementation.
There are 3 grab states, ungrabbed (UG), visible (VG), and invisible
(IG). Both VG and IG keep the mouse constrained to the window and
produce relative motion events. In VG the cursor is visible (duh), in
IG it is not. In VG, absolute motion events also work.
There are 6 actions that can affect grabbing:
1. Set Fullscreen/Window (F/W). In fullscreen, a visible grab should do
nothing. However, a fullscreen visible grab can be treated just like a
windowed visible grab, which is what I have done to help simplify
things.
2. Cursor hide/show (H/S). If the cursor is hidden when grabbing, the
grab is an invisible grab. If the cursor is visible, the grab should
just constrain the mouse to the window.
3. Input grab/ungrab(G/U). If grabbed, the cursor should be confined to
the window as should the keyboard input. On Mac OS X, the keyboard
input is implicitly grabbed by confining the cursor, except for
command-tab which can switch away from the application. Should the
window come to the foreground if the application is deactivated and
grab input is called? This isn't necessary in this implementation
because the grab state will be asserted upon activation.
Using my notation, these are all the cases that need to be handled
(state + action = new state).
UG+U = UG
UG+G = VG or IG, if cursor is visible or not
UG+H = UG
UG+S = UG
VG+U = UG
VG+G = VG
VG+H = IG
VG+S = VG
IG+U = UG
IG+G = IG
IG+H = IG
IG+S = VG
The cases that result in the same state can be ignored in the code,
which cuts it down to just 5 cases.
Another issue is what happens when the app loses/gains input focus from
deactivate/activate or iconify/deiconify. I think that if input focus
is ever lost (outside of SDL's control), the grab state should be
suspended and the cursor should become visible and active again. When
regained, the cursor should reappear in its original location and/or
grab state. This way, when reactivating the cursor is still in the same
position as before so apps shouldn't get confused when the next motion
event comes in. This is what I've done in this patch.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Fri, 27 Dec 2002 20:52:41 +0000 |
parents | bce7171e7a85 |
children | 8e3ce997621c |
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:
0
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 QNX Realtime Platform version for SDL YUV video overlays */ | |
29 | |
30 #include <stdlib.h> | |
31 #include <string.h> | |
32 #ifndef bool | |
33 #define bool char | |
34 #define TRUE 1 | |
35 #define FALSE 0 | |
36 #endif | |
37 #include <errno.h> | |
38 | |
39 #include <Ph.h> | |
40 #include <Pt.h> | |
41 | |
42 #include "SDL_error.h" | |
43 #include "SDL_video.h" | |
44 #include "SDL_phyuv_c.h" | |
45 #include "SDL_yuvfuncs.h" | |
46 | |
47 #if 0 //just for reference | |
48 /* YUV data formats FourCC Layout H sample (YUV) V sample (YUV) BPP */ | |
49 #define Pg_VIDEO_FORMAT_IYU1 0x31555949 /* U2Y2Y2V2Y2Y2 144 111 12 */ | |
50 #define Pg_VIDEO_FORMAT_IYU2 0x32555949 /* U4Y4V4U4Y4V4 111 111 24 */ | |
51 #define Pg_VIDEO_FORMAT_UYVY 0x59565955 /* U8Y8V8Y8 122 111 16 */ | |
52 #define Pg_VIDEO_FORMAT_YUY2 0x32595559 /* Y8U8Y8V8 122 111 16 */ | |
53 #define Pg_VIDEO_FORMAT_YVYU 0x55595659 /* Y8V8Y8U8 122 111 16 */ | |
54 #define Pg_VIDEO_FORMAT_V422 0x56343232 /* V8Y8U8Y8 122 111 16 */ | |
55 #define Pg_VIDEO_FORMAT_CLJR 0x524a4c43 /* V6U6Y5Y5Y5Y5 133 111 8 */ | |
56 #define Pg_VIDEO_FORMAT_YVU9 0x39555659 /* Planar YVU 144 144 9 */ | |
57 #define Pg_VIDEO_FORMAT_YV12 0x32315659 /* Planar YUV 122 122 12 */ | |
58 | |
59 /* There seems to be no FourCC that matches this */ | |
60 #define Pg_VIDEO_FORMAT_YUV420 0x00000100 /* Planar YUV 122 111 16 */ | |
61 | |
62 /* These formats are the same as YV12, except the U and V planes do not have to contiguously follow the Y plane */ | |
63 /* but they're all the same to us, since we always have 3 plane pointers */ | |
64 #define Pg_VIDEO_FORMAT_CLPL Pg_VIDEO_FORMAT_YV12 /* Cirrus Logic Planar format */ | |
65 #define Pg_VIDEO_FORMAT_VBPL Pg_VIDEO_FORMAT_YV12 /* VooDoo Banshee planar format */ | |
66 | |
67 #define SDL_YV12_OVERLAY 0x32315659 /* Planar mode: Y + V + U */ | |
68 #define SDL_IYUV_OVERLAY 0x56555949 /* Planar mode: Y + U + V */ | |
69 #define SDL_YUY2_OVERLAY 0x32595559 /* Packed mode: Y0+U0+Y1+V0 */ | |
70 #define SDL_UYVY_OVERLAY 0x59565955 /* Packed mode: U0+Y0+V0+Y1 */ | |
71 #define SDL_YVYU_OVERLAY 0x55595659 /* Packed mode: Y0+V0+Y1+U0 */ | |
72 | |
73 #endif | |
74 | |
75 | |
76 #define OVERLAY_STATE_UNINIT 0 | |
77 #define OVERLAY_STATE_ACTIVE 1 | |
78 | |
79 /* The functions used to manipulate software video overlays */ | |
80 static struct private_yuvhwfuncs ph_yuvfuncs = { | |
81 ph_LockYUVOverlay, | |
82 ph_UnlockYUVOverlay, | |
83 ph_DisplayYUVOverlay, | |
84 ph_FreeYUVOverlay | |
85 }; | |
86 | |
87 | |
88 typedef struct { | |
89 int id; | |
90 int width, height; | |
91 int data_size; /* bytes */ | |
92 int num_planes; | |
93 int *pitches; /* bytes */ | |
94 int *offsets; /* bytes */ | |
95 char *data; | |
96 void *obdata; | |
97 } XvImage; | |
98 | |
99 | |
100 struct private_yuvhwdata { | |
101 XvImage *image; | |
102 FRAMEDATA *CurrentFrameData; | |
103 FRAMEDATA *FrameData0; | |
104 FRAMEDATA *FrameData1; | |
105 PgScalerProps_t props; | |
370
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
106 PgScalerCaps_t caps; |
0 | 107 PgVideoChannel_t *channel; |
108 SDL_Rect CurrentWindow; | |
109 long format; | |
110 int screen_width; | |
111 int screen_height ; | |
112 int screen_bpp ; //2 | |
113 bool planar; | |
114 bool scaler_on ; | |
115 int current; | |
116 long YStride; | |
117 long VStride; | |
118 long UStride; | |
119 long chromakey; | |
120 unsigned long State; | |
121 long flags; | |
122 }; | |
123 | |
124 extern PgVideoChannel_t * PgCreateVideoChannel(unsigned type, unsigned flags); | |
125 extern int PgGetScalerCapabilities( PgVideoChannel_t *channel, int format_index, PgScalerCaps_t *vcaps ); | |
126 extern int PgConfigScalerChannel(PgVideoChannel_t *channel, PgScalerProps_t *props); | |
127 extern void PgDestroyVideoChannel(PgVideoChannel_t *channel); | |
128 extern PgColor_t PgGetOverlayChromaColor(void); | |
129 | |
130 void | |
131 grab_ptrs2(PgVideoChannel_t *channel, FRAMEDATA *Frame0, FRAMEDATA *Frame1 ) | |
132 { | |
133 | |
134 /* Buffers have moved; re-obtain the pointers */ | |
135 Frame0->Y = (unsigned char *)PdGetOffscreenContextPtr(channel->yplane1); | |
136 Frame1->Y = (unsigned char *)PdGetOffscreenContextPtr(channel->yplane2); | |
137 Frame0->U = (unsigned char *)PdGetOffscreenContextPtr(channel->uplane1); | |
138 Frame1->U = (unsigned char *)PdGetOffscreenContextPtr(channel->uplane2); | |
139 Frame0->V = (unsigned char *)PdGetOffscreenContextPtr(channel->vplane1); | |
140 Frame1->V = (unsigned char *)PdGetOffscreenContextPtr(channel->vplane2); | |
141 | |
142 } | |
143 | |
370
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
144 SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) |
0 | 145 { |
146 SDL_Overlay *overlay; | |
147 struct private_yuvhwdata *hwdata; | |
148 int xv_port; | |
149 int rtncode; | |
150 // PhRect_t rect; | |
151 // PhSysInfo_t info; | |
152 // PhRegion_t region; | |
153 // short x, y; | |
154 PtArg_t argt; | |
155 int i =0; | |
156 // bool bCont = TRUE; | |
157 int Priority[20]; | |
158 int Type[20]; | |
159 int entries, select, highest; | |
160 | |
161 PhDCSetCurrent(0); //Need to set draw context to window esp. if we we in Offscreeen mode | |
162 | |
163 /* Create the overlay structure */ | |
370
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
164 overlay = (SDL_Overlay *)malloc(sizeof(SDL_Overlay)); |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
165 memset(overlay, 0x00, sizeof(SDL_Overlay)); |
0 | 166 if ( overlay == NULL ) { |
167 SDL_OutOfMemory(); | |
168 return(NULL); | |
169 } | |
170 memset(overlay, 0, (sizeof *overlay)); | |
171 | |
172 /* Fill in the basic members */ | |
173 overlay->format = format; | |
174 overlay->w = width; | |
175 overlay->h = height; | |
176 | |
177 /* Set up the YUV surface function structure */ | |
178 overlay->hwfuncs = &ph_yuvfuncs; | |
179 | |
180 /* Create the pixel data and lookup tables */ | |
370
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
181 hwdata = (struct private_yuvhwdata *)malloc(sizeof(struct private_yuvhwdata)); |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
182 memset(hwdata, 0x00, sizeof(struct private_yuvhwdata)); |
0 | 183 overlay->hwdata = hwdata; |
184 if ( hwdata == NULL ) { | |
185 SDL_OutOfMemory(); | |
186 SDL_FreeYUVOverlay(overlay); | |
187 return(NULL); | |
188 } | |
189 | |
370
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
190 if (overlay->hwdata->channel == NULL) |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
191 { |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
192 if ((overlay->hwdata->channel = PgCreateVideoChannel(Pg_VIDEO_CHANNEL_SCALER,0)) == NULL) |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
193 { |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
194 SDL_SetError("ph_CreateYUVOverlay(): Create channel failed: %s\n", strerror( errno )); |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
195 free(overlay->hwdata); |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
196 free(overlay); |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
197 return (NULL); |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
198 } |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
199 } |
0 | 200 |
370
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
201 overlay->hwdata->CurrentWindow.x = 0; |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
202 overlay->hwdata->CurrentWindow.y = 0; |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
203 overlay->hwdata->CurrentWindow.w = 320; |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
204 overlay->hwdata->CurrentWindow.h = 240; |
0 | 205 |
370
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
206 overlay->hwdata->State = OVERLAY_STATE_UNINIT; |
0 | 207 |
370
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
208 overlay->hwdata->screen_bpp = 2; |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
209 overlay->hwdata->scaler_on = FALSE; |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
210 overlay->hwdata->screen_width = 1024; |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
211 overlay->hwdata->screen_height = 768; |
0 | 212 |
380
bce7171e7a85
Date: Wed, 22 May 2002 22:30:58 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
370
diff
changeset
|
213 overlay->hwdata->FrameData0 = (FRAMEDATA *) malloc((size_t)(sizeof(FRAMEDATA))); |
bce7171e7a85
Date: Wed, 22 May 2002 22:30:58 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
370
diff
changeset
|
214 overlay->hwdata->FrameData1 = (FRAMEDATA *) malloc((size_t)(sizeof(FRAMEDATA))); |
bce7171e7a85
Date: Wed, 22 May 2002 22:30:58 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
370
diff
changeset
|
215 memset(overlay->hwdata->FrameData0, 0x00, (size_t)(sizeof(FRAMEDATA))); |
bce7171e7a85
Date: Wed, 22 May 2002 22:30:58 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
370
diff
changeset
|
216 memset(overlay->hwdata->FrameData1, 0x00, (size_t)(sizeof(FRAMEDATA))); |
0 | 217 |
370
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
218 overlay->hwdata->caps.size = sizeof(overlay->hwdata->caps); |
0 | 219 |
220 //Note you really don't need to do this for SDL as you are given a format, but this is a good example | |
221 | |
370
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
222 xv_port = -1; |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
223 i=0; |
ba72f259bc88
Date: Sat, 18 May 2002 17:40:53 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
224 |
0 | 225 while(PgGetScalerCapabilities(overlay->hwdata->channel, i++, &(overlay->hwdata->caps)) == 0) |
226 { | |
227 if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_YV12) //in SDL | |
228 { | |
229 | |
230 Priority[i-1] = 0; | |
231 Type[i-1] = Pg_VIDEO_FORMAT_YV12; | |
232 if(format == Pg_VIDEO_FORMAT_YV12) | |
233 { | |
234 overlay->hwdata->props.format = Pg_VIDEO_FORMAT_YV12; | |
235 xv_port = 1; //supported | |
236 Priority[i-1] = 100; //force selected | |
237 } | |
238 | |
239 } | |
240 else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_YVU9) //in SDL | |
241 { | |
242 | |
243 Priority[i-1] = 0; | |
244 Type[i-1] = Pg_VIDEO_FORMAT_YVU9; | |
245 if(format == Pg_VIDEO_FORMAT_YVU9) | |
246 { | |
247 overlay->hwdata->props.format = Pg_VIDEO_FORMAT_YVU9; | |
248 xv_port = 1; //supported | |
249 Priority[i-1] = 100; //force selected | |
250 } | |
251 | |
252 } | |
253 #if 0 //this part of SDL is YUV specific | |
254 else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_RGB555) | |
255 { | |
256 | |
257 Priority[i-1] = 3; | |
258 Type[i-1] = Pg_VIDEO_FORMAT_RGB555; | |
259 } | |
260 else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_RGB565) | |
261 { | |
262 | |
263 Priority[i-1] = 2; | |
264 Type[i-1] = Pg_VIDEO_FORMAT_RGB565; | |
265 } | |
266 else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_RGB8888) | |
267 { | |
268 | |
269 Priority[i-1] = 1; | |
270 Type[i-1] = Pg_VIDEO_FORMAT_RGB8888; | |
271 } | |
272 #endif | |
273 else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_IYU1) | |
274 { | |
275 | |
276 Priority[i-1] = 0; | |
277 Type[i-1] = Pg_VIDEO_FORMAT_IYU1; | |
278 | |
279 } | |
280 else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_IYU2) | |
281 { | |
282 | |
283 Priority[i-1] = 0; | |
284 Type[i-1] = Pg_VIDEO_FORMAT_IYU2; | |
285 } | |
286 | |
287 else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_UYVY) //in SDL | |
288 { | |
289 | |
290 Priority[i-1] = 7; | |
291 Type[i-1] = Pg_VIDEO_FORMAT_UYVY; | |
292 if(format == Pg_VIDEO_FORMAT_UYVY) | |
293 { | |
294 overlay->hwdata->props.format = Pg_VIDEO_FORMAT_UYVY; | |
295 xv_port = 1; //supported | |
296 Priority[i-1] = 100; //force selected | |
297 } | |
298 | |
299 } | |
300 else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_YUY2) //in SDL | |
301 { | |
302 | |
303 Priority[i-1] = 8; | |
304 Type[i-1] = Pg_VIDEO_FORMAT_YUY2; | |
305 if(format == Pg_VIDEO_FORMAT_YUY2) | |
306 { | |
307 overlay->hwdata->props.format = Pg_VIDEO_FORMAT_YUY2; | |
308 xv_port = 1; //supported | |
309 Priority[i-1] = 100; //force selected | |
310 } | |
311 | |
312 } | |
313 else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_YVYU) //in SDL | |
314 { | |
315 | |
316 Priority[i-1] = 4; | |
317 Type[i-1] = Pg_VIDEO_FORMAT_YVYU; | |
318 | |
319 if(format == Pg_VIDEO_FORMAT_YVYU) | |
320 { | |
321 overlay->hwdata->props.format = Pg_VIDEO_FORMAT_YVYU; | |
322 xv_port = 1; //supported | |
323 Priority[i-1] = 100; //force selected | |
324 | |
325 } | |
326 | |
327 } | |
328 else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_V422) | |
329 { | |
330 | |
331 Priority[i-1] = 5; | |
332 Type[i-1] = Pg_VIDEO_FORMAT_V422; | |
333 } | |
334 else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_CLJR) | |
335 { | |
336 | |
337 Priority[i-1] = 6; | |
338 Type[i-1] = Pg_VIDEO_FORMAT_CLJR; | |
339 } | |
340 else | |
341 { | |
342 | |
343 Priority[i-1] = 0; | |
344 } | |
345 | |
346 overlay->hwdata->caps.size = sizeof(overlay->hwdata->caps); | |
347 } | |
348 | |
349 if ( xv_port == -1 ) | |
350 { | |
351 SDL_SetError("No available video ports for requested format"); | |
352 return(NULL); | |
353 } | |
354 | |
355 //Pick the highest priority format | |
356 entries = i -2; | |
357 highest = Priority[0]; //make first entry top at begining | |
358 select = 0; | |
359 | |
360 for (i = 1; i < entries; i++) | |
361 { | |
362 | |
363 | |
364 if(Priority[i] > highest) | |
365 { | |
366 highest = Priority[i]; | |
367 select = i; | |
368 } | |
369 } | |
370 | |
371 | |
372 | |
373 overlay->hwdata->caps.size = sizeof (overlay->hwdata->caps ); | |
374 PgGetScalerCapabilities(overlay->hwdata->channel, select, &(overlay->hwdata->caps)); | |
375 overlay->hwdata->props.format = overlay->hwdata->caps.format ; | |
376 | |
377 overlay->hwdata->format = overlay->hwdata->props.format; //to make easier for apps to use | |
378 | |
379 | |
380 overlay->hwdata->props.size = sizeof (overlay->hwdata->props); | |
381 overlay->hwdata->props.src_dim.w = width; | |
382 overlay->hwdata->props.src_dim.h = height; | |
383 | |
384 overlay->hwdata->chromakey = PgGetOverlayChromaColor(); | |
385 | |
386 // Set chromakey in video widget so we can see overlay data | |
387 /* I don't know where the container widget is!!!, I guess it is in hidden->window*/ | |
388 | |
389 PtEnter(0); | |
390 PtSetArg( &argt, Pt_ARG_FILL_COLOR, overlay->hwdata->chromakey, 0 ); | |
391 PtSetResources( window, 1, &argt ); | |
392 PtLeave(0); | |
393 | |
394 | |
395 fflush( stderr ); | |
396 | |
397 overlay->hwdata->props.viewport.ul.x = overlay->hwdata->CurrentWindow.x; | |
398 overlay->hwdata->props.viewport.ul.y = overlay->hwdata->CurrentWindow.y; | |
399 //Next line MIGHT have x and y reversed!!!!!!!!!!!! | |
400 overlay->hwdata->props.viewport.lr.x = overlay->hwdata->CurrentWindow.x +overlay->hwdata->CurrentWindow.w; | |
401 overlay->hwdata->props.viewport.lr.y = overlay->hwdata->CurrentWindow.y + overlay->hwdata->CurrentWindow.h; | |
402 | |
403 | |
404 | |
405 overlay->hwdata->props.flags = | |
406 ~Pg_SCALER_PROP_SCALER_ENABLE | Pg_SCALER_PROP_DOUBLE_BUFFER ; | |
407 | |
408 if (overlay->hwdata->chromakey) { | |
409 overlay->hwdata->props.flags |= Pg_SCALER_PROP_CHROMA_ENABLE; | |
410 overlay->hwdata->props.color_key = overlay->hwdata->chromakey; | |
411 overlay->hwdata->props.color_key_mask = 0xffffff; | |
412 } | |
413 else | |
414 { | |
415 overlay->hwdata->props.flags &= ~Pg_SCALER_PROP_CHROMA_ENABLE; | |
416 } | |
417 | |
418 | |
419 overlay->hwdata->scaler_on = FALSE; | |
420 | |
421 | |
422 | |
423 rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props)); | |
424 switch(rtncode) | |
425 { | |
426 case -1: | |
427 SDL_SetError("PgConfigScalerChannel failed\n"); | |
428 SDL_FreeYUVOverlay(overlay); | |
429 return(NULL); | |
430 break; | |
431 case 1: | |
432 grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1); | |
433 break; | |
434 case 0: | |
435 default: | |
436 break; | |
437 } | |
438 | |
439 | |
440 grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1); | |
441 | |
442 if(overlay->hwdata->channel->yplane1 != NULL) | |
443 overlay->hwdata->YStride = overlay->hwdata->channel->yplane1->pitch; | |
444 if(overlay->hwdata->channel->uplane1 != NULL) | |
445 overlay->hwdata->UStride = overlay->hwdata->channel->uplane1->pitch; | |
446 if(overlay->hwdata->channel->vplane1 != NULL) | |
447 overlay->hwdata->VStride = overlay->hwdata->channel->vplane1->pitch; | |
448 | |
449 | |
450 overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel); | |
451 | |
452 | |
453 | |
454 if (overlay->hwdata->current == -1) | |
455 { | |
456 SDL_SetError("PgNextFrame failed, bailing out\n"); | |
457 SDL_FreeYUVOverlay(overlay); | |
458 return(NULL); | |
459 } | |
460 | |
461 //set current frame for double buffering | |
462 if(overlay->hwdata->current == 0) | |
463 { | |
464 overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0; | |
465 } | |
466 else | |
467 { | |
468 overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1; | |
469 } | |
470 | |
471 overlay->hwdata->State = OVERLAY_STATE_ACTIVE; | |
472 | |
473 | |
474 /* We're all done.. */ | |
475 return(overlay); | |
476 } | |
477 | |
478 int ph_LockYUVOverlay(_THIS, SDL_Overlay *overlay) | |
479 { | |
480 //int rtncode; | |
481 | |
482 if(overlay == NULL) | |
483 return 0; | |
484 | |
485 //set current frame for double buffering | |
486 if(overlay->hwdata->current == 0) | |
487 { | |
488 overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0; | |
489 } | |
490 else | |
491 { | |
492 overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1; | |
493 } | |
494 | |
495 //Lock gets the pointer and passes it to the app. The app writes all yuv data into overlay->pixels | |
496 //Note this is defined as Uint8 **pixels; /* Read-write */ | |
497 overlay->pixels = &overlay->hwdata->CurrentFrameData->Y; | |
380
bce7171e7a85
Date: Wed, 22 May 2002 22:30:58 +0300
Sam Lantinga <slouken@libsdl.org>
parents:
370
diff
changeset
|
498 overlay->pitches = (Uint16*) &(overlay->hwdata->YStride); |
0 | 499 |
500 return(0); | |
501 } | |
502 | |
503 void ph_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay) | |
504 { | |
505 int rtncode; | |
506 | |
507 if(overlay == NULL) | |
508 return ; | |
509 | |
510 if(overlay->hwdata->scaler_on == FALSE) | |
511 { | |
512 | |
513 | |
514 overlay->hwdata->props.flags |= Pg_SCALER_PROP_SCALER_ENABLE; | |
515 rtncode =PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props)); | |
516 switch(rtncode) | |
517 { | |
518 case -1: | |
519 SDL_SetError("PgConfigScalerChannel failed\n"); | |
520 SDL_FreeYUVOverlay(overlay); | |
521 break; | |
522 case 1: | |
523 grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1); | |
524 overlay->hwdata->scaler_on = TRUE; | |
525 break; | |
526 case 0: | |
527 default: | |
528 overlay->hwdata->scaler_on = TRUE; | |
529 break; | |
530 } | |
531 //This would be the best place to draw chromakey but we do not have a SDL_Surface in the args | |
532 //This means we might see a chromakey flicker at startup | |
533 } | |
534 overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel); | |
535 | |
536 | |
537 if (overlay->hwdata->current == -1) { | |
538 SDL_SetError("PgNextVideoFrame failed\n"); | |
539 SDL_FreeYUVOverlay(overlay); | |
540 return; | |
541 } | |
542 | |
543 overlay->pixels = NULL; | |
544 } | |
545 | |
546 int ph_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) | |
547 { | |
548 int rtncode; | |
549 | |
550 if(overlay == NULL) | |
551 return 0; | |
552 | |
553 | |
554 /*SDL_Rect CurrentWindow*/ | |
555 //If CurrentWindow has change, move the viewport | |
556 if((overlay->hwdata->CurrentWindow.x != dstrect->x) || | |
557 (overlay->hwdata->CurrentWindow.y != dstrect->y) || | |
558 (overlay->hwdata->CurrentWindow.w != dstrect->w) || | |
559 (overlay->hwdata->CurrentWindow.h != dstrect->h)) | |
560 { | |
561 if(overlay->hwdata->State == OVERLAY_STATE_UNINIT) | |
562 return -1; | |
563 | |
564 overlay->hwdata->CurrentWindow.x = dstrect->x; | |
565 overlay->hwdata->CurrentWindow.y = dstrect->y; | |
566 overlay->hwdata->CurrentWindow.w = dstrect->w; | |
567 overlay->hwdata->CurrentWindow.h = dstrect->h; | |
568 | |
569 overlay->hwdata->props.viewport.ul.x = overlay->hwdata->CurrentWindow.x; | |
570 overlay->hwdata->props.viewport.ul.y = overlay->hwdata->CurrentWindow.y; | |
571 //Next line MIGHT have x and y reversed!!!!!!!!!!!! | |
572 overlay->hwdata->props.viewport.lr.x = overlay->hwdata->CurrentWindow.x +overlay->hwdata->CurrentWindow.w; | |
573 overlay->hwdata->props.viewport.lr.y = overlay->hwdata->CurrentWindow.y + overlay->hwdata->CurrentWindow.h; | |
574 | |
575 | |
576 rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props)); | |
577 | |
578 switch(rtncode) | |
579 { | |
580 case -1: | |
581 SDL_SetError("PgConfigScalerChannel failed\n"); | |
582 SDL_FreeYUVOverlay(overlay); | |
583 return(0); | |
584 break; | |
585 case 1: | |
586 grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1); | |
587 break; | |
588 case 0: | |
589 default: | |
590 break; | |
591 } | |
592 } | |
593 | |
594 | |
595 //JB the X11 file did this. We do this in SDL_unlock, we need to confirm that lock and unlock are called for each frame! | |
596 // XvShmPutImage(GFX_Display, hwdata->port, SDL_Window, SDL_GC, | |
597 // hwdata->image, 0, 0, overlay->w, overlay->h, | |
598 // dstrect->x, dstrect->y, dstrect->w, dstrect->h, False); | |
599 /* This is what this call is | |
600 int XvShmPutImage ( | |
601 Display *dpy, | |
602 XvPortID port, | |
603 Drawable d, | |
604 GC gc, | |
605 XvImage *image, | |
606 int src_x, | |
607 int src_y, | |
608 unsigned int src_w, | |
609 unsigned int src_h, | |
610 int dest_x, | |
611 int dest_y, | |
612 unsigned int dest_w, | |
613 unsigned int dest_h, | |
614 Bool send_event | |
615 ) | |
616 */ | |
617 | |
618 return(0); | |
619 } | |
620 | |
621 void ph_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) | |
622 { | |
623 //struct private_yuvhwdata *hwdata; | |
624 | |
625 if(overlay == NULL) | |
626 return; | |
627 | |
628 if(overlay->hwdata == NULL) | |
629 return; | |
630 | |
631 overlay->hwdata->State = OVERLAY_STATE_UNINIT; | |
632 | |
633 if( overlay->hwdata->channel == NULL ) | |
634 { | |
635 return; | |
636 } | |
637 | |
638 PgDestroyVideoChannel(overlay->hwdata->channel); | |
639 | |
640 overlay->hwdata->channel = NULL; | |
641 overlay->hwdata->CurrentFrameData = NULL; | |
642 | |
643 free(overlay->hwdata->FrameData0); | |
644 free(overlay->hwdata->FrameData1); | |
645 overlay->hwdata->FrameData0 = NULL; | |
646 overlay->hwdata->FrameData1 = NULL; | |
647 free(overlay->hwdata); | |
648 | |
649 } |