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

Commit

Permalink
Overlay functions are being replaced by YUV textures.
Browse files Browse the repository at this point in the history
If the driver doesn't support YUV textures, they can be emulated by backing
the texture with an RGB texture and using the software conversion routines.

Note that it doesn't make sense to lock a portion of a YV12 texture, since
you'd need to return three pixel pointers and pitch values instead of the
one that's available through the API.  I'm guessing that's one of the reasons
DirectX 9 doesn't support this format at all.
  • Loading branch information
slouken committed Jun 11, 2006
1 parent 7bc28b3 commit d97eed4
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 260 deletions.
45 changes: 43 additions & 2 deletions include/SDL_compat.h
Expand Up @@ -79,6 +79,37 @@ typedef struct SDL_VideoInfo
SDL_PixelFormat *vfmt;
} SDL_VideoInfo;

/* The most common video overlay formats.
For an explanation of these pixel formats, see:
http://www.webartz.com/fourcc/indexyuv.htm
For information on the relationship between color spaces, see:
http://www.neuro.sfc.keio.ac.jp/~aly/polygon/info/color-space-faq.html
*/
#define SDL_YV12_OVERLAY 0x32315659 /* Planar mode: Y + V + U (3 planes) */
#define SDL_IYUV_OVERLAY 0x56555949 /* Planar mode: Y + U + V (3 planes) */
#define SDL_YUY2_OVERLAY 0x32595559 /* Packed mode: Y0+U0+Y1+V0 (1 plane) */
#define SDL_UYVY_OVERLAY 0x59565955 /* Packed mode: U0+Y0+V0+Y1 (1 plane) */
#define SDL_YVYU_OVERLAY 0x55595659 /* Packed mode: Y0+V0+Y1+U0 (1 plane) */

/* The YUV hardware video overlay */
typedef struct SDL_Overlay
{
Uint32 format; /* Read-only */
int w, h; /* Read-only */
int planes; /* Read-only */
Uint16 *pitches; /* Read-only */
Uint8 **pixels; /* Read-write */

/* Hardware-specific surface info */
struct private_yuvhwfuncs *hwfuncs;
struct private_yuvhwdata *hwdata;

/* Special flags */
Uint32 hw_overlay:1; /* Flag: This overlay hardware accelerated? */
Uint32 UnusedBits:31;
} SDL_Overlay;

typedef enum
{
SDL_GRAB_QUERY = -1,
Expand Down Expand Up @@ -114,14 +145,25 @@ extern DECLSPEC void SDLCALL SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask);
extern DECLSPEC int SDLCALL SDL_WM_IconifyWindow(void);
extern DECLSPEC int SDLCALL SDL_WM_ToggleFullScreen(SDL_Surface * surface);
extern DECLSPEC SDL_GrabMode SDLCALL SDL_WM_GrabInput(SDL_GrabMode mode);
extern DECLSPEC Uint8 SDLCALL SDL_GetAppState(void);
extern DECLSPEC int SDLCALL SDL_SetPalette(SDL_Surface * surface, int flags,
SDL_Color * colors,
int firstcolor, int ncolors);
extern DECLSPEC int SDLCALL SDL_SetScreenColors(SDL_Surface * screen,
SDL_Color * colors,
int firstcolor, int ncolors);
extern DECLSPEC int SDLCALL SDL_GetWMInfo(SDL_SysWMinfo * info);
extern DECLSPEC Uint8 SDLCALL SDL_GetAppState(void);
extern DECLSPEC void SDLCALL SDL_WarpMouse(Uint16 x, Uint16 y);
extern DECLSPEC SDL_Overlay *SDLCALL SDL_CreateYUVOverlay(int width,
int height,
Uint32 format,
SDL_Surface *
display);
extern DECLSPEC int SDLCALL SDL_LockYUVOverlay(SDL_Overlay * overlay);
extern DECLSPEC void SDLCALL SDL_UnlockYUVOverlay(SDL_Overlay * overlay);
extern DECLSPEC int SDLCALL SDL_DisplayYUVOverlay(SDL_Overlay * overlay,
SDL_Rect * dstrect);
extern DECLSPEC void SDLCALL SDL_FreeYUVOverlay(SDL_Overlay * overlay);

/* Ends C function definitions when using C++ */
#ifdef __cplusplus
Expand All @@ -134,4 +176,3 @@ extern DECLSPEC int SDLCALL SDL_GetWMInfo(SDL_SysWMinfo * info);
#endif /* _SDL_compat_h */

/* vi: set ts=4 sw=4 expandtab: */
extern DECLSPEC void SDLCALL SDL_WarpMouse(Uint16 x, Uint16 y);
9 changes: 9 additions & 0 deletions include/SDL_pixels.h
Expand Up @@ -95,6 +95,9 @@ enum
SDL_PackedLayout_1010102,
};

#define SDL_DEFINE_PIXELFOURCC(A, B, C, D) \
((A) | ((B) << 8) | ((C) << 16) | ((D) << 24))

#define SDL_DEFINE_PIXELFORMAT(type, order, layout, bits, bytes) \
((1 << 31) | ((type) << 24) | ((order) << 20) | ((layout) << 16) | \
((bits) << 8) | ((bytes) << 0))
Expand Down Expand Up @@ -167,6 +170,12 @@ enum
SDL_PixelFormat_ARGB2101010 =
SDL_DEFINE_PIXELFORMAT(SDL_PixelType_Packed32, SDL_PackedOrder_ARGB,
SDL_PackedLayout_2101010, 32, 4),

SDL_PixelFormat_YV12 = SDL_DEFINE_PIXELFOURCC('Y', 'V', '1', '2'),
SDL_PixelFormat_IYUV = SDL_DEFINE_PIXELFOURCC('I', 'Y', 'U', 'V'),
SDL_PixelFormat_YUY2 = SDL_DEFINE_PIXELFOURCC('Y', 'U', 'Y', '2'),
SDL_PixelFormat_UYVY = SDL_DEFINE_PIXELFOURCC('U', 'Y', 'V', 'Y'),
SDL_PixelFormat_YVYU = SDL_DEFINE_PIXELFOURCC('Y', 'V', 'Y', 'U'),
};

typedef struct SDL_Color
Expand Down
64 changes: 0 additions & 64 deletions include/SDL_video.h
Expand Up @@ -274,37 +274,6 @@ typedef int (*SDL_blit) (struct SDL_Surface * src, SDL_Rect * srcrect,
struct SDL_Surface * dst, SDL_Rect * dstrect);


/* The most common video overlay formats.
For an explanation of these pixel formats, see:
http://www.webartz.com/fourcc/indexyuv.htm
For information on the relationship between color spaces, see:
http://www.neuro.sfc.keio.ac.jp/~aly/polygon/info/color-space-faq.html
*/
#define SDL_YV12_OVERLAY 0x32315659 /* Planar mode: Y + V + U (3 planes) */
#define SDL_IYUV_OVERLAY 0x56555949 /* Planar mode: Y + U + V (3 planes) */
#define SDL_YUY2_OVERLAY 0x32595559 /* Packed mode: Y0+U0+Y1+V0 (1 plane) */
#define SDL_UYVY_OVERLAY 0x59565955 /* Packed mode: U0+Y0+V0+Y1 (1 plane) */
#define SDL_YVYU_OVERLAY 0x55595659 /* Packed mode: Y0+V0+Y1+U0 (1 plane) */

/* The YUV hardware video overlay */
typedef struct SDL_Overlay
{
Uint32 format; /* Read-only */
int w, h; /* Read-only */
int planes; /* Read-only */
Uint16 *pitches; /* Read-only */
Uint8 **pixels; /* Read-write */

/* Hardware-specific surface info */
struct private_yuvhwfuncs *hwfuncs;
struct private_yuvhwdata *hwdata;

/* Special flags */
Uint32 hw_overlay:1; /* Flag: This overlay hardware accelerated? */
Uint32 UnusedBits:31;
} SDL_Overlay;

/**
* \enum SDL_GLattr
*
Expand Down Expand Up @@ -1341,39 +1310,6 @@ extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface * src,
SDL_Surface * dst,
SDL_Rect * dstrect);


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* YUV video surface overlay functions */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/* This function creates a video output overlay
Calling the returned surface an overlay is something of a misnomer because
the contents of the display surface underneath the area where the overlay
is shown is undefined - it may be overwritten with the converted YUV data.
*/
extern DECLSPEC SDL_Overlay *SDLCALL SDL_CreateYUVOverlay(int width,
int height,
Uint32 format,
SDL_Surface *
display);

/* Lock an overlay for direct access, and unlock it when you are done */
extern DECLSPEC int SDLCALL SDL_LockYUVOverlay(SDL_Overlay * overlay);
extern DECLSPEC void SDLCALL SDL_UnlockYUVOverlay(SDL_Overlay * overlay);

/* Blit a video overlay to the display surface.
The contents of the video surface underneath the blit destination are
not defined.
The width and height of the destination rectangle may be different from
that of the overlay, but currently only 2x scaling is supported.
*/
extern DECLSPEC int SDLCALL SDL_DisplayYUVOverlay(SDL_Overlay * overlay,
SDL_Rect * dstrect);

/* Free a video overlay */
extern DECLSPEC void SDLCALL SDL_FreeYUVOverlay(SDL_Overlay * overlay);


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* OpenGL support functions. */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Expand Down
115 changes: 115 additions & 0 deletions src/SDL_compat.c
Expand Up @@ -1235,4 +1235,119 @@ SDL_ResetCursor(void)
}
}

SDL_Overlay *
SDL_CreateYUVOverlay(int w, int h, Uint32 format, SDL_Surface * display)
{
SDL_VideoDevice *_this = SDL_GetVideoDevice();
SDL_Window *window;
const char *yuv_hwaccel;
SDL_Overlay *overlay;

window = SDL_GetWindowFromSurface(display);
if (window && (window->flags & SDL_WINDOW_OPENGL)) {
SDL_SetError("YUV overlays are not supported in OpenGL mode");
return NULL;
}

/* Display directly on video surface, if possible */
if (SDL_getenv("SDL_VIDEO_YUV_DIRECT")) {
if (window &&
((window->surface->format->BytesPerPixel == 2) ||
(window->surface->format->BytesPerPixel == 4))) {
display = window->surface;
}
}
overlay = NULL;
yuv_hwaccel = SDL_getenv("SDL_VIDEO_YUV_HWACCEL");
if (((display->flags & SDL_SCREEN_SURFACE) && _this->CreateYUVOverlay) &&
(!yuv_hwaccel || (SDL_atoi(yuv_hwaccel) > 0))) {
overlay = _this->CreateYUVOverlay(_this, w, h, format, display);
}
/* If hardware YUV overlay failed ... */
if (overlay == NULL) {
overlay = SDL_CreateYUV_SW(_this, w, h, format, display);
}
return overlay;
}

int
SDL_LockYUVOverlay(SDL_Overlay * overlay)
{
SDL_VideoDevice *_this = SDL_GetVideoDevice();
return overlay->hwfuncs->Lock(_this, overlay);
}

void
SDL_UnlockYUVOverlay(SDL_Overlay * overlay)
{
SDL_VideoDevice *_this = SDL_GetVideoDevice();
overlay->hwfuncs->Unlock(_this, overlay);
}

int
SDL_DisplayYUVOverlay(SDL_Overlay * overlay, SDL_Rect * dstrect)
{
SDL_VideoDevice *_this = SDL_GetVideoDevice();
SDL_Rect src, dst;
int srcx, srcy, srcw, srch;
int dstx, dsty, dstw, dsth;

/* Clip the rectangle to the screen area */
srcx = 0;
srcy = 0;
srcw = overlay->w;
srch = overlay->h;
dstx = dstrect->x;
dsty = dstrect->y;
dstw = dstrect->w;
dsth = dstrect->h;
if (dstx < 0) {
srcw += (dstx * overlay->w) / dstrect->w;
dstw += dstx;
srcx -= (dstx * overlay->w) / dstrect->w;
dstx = 0;
}
if ((dstx + dstw) > SDL_VideoSurface->w) {
int extra = (dstx + dstw - SDL_VideoSurface->w);
srcw -= (extra * overlay->w) / dstrect->w;
dstw -= extra;
}
if (dsty < 0) {
srch += (dsty * overlay->h) / dstrect->h;
dsth += dsty;
srcy -= (dsty * overlay->h) / dstrect->h;
dsty = 0;
}
if ((dsty + dsth) > SDL_VideoSurface->h) {
int extra = (dsty + dsth - SDL_VideoSurface->h);
srch -= (extra * overlay->h) / dstrect->h;
dsth -= extra;
}
if (srcw <= 0 || srch <= 0 || srch <= 0 || dsth <= 0) {
return 0;
}
/* Ugh, I can't wait for SDL_Rect to be int values */
src.x = srcx;
src.y = srcy;
src.w = srcw;
src.h = srch;
dst.x = dstx;
dst.y = dsty;
dst.w = dstw;
dst.h = dsth;
return overlay->hwfuncs->Display(_this, overlay, &src, &dst);
}

void
SDL_FreeYUVOverlay(SDL_Overlay * overlay)
{
SDL_VideoDevice *_this = SDL_GetVideoDevice();
if (overlay) {
if (overlay->hwfuncs) {
overlay->hwfuncs->FreeHW(_this, overlay);
}
SDL_free(overlay);
}
}

/* vi: set ts=4 sw=4 expandtab: */
7 changes: 0 additions & 7 deletions src/video/SDL_sysvideo.h
Expand Up @@ -200,13 +200,6 @@ struct SDL_VideoDevice
SDL_bool(*GetWindowWMInfo) (_THIS, SDL_Window * window,
SDL_SysWMinfo * info);

/* Create a YUV video surface (possibly overlay) of the given
format. The hardware should be able to perform at least 2x
scaling on display.
*/
SDL_Overlay *(*CreateYUVOverlay) (_THIS, int width, int height,
Uint32 format, SDL_Surface * display);

/* Reverse the effects VideoInit() -- called if VideoInit() fails
or if the application is shutting down the video subsystem.
*/
Expand Down

0 comments on commit d97eed4

Please sign in to comment.