diff 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
line wrap: on
line diff
--- a/src/video/photon/SDL_phyuv.c	Mon Jan 20 01:37:07 2003 +0000
+++ b/src/video/photon/SDL_phyuv.c	Mon Jan 20 01:38:37 2003 +0000
@@ -29,11 +29,6 @@
 
 #include <stdlib.h>
 #include <string.h>
-#ifndef bool
-#define bool char
-#define TRUE 1
-#define FALSE 0
-#endif
 #include <errno.h>
 
 #include <Ph.h>
@@ -44,606 +39,426 @@
 #include "SDL_phyuv_c.h"
 #include "SDL_yuvfuncs.h"
 
-#if 0  //just for reference
-/* YUV data formats			FourCC		   Layout		H sample (YUV)	V sample (YUV)	BPP */
-#define Pg_VIDEO_FORMAT_IYU1		0x31555949	/* U2Y2Y2V2Y2Y2		144		111		12  */
-#define Pg_VIDEO_FORMAT_IYU2		0x32555949	/* U4Y4V4U4Y4V4		111		111		24  */
-#define Pg_VIDEO_FORMAT_UYVY		0x59565955	/* U8Y8V8Y8		122		111		16  */
-#define Pg_VIDEO_FORMAT_YUY2		0x32595559	/* Y8U8Y8V8		122		111		16  */
-#define Pg_VIDEO_FORMAT_YVYU		0x55595659	/* Y8V8Y8U8		122		111		16  */
-#define Pg_VIDEO_FORMAT_V422		0x56343232	/* V8Y8U8Y8		122		111		16  */
-#define Pg_VIDEO_FORMAT_CLJR		0x524a4c43	/* V6U6Y5Y5Y5Y5		133		111		8   */
-#define Pg_VIDEO_FORMAT_YVU9		0x39555659	/* Planar YVU		144		144		9   */
-#define Pg_VIDEO_FORMAT_YV12		0x32315659	/* Planar YUV		122		122		12  */
-
-/* There seems to be no FourCC that matches this */
-#define Pg_VIDEO_FORMAT_YUV420		0x00000100	/* Planar YUV		122		111		16  */
-
-/* These formats are the same as YV12, except the U and V planes do not have to contiguously follow the Y plane */
-/* but they're all the same to us, since we always have 3 plane pointers */
-#define Pg_VIDEO_FORMAT_CLPL	Pg_VIDEO_FORMAT_YV12	/* Cirrus Logic Planar format */
-#define Pg_VIDEO_FORMAT_VBPL	Pg_VIDEO_FORMAT_YV12	/* VooDoo Banshee planar format */
-
-#define SDL_YV12_OVERLAY	0x32315659	/* Planar mode: Y + V + U */
-#define SDL_IYUV_OVERLAY	0x56555949	/* Planar mode: Y + U + V */
-#define SDL_YUY2_OVERLAY	0x32595559	/* Packed mode: Y0+U0+Y1+V0 */
-#define SDL_UYVY_OVERLAY	0x59565955	/* Packed mode: U0+Y0+V0+Y1 */
-#define SDL_YVYU_OVERLAY	0x55595659	/* Packed mode: Y0+V0+Y1+U0 */
-
-#endif 
-
-
-#define OVERLAY_STATE_UNINIT  0
+#define OVERLAY_STATE_UNINIT 0
 #define OVERLAY_STATE_ACTIVE 1
 
 /* The functions used to manipulate software video overlays */
 static struct private_yuvhwfuncs ph_yuvfuncs = {
-	ph_LockYUVOverlay,
-	ph_UnlockYUVOverlay,
-	ph_DisplayYUVOverlay,
-	ph_FreeYUVOverlay
+    ph_LockYUVOverlay,
+    ph_UnlockYUVOverlay,
+    ph_DisplayYUVOverlay,
+    ph_FreeYUVOverlay
 };
 
-
-typedef struct {
-  int id;
-  int width, height;
-  int data_size;              /* bytes */
-  int num_planes;
-  int *pitches;               /* bytes */
-  int *offsets;               /* bytes */
-  char *data;
-  void *obdata;     
-} XvImage;
-
-
 struct private_yuvhwdata {
-	XvImage *image;	
-	FRAMEDATA *CurrentFrameData;
-	FRAMEDATA *FrameData0;
-	FRAMEDATA *FrameData1;
-	PgScalerProps_t	props;
-	PgScalerCaps_t	caps;
-	PgVideoChannel_t *channel;
-	SDL_Rect CurrentWindow;
-	long format;
-	int screen_width;
-	int screen_height ;
-	int screen_bpp ;    //2
-	bool planar;
-	bool scaler_on ;
-	int current;
-	long YStride;
-	long VStride;
-	long UStride;
-	long chromakey;
-	unsigned long State;
-	long flags;
+    FRAMEDATA* CurrentFrameData;
+    FRAMEDATA* FrameData0;
+    FRAMEDATA* FrameData1;
+    PgScalerProps_t   props;
+    PgScalerCaps_t    caps;
+    PgVideoChannel_t* channel;
+    PhArea_t CurrentWindow;
+    long format;
+    int planar;
+    int scaler_on;
+    int current;
+    long YStride;
+    long VStride;
+    long UStride;
+    int ischromakey;
+    long chromakey;
+    unsigned long State;
+    long flags;
+    int locked;
 };
 
-extern PgVideoChannel_t * PgCreateVideoChannel(unsigned type, unsigned flags);
-extern int PgGetScalerCapabilities( PgVideoChannel_t *channel, int format_index, PgScalerCaps_t *vcaps );
-extern int PgConfigScalerChannel(PgVideoChannel_t *channel, PgScalerProps_t *props);
-extern void PgDestroyVideoChannel(PgVideoChannel_t *channel);
-extern PgColor_t PgGetOverlayChromaColor(void);
-
-void
-grab_ptrs2(PgVideoChannel_t *channel, FRAMEDATA *Frame0, FRAMEDATA *Frame1 )
+int grab_ptrs2(PgVideoChannel_t* channel, FRAMEDATA* Frame0, FRAMEDATA* Frame1 )
 {
+    int planes = 0;
 
-	/* Buffers have moved; re-obtain the pointers */
-	Frame0->Y = (unsigned char *)PdGetOffscreenContextPtr(channel->yplane1);
-	Frame1->Y = (unsigned char *)PdGetOffscreenContextPtr(channel->yplane2);
-	Frame0->U = (unsigned char *)PdGetOffscreenContextPtr(channel->uplane1);
-	Frame1->U = (unsigned char *)PdGetOffscreenContextPtr(channel->uplane2);
-	Frame0->V = (unsigned char *)PdGetOffscreenContextPtr(channel->vplane1);
-	Frame1->V = (unsigned char *)PdGetOffscreenContextPtr(channel->vplane2);
+    /* Buffers have moved; re-obtain the pointers */
+    Frame0->Y = (unsigned char *)PdGetOffscreenContextPtr(channel->yplane1);
+    Frame1->Y = (unsigned char *)PdGetOffscreenContextPtr(channel->yplane2);
+    Frame0->U = (unsigned char *)PdGetOffscreenContextPtr(channel->uplane1);
+    Frame1->U = (unsigned char *)PdGetOffscreenContextPtr(channel->uplane2);
+    Frame0->V = (unsigned char *)PdGetOffscreenContextPtr(channel->vplane1);
+    Frame1->V = (unsigned char *)PdGetOffscreenContextPtr(channel->vplane2);
 
+    if (Frame0->Y)
+        planes++;
+
+    if (Frame0->U)
+        planes++;
+
+    if (Frame0->V)
+        planes++;
+
+    return planes;
 }
 
 SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
 {
-	SDL_Overlay *overlay;
-	struct private_yuvhwdata *hwdata;
-	int xv_port;
-	int rtncode;
-//	PhRect_t rect;
-//	PhSysInfo_t info;
-//	PhRegion_t region;
-//	short x, y;
-	PtArg_t argt;
-	int i =0;
-//	bool bCont = TRUE;
-	int Priority[20];
-	int Type[20];
-	int entries, select, highest;
+    SDL_Overlay *overlay;
+    struct private_yuvhwdata *hwdata;
+    int xv_port;
+    int rtncode;
+    int planes;
+    int i=0;
+    PhPoint_t pos;
 
-	PhDCSetCurrent(0);  //Need to set draw context to window esp. if we we in Offscreeen mode
+    /* Create the overlay structure */
+    overlay = calloc(1, sizeof(SDL_Overlay));
+
+    if (overlay == NULL) {
+        SDL_OutOfMemory();
+        return (NULL);
+    }
 
-	/* Create the overlay structure */
-	overlay = (SDL_Overlay *)malloc(sizeof(SDL_Overlay));
-        memset(overlay, 0x00, sizeof(SDL_Overlay));
-	if ( overlay == NULL ) {
-		SDL_OutOfMemory();
-		return(NULL);
-	}
-	memset(overlay, 0, (sizeof *overlay));
-
-	/* Fill in the basic members */
-	overlay->format = format;
-	overlay->w = width;
-	overlay->h = height;
+    /* Fill in the basic members */
+    overlay->format = format;
+    overlay->w = width;
+    overlay->h = height;
 	
-	/* Set up the YUV surface function structure */
-	overlay->hwfuncs = &ph_yuvfuncs;
+    /* Set up the YUV surface function structure */
+    overlay->hwfuncs = &ph_yuvfuncs;
+
+    /* Create the pixel data and lookup tables */
+    hwdata = calloc(1, sizeof(struct private_yuvhwdata));
 
-	/* Create the pixel data and lookup tables */
-	hwdata = (struct private_yuvhwdata *)malloc(sizeof(struct private_yuvhwdata));
-        memset(hwdata, 0x00, sizeof(struct private_yuvhwdata));
-	overlay->hwdata = hwdata;
-	if ( hwdata == NULL ) {
-		SDL_OutOfMemory();
-		SDL_FreeYUVOverlay(overlay);
-		return(NULL);
-	}
-	
+    overlay->hwdata = hwdata;
+    if (hwdata == NULL) {
+        SDL_OutOfMemory();
+        SDL_FreeYUVOverlay(overlay);
+        return(NULL);
+    }
+
+    PhDCSetCurrent(0);
     if (overlay->hwdata->channel == NULL)
     {
         if ((overlay->hwdata->channel = PgCreateVideoChannel(Pg_VIDEO_CHANNEL_SCALER,0)) == NULL) 
         {
-            SDL_SetError("ph_CreateYUVOverlay(): Create channel failed: %s\n", strerror( errno ));
-            free(overlay->hwdata);
-            free(overlay);
-            return (NULL);
+            SDL_SetError("ph_CreateYUVOverlay(): Create channel failed: %s\n", strerror(errno));
+            SDL_FreeYUVOverlay(overlay);
+
+            return(NULL);
+
         }
     }
 
-    overlay->hwdata->CurrentWindow.x = 0;
-    overlay->hwdata->CurrentWindow.y = 0;
-    overlay->hwdata->CurrentWindow.w = 320;
-    overlay->hwdata->CurrentWindow.h = 240;
-
+    PtGetAbsPosition(window, &pos.x, &pos.y);
+    overlay->hwdata->CurrentWindow.pos.x = pos.x;
+    overlay->hwdata->CurrentWindow.pos.y = pos.y;
+    overlay->hwdata->CurrentWindow.size.w = width;
+    overlay->hwdata->CurrentWindow.size.h = height;
     overlay->hwdata->State = OVERLAY_STATE_UNINIT;
-
-    overlay->hwdata->screen_bpp = 2;
-    overlay->hwdata->scaler_on = FALSE;
-    overlay->hwdata->screen_width = 1024;
-    overlay->hwdata->screen_height  = 768;
-
-    overlay->hwdata->FrameData0 = (FRAMEDATA *) malloc((size_t)(sizeof(FRAMEDATA)));
-    overlay->hwdata->FrameData1 = (FRAMEDATA *) malloc((size_t)(sizeof(FRAMEDATA)));
-    memset(overlay->hwdata->FrameData0, 0x00, (size_t)(sizeof(FRAMEDATA)));
-    memset(overlay->hwdata->FrameData1, 0x00, (size_t)(sizeof(FRAMEDATA)));
-
-    overlay->hwdata->caps.size = sizeof(overlay->hwdata->caps);
-
-//Note you really don't need to do this for SDL as you are given a format, but this is a good example
+    overlay->hwdata->FrameData0 = (FRAMEDATA *) calloc(1, sizeof(FRAMEDATA));
+    overlay->hwdata->FrameData1 = (FRAMEDATA *) calloc(1, sizeof(FRAMEDATA));
 
     xv_port = -1;
     i=0;
-
-while(PgGetScalerCapabilities(overlay->hwdata->channel, i++, &(overlay->hwdata->caps)) == 0) 
-{
-		if(overlay->hwdata->caps.format  == Pg_VIDEO_FORMAT_YV12) //in SDL
-		{
-			
-			Priority[i-1] = 0;
-			Type[i-1] = Pg_VIDEO_FORMAT_YV12;
-			if(format == Pg_VIDEO_FORMAT_YV12)
-			{
-				overlay->hwdata->props.format =  Pg_VIDEO_FORMAT_YV12;
-				xv_port = 1; //supported
-				Priority[i-1] = 100; //force selected
-			}
-			
-		}
-		else if(overlay->hwdata->caps.format  == Pg_VIDEO_FORMAT_YVU9) //in SDL
-		{
-			
-			Priority[i-1] = 0;
-			Type[i-1] = Pg_VIDEO_FORMAT_YVU9;			
-			if(format == Pg_VIDEO_FORMAT_YVU9)
-			{
-				overlay->hwdata->props.format =  Pg_VIDEO_FORMAT_YVU9;
-				xv_port = 1; //supported
-				Priority[i-1] = 100; //force selected
-			}
-			
-		}
-#if 0 //this part of SDL is YUV specific
-		else if(overlay->hwdata->caps.format  == Pg_VIDEO_FORMAT_RGB555)
-		{
-			
-			Priority[i-1] = 3;
-			Type[i-1] = Pg_VIDEO_FORMAT_RGB555;			
-		}
-		else if(overlay->hwdata->caps.format  == Pg_VIDEO_FORMAT_RGB565)
-		{
-			
-			Priority[i-1] =  2;
-			Type[i-1] = Pg_VIDEO_FORMAT_RGB565;			
-		}
-		else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_RGB8888)
-		{
-			
-			Priority[i-1] = 1;
-			Type[i-1] = Pg_VIDEO_FORMAT_RGB8888;			
-		}
-#endif
-		else if(overlay->hwdata->caps.format  == Pg_VIDEO_FORMAT_IYU1)
-		{
-			
-			Priority[i-1] = 0;
-			Type[i-1] = Pg_VIDEO_FORMAT_IYU1;
-			
-		}
-		else if(overlay->hwdata->caps.format  == Pg_VIDEO_FORMAT_IYU2)
-		{
-			
-			Priority[i-1] = 0;
-			Type[i-1] = Pg_VIDEO_FORMAT_IYU2;			
-		}
+    
+    overlay->hwdata->ischromakey=0;
 
-		else if(overlay->hwdata->caps.format  == Pg_VIDEO_FORMAT_UYVY) //in SDL
-		{
-			
-			Priority[i-1] = 7;
-			Type[i-1] = Pg_VIDEO_FORMAT_UYVY;
-			if(format == Pg_VIDEO_FORMAT_UYVY)
-			{
-				overlay->hwdata->props.format =  Pg_VIDEO_FORMAT_UYVY;
-				xv_port = 1; //supported
-				Priority[i-1] = 100; //force selected
-			}
-			
-		}
-		else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_YUY2) //in SDL
-		{
-			
-			Priority[i-1] = 8;
-			Type[i-1] = Pg_VIDEO_FORMAT_YUY2;			
-			if(format == Pg_VIDEO_FORMAT_YUY2)
-			{
-				overlay->hwdata->props.format =  Pg_VIDEO_FORMAT_YUY2;
-				xv_port = 1; //supported
-				Priority[i-1] = 100; //force selected
-			}
-			
-		}
-		else if(overlay->hwdata->caps.format  == Pg_VIDEO_FORMAT_YVYU) //in SDL
-		{
-			
-			Priority[i-1] = 4;
-			Type[i-1] = Pg_VIDEO_FORMAT_YVYU;	
-			
-			if(format == Pg_VIDEO_FORMAT_YVYU)
-			{
-				overlay->hwdata->props.format =  Pg_VIDEO_FORMAT_YVYU;
-				xv_port = 1; //supported
-				Priority[i-1] = 100; //force selected
-				
-			}
-		
-		}
-		else if(overlay->hwdata->caps.format  == Pg_VIDEO_FORMAT_V422)
-		{
-			
-			Priority[i-1] = 5;
-			Type[i-1] = Pg_VIDEO_FORMAT_V422;			
-		}		
-		else if(overlay->hwdata->caps.format  == Pg_VIDEO_FORMAT_CLJR)
-		{
-			
-			Priority[i-1] = 6;
-			Type[i-1] = Pg_VIDEO_FORMAT_CLJR;		
-		}	
-		else
-		{
-		
-		Priority[i-1] = 0;
-		}
-			
-overlay->hwdata->caps.size = sizeof(overlay->hwdata->caps);
-}
-
-	if ( xv_port == -1 )
-	{
-		SDL_SetError("No available video ports for requested format");
-		return(NULL);
-	}
- 
-//Pick the highest priority format
-entries = i -2;
-highest = Priority[0]; //make first entry top at begining
-select = 0;
-
-for (i = 1; i < entries; i++)
-{
+    do {
+        memset(&overlay->hwdata->caps, 0x00, sizeof(PgScalerCaps_t));
+        overlay->hwdata->caps.size = sizeof(PgScalerCaps_t);
+        rtncode = PgGetScalerCapabilities(overlay->hwdata->channel, i, &overlay->hwdata->caps);
+        if (rtncode==0)
+        { 
+            if (overlay->hwdata->caps.format==format)
+            {
+               if ((overlay->hwdata->caps.flags & Pg_SCALER_CAP_DST_CHROMA_KEY) == Pg_SCALER_CAP_DST_CHROMA_KEY)
+               {
+                   overlay->hwdata->ischromakey=1;
+               }
+               xv_port=1;
+               break;
+            }
+        }
+        else
+        {
+           break;
+        }
+        i++;
+    } while(1);
 
 
-   if(Priority[i] > highest)
-   {
-      highest = Priority[i];
-      select  = i;
-   }
-} 
-
- 
+    if (xv_port == -1)
+    {
+        SDL_SetError("No available video ports for requested format\n");
+        SDL_FreeYUVOverlay(overlay);
+        return(NULL);
+    }
  
- overlay->hwdata->caps.size = sizeof (overlay->hwdata->caps	);
-PgGetScalerCapabilities(overlay->hwdata->channel, select, &(overlay->hwdata->caps));
-overlay->hwdata->props.format = overlay->hwdata->caps.format ;
-
-    overlay->hwdata->format = overlay->hwdata->props.format;  //to make easier for apps to use
-
-
-	overlay->hwdata->props.size = sizeof (overlay->hwdata->props);
+    overlay->hwdata->format = format;
+    overlay->hwdata->props.format = format;
+    overlay->hwdata->props.size = sizeof(PgScalerProps_t);
     overlay->hwdata->props.src_dim.w = width;   
     overlay->hwdata->props.src_dim.h = height;   
 	
-	overlay->hwdata->chromakey = PgGetOverlayChromaColor();
+    /* Don't use chromakey for now, blitting a surface will cover the window,
+     * and therefore the chroma. */
+    overlay->hwdata->chromakey = 0;
+    PtSetResource(window, Pt_ARG_FILL_COLOR, overlay->hwdata->chromakey, 0);
 
-	// Set chromakey in video widget so we can see overlay data
-	/* I don't know where the container widget is!!!, I guess it is in hidden->window*/
-	
-	PtEnter(0);
-	PtSetArg( &argt, Pt_ARG_FILL_COLOR, overlay->hwdata->chromakey, 0 );
-	PtSetResources( window, 1, &argt ); 
-	PtLeave(0);
+    PhAreaToRect(&overlay->hwdata->CurrentWindow, &overlay->hwdata->props.viewport);
 
-
-	fflush( stderr );
+    overlay->hwdata->props.flags = Pg_SCALER_PROP_DOUBLE_BUFFER;
 
-	overlay->hwdata->props.viewport.ul.x = overlay->hwdata->CurrentWindow.x;
-	overlay->hwdata->props.viewport.ul.y = overlay->hwdata->CurrentWindow.y;
-	//Next line MIGHT have x and y reversed!!!!!!!!!!!!
-	overlay->hwdata->props.viewport.lr.x = overlay->hwdata->CurrentWindow.x +overlay->hwdata->CurrentWindow.w;
-	overlay->hwdata->props.viewport.lr.y = overlay->hwdata->CurrentWindow.y + overlay->hwdata->CurrentWindow.h;
-		
+    if ((overlay->hwdata->ischromakey)&&(overlay->hwdata->chromakey))
+    {
+        overlay->hwdata->props.flags |= Pg_SCALER_PROP_CHROMA_ENABLE;
+        overlay->hwdata->props.color_key = overlay->hwdata->chromakey;
+        overlay->hwdata->props.color_key_mask = 0x00FFFFFFUL;
+    } 
+    else
+    {
+        overlay->hwdata->props.flags &= ~Pg_SCALER_PROP_CHROMA_ENABLE;
+    }
 
-
-	overlay->hwdata->props.flags =
-	    ~Pg_SCALER_PROP_SCALER_ENABLE | Pg_SCALER_PROP_DOUBLE_BUFFER ;
+    rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &overlay->hwdata->props);
 
-	if (overlay->hwdata->chromakey) {
-		overlay->hwdata->props.flags |= Pg_SCALER_PROP_CHROMA_ENABLE;
-		overlay->hwdata->props.color_key = overlay->hwdata->chromakey;
-		overlay->hwdata->props.color_key_mask = 0xffffff;
-	} 
-	else
-	{
-		overlay->hwdata->props.flags &= ~Pg_SCALER_PROP_CHROMA_ENABLE;
-	}
+    switch(rtncode)
+    {
+        case -1: SDL_SetError("PgConfigScalerChannel failed\n");
+		 SDL_FreeYUVOverlay(overlay);
+		 return(NULL);
+   		 break;
+        case 1:
+        case 0:
+        default:
+                 break;
+    }
 
-
-	overlay->hwdata->scaler_on = FALSE;
-
-
+    planes = grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
 
- rtncode =    PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props));	
-	switch(rtncode)
-	{
-	case -1:
-		SDL_SetError("PgConfigScalerChannel failed\n");
-		SDL_FreeYUVOverlay(overlay);
-		return(NULL);
-   		break;
-	case 1:
-		grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
-		break;
-	case 0:
-	default:
-   		break;
-	}
+    if(overlay->hwdata->channel->yplane1 != NULL)			
+        overlay->hwdata->YStride = overlay->hwdata->channel->yplane1->pitch;
+    if(overlay->hwdata->channel->uplane1 != NULL)			
+        overlay->hwdata->UStride = overlay->hwdata->channel->uplane1->pitch;
+    if(overlay->hwdata->channel->vplane1 != NULL)			
+        overlay->hwdata->VStride = overlay->hwdata->channel->vplane1->pitch;
 
-
-	grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
+    overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
 
-if(overlay->hwdata->channel->yplane1 != NULL)			
-	overlay->hwdata->YStride = overlay->hwdata->channel->yplane1->pitch;
-if(overlay->hwdata->channel->uplane1 != NULL)			
-	overlay->hwdata->UStride = overlay->hwdata->channel->uplane1->pitch;
-if(overlay->hwdata->channel->vplane1 != NULL)			
-	overlay->hwdata->VStride = overlay->hwdata->channel->vplane1->pitch;
+    if(overlay->hwdata->current==0)
+        overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
+    else
+        overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
 
+    overlay->hwdata->locked = 1;
 
-	overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
-
-
+    /* Find the pitch and offset values for the overlay */
+    overlay->planes = planes;
+    overlay->pitches = calloc(overlay->planes, sizeof(Uint16));
+    overlay->pixels  = calloc(overlay->planes, sizeof(Uint8*));
+    if (!overlay->pitches || !overlay->pixels)
+    {
+        SDL_OutOfMemory();
+        SDL_FreeYUVOverlay(overlay);
+        return(NULL);
+    }
 
-	if (overlay->hwdata->current == -1)
-	{
-		SDL_SetError("PgNextFrame failed, bailing out\n");
-		SDL_FreeYUVOverlay(overlay);
-		return(NULL);
-	}
-        
-        //set current frame for double buffering
-	if(overlay->hwdata->current == 0)
-	{
-		overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
-	}
-	else
-	{
-		overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
-	}
-    
-	overlay->hwdata->State = OVERLAY_STATE_ACTIVE;
+    if (overlay->planes > 0)
+    {
+        overlay->pitches[0] = overlay->hwdata->channel->yplane1->pitch;
+        overlay->pixels[0]  = overlay->hwdata->CurrentFrameData->Y;
+    }
+    if (overlay->planes > 1)
+    {
+        overlay->pitches[1] = overlay->hwdata->channel->uplane1->pitch;
+        overlay->pixels[1]  = overlay->hwdata->CurrentFrameData->U;
+    }
+    if (overlay->planes > 2)
+    {
+        overlay->pitches[2] = overlay->hwdata->channel->vplane1->pitch;
+        overlay->pixels[2]  = overlay->hwdata->CurrentFrameData->V;
+    }
 
+    overlay->hwdata->State = OVERLAY_STATE_ACTIVE;
+    overlay->hwdata->scaler_on = 0;
+    overlay->hw_overlay = 1;
 
-	/* We're all done.. */
-	return(overlay);
+    return (overlay);
 }
 
 int ph_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
 {
-//int rtncode;
+    if (overlay == NULL)
+        return 0;
 
-if(overlay == NULL)
-   return 0;
+    overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
+    if (overlay->hwdata->current == -1)
+    {
+        SDL_SetError("PgNextFrame failed, bailing out\n");
+        SDL_FreeYUVOverlay(overlay);
+        return(NULL);
+    }
+
+    overlay->hwdata->locked = 1;
 
-//set current frame for double buffering
-	if(overlay->hwdata->current == 0)
-	{
-		overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
-	}
-	else
-	{
-		overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
-	}
+    /* set current frame for double buffering */
+    if (overlay->hwdata->current == 0)
+        overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
+    else
+        overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
 
-	//Lock gets the pointer and passes it to the app. The app writes all yuv data into overlay->pixels
-//Note this is defined as Uint8 **pixels;				/* Read-write */	
-	overlay->pixels = &overlay->hwdata->CurrentFrameData->Y; 
-	overlay->pitches = (Uint16*) &(overlay->hwdata->YStride);
-		
-	return(0);
+    if (overlay->planes > 0)
+    {
+        overlay->pitches[0] = overlay->hwdata->channel->yplane1->pitch;
+        overlay->pixels[0]  = overlay->hwdata->CurrentFrameData->Y;
+    }
+    if (overlay->planes > 1)
+    {
+        overlay->pitches[1] = overlay->hwdata->channel->uplane1->pitch;
+        overlay->pixels[1]  = overlay->hwdata->CurrentFrameData->U;
+    }
+    if (overlay->planes > 2)
+    {
+        overlay->pitches[2] = overlay->hwdata->channel->vplane1->pitch;
+        overlay->pixels[2]  = overlay->hwdata->CurrentFrameData->V;
+    }
+
+    return(0);
 }
 
 void ph_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
 {
-int rtncode;
-
-if(overlay == NULL)
-   return ;
+    int rtncode;
 
-		if(overlay->hwdata->scaler_on == FALSE) 
-		{
-			
-		
-		overlay->hwdata->props.flags |= Pg_SCALER_PROP_SCALER_ENABLE;
+    if(overlay == NULL)
+         return;
+
+    if(overlay->hwdata->scaler_on == 1) 
+    {
         rtncode =PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props));
-        	switch(rtncode)
-			{
-				case -1:
-					SDL_SetError("PgConfigScalerChannel failed\n");
-					SDL_FreeYUVOverlay(overlay);
-   					break;
-				case 1:
-					grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
-					overlay->hwdata->scaler_on = TRUE;
-					break;
-				case 0:
-					default:
-					overlay->hwdata->scaler_on = TRUE;
-   					break;
-			}
-//This would be the best place to draw chromakey but we do not have a SDL_Surface in the args
-//This means we might see a chromakey flicker at startup
-		}
-		overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
+        switch(rtncode)
+        {
+            case -1:
+                     SDL_SetError("PgConfigScalerChannel failed\n");
+                     SDL_FreeYUVOverlay(overlay);
+                     break;
+            case 1:
+                     grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
+                     break;
+            case 0:
+            default:
+                     break;
+        }
+    }
 
-
-	if (overlay->hwdata->current == -1) {
-		SDL_SetError("PgNextVideoFrame failed\n");
-		SDL_FreeYUVOverlay(overlay);	
-		return;	
-	}
-
-	overlay->pixels = NULL;
+    /* This would be the best place to draw chromakey but we do not have a SDL_Surface in the args
+     * This means we might see a chromakey flicker at startup. */
 }
 
 int ph_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect)
 {
-int rtncode;
+    int rtncode;
+    PhPoint_t pos;
 
-if(overlay == NULL)
-   return 0;
-
+    if(overlay == NULL)
+        return -1;
 
-	/*SDL_Rect CurrentWindow*/
-//If CurrentWindow has change, move the viewport
-if((overlay->hwdata->CurrentWindow.x != dstrect->x) ||
-  (overlay->hwdata->CurrentWindow.y != dstrect->y) ||
-  (overlay->hwdata->CurrentWindow.w != dstrect->w) ||
-  (overlay->hwdata->CurrentWindow.h != dstrect->h))
-{
-		if(overlay->hwdata->State == OVERLAY_STATE_UNINIT)
-		return -1;
+    /* If CurrentWindow has change, move the viewport */
+    if((overlay->hwdata->CurrentWindow.pos.x != dstrect->x) ||
+       (overlay->hwdata->CurrentWindow.pos.y != dstrect->y) ||
+       (overlay->hwdata->CurrentWindow.size.w != dstrect->w) ||
+       (overlay->hwdata->CurrentWindow.size.h != dstrect->h) ||
+       (overlay->hwdata->scaler_on==0))
+    {
+        if(overlay->hwdata->State == OVERLAY_STATE_UNINIT)
+            return -1;
 
-	overlay->hwdata->CurrentWindow.x = dstrect->x;
-  	overlay->hwdata->CurrentWindow.y = dstrect->y;
-  	overlay->hwdata->CurrentWindow.w = dstrect->w;
-  	overlay->hwdata->CurrentWindow.h = dstrect->h;
+        overlay->hwdata->props.flags |= Pg_SCALER_PROP_SCALER_ENABLE;
+        overlay->hwdata->scaler_on = 1;
 
-	overlay->hwdata->props.viewport.ul.x = overlay->hwdata->CurrentWindow.x;
-	overlay->hwdata->props.viewport.ul.y = overlay->hwdata->CurrentWindow.y;
-	//Next line MIGHT have x and y reversed!!!!!!!!!!!!
-	overlay->hwdata->props.viewport.lr.x = overlay->hwdata->CurrentWindow.x +overlay->hwdata->CurrentWindow.w;
-	overlay->hwdata->props.viewport.lr.y = overlay->hwdata->CurrentWindow.y + overlay->hwdata->CurrentWindow.h;
+        PtGetAbsPosition(window, &pos.x, &pos.y);
+        overlay->hwdata->CurrentWindow.pos.x = pos.x + dstrect->x;
+        overlay->hwdata->CurrentWindow.pos.y = pos.y + dstrect->y;
+        overlay->hwdata->CurrentWindow.size.w = dstrect->w;
+        overlay->hwdata->CurrentWindow.size.h = dstrect->h;
 
-	
-     rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props));
+        PhAreaToRect(&overlay->hwdata->CurrentWindow, &overlay->hwdata->props.viewport);
+
+        rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props));
 
-	switch(rtncode)
-	{
-	case -1:
-		SDL_SetError("PgConfigScalerChannel failed\n");
-		SDL_FreeYUVOverlay(overlay);
-		return(0);
-   		break;
-	case 1:
-		grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
-		break;
-	case 0:
-	default:
-   		break;
-	}
-}
-
+        switch(rtncode)
+        {
+            case -1:
+                     SDL_SetError("PgConfigScalerChannel failed\n");
+                     SDL_FreeYUVOverlay(overlay);
+                     return (0);
+            case 1:
+                     grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
+                     break;
+            case 0:
+            default:
+                     break;
+        }
+    }
 
-//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!
-//	XvShmPutImage(GFX_Display, hwdata->port, SDL_Window, SDL_GC,
-//	              hwdata->image, 0, 0, overlay->w, overlay->h,
-//	              dstrect->x, dstrect->y, dstrect->w, dstrect->h, False);	           
-/*  This is what this call is
-int XvShmPutImage (
-   Display *dpy,
-   XvPortID port,
-   Drawable d,
-   GC gc,
-   XvImage *image,
-   int src_x,
-   int src_y,
-   unsigned int src_w,
-   unsigned int src_h,
-   int dest_x, 
-   int dest_y,
-   unsigned int dest_w,
-   unsigned int dest_h,
-   Bool send_event
-)
-*/
+    if (!overlay->hwdata->locked)
+    {
+        overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
+        if (overlay->hwdata->current == -1)
+        {
+            SDL_SetError("PgNextVideoFrame failed\n");
+            SDL_FreeYUVOverlay(overlay);
+            return 0;
+        }
+        if (overlay->hwdata->current == 0)
+            overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
+        else
+            overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
 
-	return(0);
+        if (overlay->planes > 0)
+        {
+            overlay->pitches[0] = overlay->hwdata->channel->yplane1->pitch;
+            overlay->pixels[0]  = overlay->hwdata->CurrentFrameData->Y;
+        }
+        if (overlay->planes > 1)
+        {
+            overlay->pitches[1] = overlay->hwdata->channel->uplane1->pitch;
+            overlay->pixels[1]  = overlay->hwdata->CurrentFrameData->U;
+        }
+        if (overlay->planes > 2)
+        {
+            overlay->pitches[2] = overlay->hwdata->channel->vplane1->pitch;
+            overlay->pixels[2]  = overlay->hwdata->CurrentFrameData->V;
+        }
+    }
+        
+    return 0;
 }
 
 void ph_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
 {
-	//struct private_yuvhwdata *hwdata;
+    if (overlay == NULL)
+        return;
+
+    if (overlay->hwdata == NULL)
+        return;
 
-	if(overlay == NULL)
-		return;
-	
-	if(overlay->hwdata == NULL)
-		return;
-	
-	overlay->hwdata->State = OVERLAY_STATE_UNINIT;
+    /* it is need for some buggy drivers, that can't hide overlay before */
+    /* freeing buffer, so we got trash on the srceen                     */
+    overlay->hwdata->props.flags &= ~Pg_SCALER_PROP_SCALER_ENABLE;
+    PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props));
+
+    overlay->hwdata->scaler_on = 0;
+    overlay->hwdata->State = OVERLAY_STATE_UNINIT;
 
-	if( overlay->hwdata->channel == NULL )
-	{
-		return;
-	}	
-
-	PgDestroyVideoChannel(overlay->hwdata->channel);
+    if (overlay->hwdata->channel != NULL)
+    {
+        PgDestroyVideoChannel(overlay->hwdata->channel);
+        overlay->hwdata->channel = NULL;
+        return;
+    }	
 
-	overlay->hwdata->channel = NULL;
-	overlay->hwdata->CurrentFrameData = NULL;  
+    overlay->hwdata->CurrentFrameData = NULL;  
 	
-	free(overlay->hwdata->FrameData0);
-	free(overlay->hwdata->FrameData1);
-	overlay->hwdata->FrameData0 = NULL;
-	overlay->hwdata->FrameData1 = NULL;
-	free(overlay->hwdata);
-
+    free(overlay->hwdata->FrameData0);
+    free(overlay->hwdata->FrameData1);
+    overlay->hwdata->FrameData0 = NULL;
+    overlay->hwdata->FrameData1 = NULL;
+    free(overlay->hwdata);
 }