comparison src/video/photon/SDL_phyuv.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 bce7171e7a85
children 8bedd6d61642
comparison
equal deleted inserted replaced
570:04d6411da49d 571:8e3ce997621c
27 27
28 /* This is the QNX Realtime Platform version for SDL YUV video overlays */ 28 /* This is the QNX Realtime Platform version for SDL YUV video overlays */
29 29
30 #include <stdlib.h> 30 #include <stdlib.h>
31 #include <string.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> 32 #include <errno.h>
38 33
39 #include <Ph.h> 34 #include <Ph.h>
40 #include <Pt.h> 35 #include <Pt.h>
41 36
42 #include "SDL_error.h" 37 #include "SDL_error.h"
43 #include "SDL_video.h" 38 #include "SDL_video.h"
44 #include "SDL_phyuv_c.h" 39 #include "SDL_phyuv_c.h"
45 #include "SDL_yuvfuncs.h" 40 #include "SDL_yuvfuncs.h"
46 41
47 #if 0 //just for reference 42 #define OVERLAY_STATE_UNINIT 0
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 43 #define OVERLAY_STATE_ACTIVE 1
78 44
79 /* The functions used to manipulate software video overlays */ 45 /* The functions used to manipulate software video overlays */
80 static struct private_yuvhwfuncs ph_yuvfuncs = { 46 static struct private_yuvhwfuncs ph_yuvfuncs = {
81 ph_LockYUVOverlay, 47 ph_LockYUVOverlay,
82 ph_UnlockYUVOverlay, 48 ph_UnlockYUVOverlay,
83 ph_DisplayYUVOverlay, 49 ph_DisplayYUVOverlay,
84 ph_FreeYUVOverlay 50 ph_FreeYUVOverlay
85 }; 51 };
86 52
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 { 53 struct private_yuvhwdata {
101 XvImage *image; 54 FRAMEDATA* CurrentFrameData;
102 FRAMEDATA *CurrentFrameData; 55 FRAMEDATA* FrameData0;
103 FRAMEDATA *FrameData0; 56 FRAMEDATA* FrameData1;
104 FRAMEDATA *FrameData1; 57 PgScalerProps_t props;
105 PgScalerProps_t props; 58 PgScalerCaps_t caps;
106 PgScalerCaps_t caps; 59 PgVideoChannel_t* channel;
107 PgVideoChannel_t *channel; 60 PhArea_t CurrentWindow;
108 SDL_Rect CurrentWindow; 61 long format;
109 long format; 62 int planar;
110 int screen_width; 63 int scaler_on;
111 int screen_height ; 64 int current;
112 int screen_bpp ; //2 65 long YStride;
113 bool planar; 66 long VStride;
114 bool scaler_on ; 67 long UStride;
115 int current; 68 int ischromakey;
116 long YStride; 69 long chromakey;
117 long VStride; 70 unsigned long State;
118 long UStride; 71 long flags;
119 long chromakey; 72 int locked;
120 unsigned long State;
121 long flags;
122 }; 73 };
123 74
124 extern PgVideoChannel_t * PgCreateVideoChannel(unsigned type, unsigned flags); 75 int grab_ptrs2(PgVideoChannel_t* channel, FRAMEDATA* Frame0, FRAMEDATA* Frame1 )
125 extern int PgGetScalerCapabilities( PgVideoChannel_t *channel, int format_index, PgScalerCaps_t *vcaps ); 76 {
126 extern int PgConfigScalerChannel(PgVideoChannel_t *channel, PgScalerProps_t *props); 77 int planes = 0;
127 extern void PgDestroyVideoChannel(PgVideoChannel_t *channel); 78
128 extern PgColor_t PgGetOverlayChromaColor(void); 79 /* Buffers have moved; re-obtain the pointers */
129 80 Frame0->Y = (unsigned char *)PdGetOffscreenContextPtr(channel->yplane1);
130 void 81 Frame1->Y = (unsigned char *)PdGetOffscreenContextPtr(channel->yplane2);
131 grab_ptrs2(PgVideoChannel_t *channel, FRAMEDATA *Frame0, FRAMEDATA *Frame1 ) 82 Frame0->U = (unsigned char *)PdGetOffscreenContextPtr(channel->uplane1);
132 { 83 Frame1->U = (unsigned char *)PdGetOffscreenContextPtr(channel->uplane2);
133 84 Frame0->V = (unsigned char *)PdGetOffscreenContextPtr(channel->vplane1);
134 /* Buffers have moved; re-obtain the pointers */ 85 Frame1->V = (unsigned char *)PdGetOffscreenContextPtr(channel->vplane2);
135 Frame0->Y = (unsigned char *)PdGetOffscreenContextPtr(channel->yplane1); 86
136 Frame1->Y = (unsigned char *)PdGetOffscreenContextPtr(channel->yplane2); 87 if (Frame0->Y)
137 Frame0->U = (unsigned char *)PdGetOffscreenContextPtr(channel->uplane1); 88 planes++;
138 Frame1->U = (unsigned char *)PdGetOffscreenContextPtr(channel->uplane2); 89
139 Frame0->V = (unsigned char *)PdGetOffscreenContextPtr(channel->vplane1); 90 if (Frame0->U)
140 Frame1->V = (unsigned char *)PdGetOffscreenContextPtr(channel->vplane2); 91 planes++;
141 92
93 if (Frame0->V)
94 planes++;
95
96 return planes;
142 } 97 }
143 98
144 SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) 99 SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
145 { 100 {
146 SDL_Overlay *overlay; 101 SDL_Overlay *overlay;
147 struct private_yuvhwdata *hwdata; 102 struct private_yuvhwdata *hwdata;
148 int xv_port; 103 int xv_port;
149 int rtncode; 104 int rtncode;
150 // PhRect_t rect; 105 int planes;
151 // PhSysInfo_t info; 106 int i=0;
152 // PhRegion_t region; 107 PhPoint_t pos;
153 // short x, y; 108
154 PtArg_t argt; 109 /* Create the overlay structure */
155 int i =0; 110 overlay = calloc(1, sizeof(SDL_Overlay));
156 // bool bCont = TRUE; 111
157 int Priority[20]; 112 if (overlay == NULL) {
158 int Type[20]; 113 SDL_OutOfMemory();
159 int entries, select, highest; 114 return (NULL);
160 115 }
161 PhDCSetCurrent(0); //Need to set draw context to window esp. if we we in Offscreeen mode 116
162 117 /* Fill in the basic members */
163 /* Create the overlay structure */ 118 overlay->format = format;
164 overlay = (SDL_Overlay *)malloc(sizeof(SDL_Overlay)); 119 overlay->w = width;
165 memset(overlay, 0x00, sizeof(SDL_Overlay)); 120 overlay->h = height;
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 121
177 /* Set up the YUV surface function structure */ 122 /* Set up the YUV surface function structure */
178 overlay->hwfuncs = &ph_yuvfuncs; 123 overlay->hwfuncs = &ph_yuvfuncs;
179 124
180 /* Create the pixel data and lookup tables */ 125 /* Create the pixel data and lookup tables */
181 hwdata = (struct private_yuvhwdata *)malloc(sizeof(struct private_yuvhwdata)); 126 hwdata = calloc(1, sizeof(struct private_yuvhwdata));
182 memset(hwdata, 0x00, sizeof(struct private_yuvhwdata)); 127
183 overlay->hwdata = hwdata; 128 overlay->hwdata = hwdata;
184 if ( hwdata == NULL ) { 129 if (hwdata == NULL) {
185 SDL_OutOfMemory(); 130 SDL_OutOfMemory();
186 SDL_FreeYUVOverlay(overlay); 131 SDL_FreeYUVOverlay(overlay);
187 return(NULL); 132 return(NULL);
188 } 133 }
189 134
135 PhDCSetCurrent(0);
190 if (overlay->hwdata->channel == NULL) 136 if (overlay->hwdata->channel == NULL)
191 { 137 {
192 if ((overlay->hwdata->channel = PgCreateVideoChannel(Pg_VIDEO_CHANNEL_SCALER,0)) == NULL) 138 if ((overlay->hwdata->channel = PgCreateVideoChannel(Pg_VIDEO_CHANNEL_SCALER,0)) == NULL)
193 { 139 {
194 SDL_SetError("ph_CreateYUVOverlay(): Create channel failed: %s\n", strerror( errno )); 140 SDL_SetError("ph_CreateYUVOverlay(): Create channel failed: %s\n", strerror(errno));
195 free(overlay->hwdata); 141 SDL_FreeYUVOverlay(overlay);
196 free(overlay); 142
197 return (NULL); 143 return(NULL);
198 } 144
199 } 145 }
200 146 }
201 overlay->hwdata->CurrentWindow.x = 0; 147
202 overlay->hwdata->CurrentWindow.y = 0; 148 PtGetAbsPosition(window, &pos.x, &pos.y);
203 overlay->hwdata->CurrentWindow.w = 320; 149 overlay->hwdata->CurrentWindow.pos.x = pos.x;
204 overlay->hwdata->CurrentWindow.h = 240; 150 overlay->hwdata->CurrentWindow.pos.y = pos.y;
205 151 overlay->hwdata->CurrentWindow.size.w = width;
152 overlay->hwdata->CurrentWindow.size.h = height;
206 overlay->hwdata->State = OVERLAY_STATE_UNINIT; 153 overlay->hwdata->State = OVERLAY_STATE_UNINIT;
207 154 overlay->hwdata->FrameData0 = (FRAMEDATA *) calloc(1, sizeof(FRAMEDATA));
208 overlay->hwdata->screen_bpp = 2; 155 overlay->hwdata->FrameData1 = (FRAMEDATA *) calloc(1, sizeof(FRAMEDATA));
209 overlay->hwdata->scaler_on = FALSE;
210 overlay->hwdata->screen_width = 1024;
211 overlay->hwdata->screen_height = 768;
212
213 overlay->hwdata->FrameData0 = (FRAMEDATA *) malloc((size_t)(sizeof(FRAMEDATA)));
214 overlay->hwdata->FrameData1 = (FRAMEDATA *) malloc((size_t)(sizeof(FRAMEDATA)));
215 memset(overlay->hwdata->FrameData0, 0x00, (size_t)(sizeof(FRAMEDATA)));
216 memset(overlay->hwdata->FrameData1, 0x00, (size_t)(sizeof(FRAMEDATA)));
217
218 overlay->hwdata->caps.size = sizeof(overlay->hwdata->caps);
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 156
222 xv_port = -1; 157 xv_port = -1;
223 i=0; 158 i=0;
224 159
225 while(PgGetScalerCapabilities(overlay->hwdata->channel, i++, &(overlay->hwdata->caps)) == 0) 160 overlay->hwdata->ischromakey=0;
226 { 161
227 if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_YV12) //in SDL 162 do {
228 { 163 memset(&overlay->hwdata->caps, 0x00, sizeof(PgScalerCaps_t));
229 164 overlay->hwdata->caps.size = sizeof(PgScalerCaps_t);
230 Priority[i-1] = 0; 165 rtncode = PgGetScalerCapabilities(overlay->hwdata->channel, i, &overlay->hwdata->caps);
231 Type[i-1] = Pg_VIDEO_FORMAT_YV12; 166 if (rtncode==0)
232 if(format == Pg_VIDEO_FORMAT_YV12) 167 {
233 { 168 if (overlay->hwdata->caps.format==format)
234 overlay->hwdata->props.format = Pg_VIDEO_FORMAT_YV12; 169 {
235 xv_port = 1; //supported 170 if ((overlay->hwdata->caps.flags & Pg_SCALER_CAP_DST_CHROMA_KEY) == Pg_SCALER_CAP_DST_CHROMA_KEY)
236 Priority[i-1] = 100; //force selected 171 {
237 } 172 overlay->hwdata->ischromakey=1;
238 173 }
239 } 174 xv_port=1;
240 else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_YVU9) //in SDL 175 break;
241 { 176 }
242 177 }
243 Priority[i-1] = 0; 178 else
244 Type[i-1] = Pg_VIDEO_FORMAT_YVU9; 179 {
245 if(format == Pg_VIDEO_FORMAT_YVU9) 180 break;
246 { 181 }
247 overlay->hwdata->props.format = Pg_VIDEO_FORMAT_YVU9; 182 i++;
248 xv_port = 1; //supported 183 } while(1);
249 Priority[i-1] = 100; //force selected 184
250 } 185
251 186 if (xv_port == -1)
252 } 187 {
253 #if 0 //this part of SDL is YUV specific 188 SDL_SetError("No available video ports for requested format\n");
254 else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_RGB555) 189 SDL_FreeYUVOverlay(overlay);
255 { 190 return(NULL);
256 191 }
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 192
355 //Pick the highest priority format 193 overlay->hwdata->format = format;
356 entries = i -2; 194 overlay->hwdata->props.format = format;
357 highest = Priority[0]; //make first entry top at begining 195 overlay->hwdata->props.size = sizeof(PgScalerProps_t);
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; 196 overlay->hwdata->props.src_dim.w = width;
382 overlay->hwdata->props.src_dim.h = height; 197 overlay->hwdata->props.src_dim.h = height;
383 198
384 overlay->hwdata->chromakey = PgGetOverlayChromaColor(); 199 /* Don't use chromakey for now, blitting a surface will cover the window,
385 200 * and therefore the chroma. */
386 // Set chromakey in video widget so we can see overlay data 201 overlay->hwdata->chromakey = 0;
387 /* I don't know where the container widget is!!!, I guess it is in hidden->window*/ 202 PtSetResource(window, Pt_ARG_FILL_COLOR, overlay->hwdata->chromakey, 0);
203
204 PhAreaToRect(&overlay->hwdata->CurrentWindow, &overlay->hwdata->props.viewport);
205
206 overlay->hwdata->props.flags = Pg_SCALER_PROP_DOUBLE_BUFFER;
207
208 if ((overlay->hwdata->ischromakey)&&(overlay->hwdata->chromakey))
209 {
210 overlay->hwdata->props.flags |= Pg_SCALER_PROP_CHROMA_ENABLE;
211 overlay->hwdata->props.color_key = overlay->hwdata->chromakey;
212 overlay->hwdata->props.color_key_mask = 0x00FFFFFFUL;
213 }
214 else
215 {
216 overlay->hwdata->props.flags &= ~Pg_SCALER_PROP_CHROMA_ENABLE;
217 }
218
219 rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &overlay->hwdata->props);
220
221 switch(rtncode)
222 {
223 case -1: SDL_SetError("PgConfigScalerChannel failed\n");
224 SDL_FreeYUVOverlay(overlay);
225 return(NULL);
226 break;
227 case 1:
228 case 0:
229 default:
230 break;
231 }
232
233 planes = grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
234
235 if(overlay->hwdata->channel->yplane1 != NULL)
236 overlay->hwdata->YStride = overlay->hwdata->channel->yplane1->pitch;
237 if(overlay->hwdata->channel->uplane1 != NULL)
238 overlay->hwdata->UStride = overlay->hwdata->channel->uplane1->pitch;
239 if(overlay->hwdata->channel->vplane1 != NULL)
240 overlay->hwdata->VStride = overlay->hwdata->channel->vplane1->pitch;
241
242 overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
243
244 if(overlay->hwdata->current==0)
245 overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
246 else
247 overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
248
249 overlay->hwdata->locked = 1;
250
251 /* Find the pitch and offset values for the overlay */
252 overlay->planes = planes;
253 overlay->pitches = calloc(overlay->planes, sizeof(Uint16));
254 overlay->pixels = calloc(overlay->planes, sizeof(Uint8*));
255 if (!overlay->pitches || !overlay->pixels)
256 {
257 SDL_OutOfMemory();
258 SDL_FreeYUVOverlay(overlay);
259 return(NULL);
260 }
261
262 if (overlay->planes > 0)
263 {
264 overlay->pitches[0] = overlay->hwdata->channel->yplane1->pitch;
265 overlay->pixels[0] = overlay->hwdata->CurrentFrameData->Y;
266 }
267 if (overlay->planes > 1)
268 {
269 overlay->pitches[1] = overlay->hwdata->channel->uplane1->pitch;
270 overlay->pixels[1] = overlay->hwdata->CurrentFrameData->U;
271 }
272 if (overlay->planes > 2)
273 {
274 overlay->pitches[2] = overlay->hwdata->channel->vplane1->pitch;
275 overlay->pixels[2] = overlay->hwdata->CurrentFrameData->V;
276 }
277
278 overlay->hwdata->State = OVERLAY_STATE_ACTIVE;
279 overlay->hwdata->scaler_on = 0;
280 overlay->hw_overlay = 1;
281
282 return (overlay);
283 }
284
285 int ph_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
286 {
287 if (overlay == NULL)
288 return 0;
289
290 overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
291 if (overlay->hwdata->current == -1)
292 {
293 SDL_SetError("PgNextFrame failed, bailing out\n");
294 SDL_FreeYUVOverlay(overlay);
295 return(NULL);
296 }
297
298 overlay->hwdata->locked = 1;
299
300 /* set current frame for double buffering */
301 if (overlay->hwdata->current == 0)
302 overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
303 else
304 overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
305
306 if (overlay->planes > 0)
307 {
308 overlay->pitches[0] = overlay->hwdata->channel->yplane1->pitch;
309 overlay->pixels[0] = overlay->hwdata->CurrentFrameData->Y;
310 }
311 if (overlay->planes > 1)
312 {
313 overlay->pitches[1] = overlay->hwdata->channel->uplane1->pitch;
314 overlay->pixels[1] = overlay->hwdata->CurrentFrameData->U;
315 }
316 if (overlay->planes > 2)
317 {
318 overlay->pitches[2] = overlay->hwdata->channel->vplane1->pitch;
319 overlay->pixels[2] = overlay->hwdata->CurrentFrameData->V;
320 }
321
322 return(0);
323 }
324
325 void ph_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
326 {
327 int rtncode;
328
329 if(overlay == NULL)
330 return;
331
332 if(overlay->hwdata->scaler_on == 1)
333 {
334 rtncode =PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props));
335 switch(rtncode)
336 {
337 case -1:
338 SDL_SetError("PgConfigScalerChannel failed\n");
339 SDL_FreeYUVOverlay(overlay);
340 break;
341 case 1:
342 grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
343 break;
344 case 0:
345 default:
346 break;
347 }
348 }
349
350 /* This would be the best place to draw chromakey but we do not have a SDL_Surface in the args
351 * This means we might see a chromakey flicker at startup. */
352 }
353
354 int ph_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect)
355 {
356 int rtncode;
357 PhPoint_t pos;
358
359 if(overlay == NULL)
360 return -1;
361
362 /* If CurrentWindow has change, move the viewport */
363 if((overlay->hwdata->CurrentWindow.pos.x != dstrect->x) ||
364 (overlay->hwdata->CurrentWindow.pos.y != dstrect->y) ||
365 (overlay->hwdata->CurrentWindow.size.w != dstrect->w) ||
366 (overlay->hwdata->CurrentWindow.size.h != dstrect->h) ||
367 (overlay->hwdata->scaler_on==0))
368 {
369 if(overlay->hwdata->State == OVERLAY_STATE_UNINIT)
370 return -1;
371
372 overlay->hwdata->props.flags |= Pg_SCALER_PROP_SCALER_ENABLE;
373 overlay->hwdata->scaler_on = 1;
374
375 PtGetAbsPosition(window, &pos.x, &pos.y);
376 overlay->hwdata->CurrentWindow.pos.x = pos.x + dstrect->x;
377 overlay->hwdata->CurrentWindow.pos.y = pos.y + dstrect->y;
378 overlay->hwdata->CurrentWindow.size.w = dstrect->w;
379 overlay->hwdata->CurrentWindow.size.h = dstrect->h;
380
381 PhAreaToRect(&overlay->hwdata->CurrentWindow, &overlay->hwdata->props.viewport);
382
383 rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props));
384
385 switch(rtncode)
386 {
387 case -1:
388 SDL_SetError("PgConfigScalerChannel failed\n");
389 SDL_FreeYUVOverlay(overlay);
390 return (0);
391 case 1:
392 grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
393 break;
394 case 0:
395 default:
396 break;
397 }
398 }
399
400 if (!overlay->hwdata->locked)
401 {
402 overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
403 if (overlay->hwdata->current == -1)
404 {
405 SDL_SetError("PgNextVideoFrame failed\n");
406 SDL_FreeYUVOverlay(overlay);
407 return 0;
408 }
409 if (overlay->hwdata->current == 0)
410 overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
411 else
412 overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
413
414 if (overlay->planes > 0)
415 {
416 overlay->pitches[0] = overlay->hwdata->channel->yplane1->pitch;
417 overlay->pixels[0] = overlay->hwdata->CurrentFrameData->Y;
418 }
419 if (overlay->planes > 1)
420 {
421 overlay->pitches[1] = overlay->hwdata->channel->uplane1->pitch;
422 overlay->pixels[1] = overlay->hwdata->CurrentFrameData->U;
423 }
424 if (overlay->planes > 2)
425 {
426 overlay->pitches[2] = overlay->hwdata->channel->vplane1->pitch;
427 overlay->pixels[2] = overlay->hwdata->CurrentFrameData->V;
428 }
429 }
430
431 return 0;
432 }
433
434 void ph_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
435 {
436 if (overlay == NULL)
437 return;
438
439 if (overlay->hwdata == NULL)
440 return;
441
442 /* it is need for some buggy drivers, that can't hide overlay before */
443 /* freeing buffer, so we got trash on the srceen */
444 overlay->hwdata->props.flags &= ~Pg_SCALER_PROP_SCALER_ENABLE;
445 PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props));
446
447 overlay->hwdata->scaler_on = 0;
448 overlay->hwdata->State = OVERLAY_STATE_UNINIT;
449
450 if (overlay->hwdata->channel != NULL)
451 {
452 PgDestroyVideoChannel(overlay->hwdata->channel);
453 overlay->hwdata->channel = NULL;
454 return;
455 }
456
457 overlay->hwdata->CurrentFrameData = NULL;
388 458
389 PtEnter(0); 459 free(overlay->hwdata->FrameData0);
390 PtSetArg( &argt, Pt_ARG_FILL_COLOR, overlay->hwdata->chromakey, 0 ); 460 free(overlay->hwdata->FrameData1);
391 PtSetResources( window, 1, &argt ); 461 overlay->hwdata->FrameData0 = NULL;
392 PtLeave(0); 462 overlay->hwdata->FrameData1 = NULL;
393 463 free(overlay->hwdata);
394 464 }
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;
498 overlay->pitches = (Uint16*) &(overlay->hwdata->YStride);
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 }