src/video/bwindow/SDL_sysyuv.cc
author Sam Lantinga <slouken@libsdl.org>
Tue, 17 Mar 2009 03:58:53 +0000
branchSDL-1.2
changeset 4164 7a4c511c980a
parent 4159 a1b03ba2fcd0
child 6137 4720145f848b
permissions -rw-r--r--
Date: Fri, 6 Mar 2009 12:41:17 -0800
From: scott mc
Subject: Re: [SDL] patch for building on haiku

Ok. I've combined the various Haiku patches for the SDL-1.2 branch
into one .diff file
slouken@756
     1
/*
slouken@756
     2
    SDL - Simple DirectMedia Layer
slouken@4159
     3
    Copyright (C) 1997-2009 Sam Lantinga
slouken@756
     4
slouken@756
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@756
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@756
     9
slouken@756
    10
    This library is distributed in the hope that it will be useful,
slouken@756
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@756
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@756
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@756
    18
slouken@756
    19
    Sam Lantinga
slouken@756
    20
    slouken@libsdl.org
slouken@756
    21
*/
slouken@1403
    22
#include "SDL_config.h"
slouken@756
    23
slouken@756
    24
/* This is the BeOS version of SDL YUV video overlays */
slouken@756
    25
slouken@756
    26
#include "SDL_video.h"
slouken@756
    27
#include "SDL_sysyuv.h"
slouken@1361
    28
#include "../SDL_yuvfuncs.h"
slouken@756
    29
slouken@756
    30
extern "C" {
slouken@756
    31
slouken@756
    32
/* The functions used to manipulate software video overlays */
slouken@756
    33
static struct private_yuvhwfuncs be_yuvfuncs =
slouken@756
    34
{
slouken@756
    35
    BE_LockYUVOverlay,
slouken@756
    36
    BE_UnlockYUVOverlay,
slouken@756
    37
    BE_DisplayYUVOverlay,
slouken@756
    38
    BE_FreeYUVOverlay
slouken@756
    39
};
slouken@756
    40
slouken@756
    41
BBitmap * BE_GetOverlayBitmap(BRect bounds, color_space cs) {
slouken@756
    42
	BBitmap *bbitmap;
slouken@756
    43
	bbitmap = new BBitmap(bounds,B_BITMAP_WILL_OVERLAY,cs);
slouken@756
    44
	if (!bbitmap || bbitmap->InitCheck() != B_OK) {
slouken@756
    45
		delete bbitmap;
slouken@756
    46
		return 0;
slouken@756
    47
	}
slouken@756
    48
	overlay_restrictions r;
slouken@756
    49
	bbitmap->GetOverlayRestrictions(&r);
slouken@756
    50
	uint32 width = bounds.IntegerWidth() + 1;
slouken@756
    51
	uint32 height = bounds.IntegerHeight() + 1;
slouken@756
    52
	uint32 width_padding = 0;
slouken@756
    53
	uint32 height_padding = 0;
slouken@756
    54
	if ((r.source.horizontal_alignment != 0) ||
slouken@756
    55
	    (r.source.vertical_alignment != 0)) {
slouken@756
    56
		delete bbitmap;
slouken@756
    57
		return 0;
slouken@756
    58
	}
slouken@756
    59
	if (r.source.width_alignment != 0) {
slouken@756
    60
		uint32 aligned_width = r.source.width_alignment + 1;
slouken@756
    61
		if (width % aligned_width > 0) {
slouken@756
    62
			width_padding = aligned_width - width % aligned_width;
slouken@756
    63
		}
slouken@756
    64
	}
slouken@756
    65
	if (r.source.height_alignment != 0) {
slouken@756
    66
		uint32 aligned_height = r.source.height_alignment + 1;
slouken@756
    67
		if (height % aligned_height > 0) {
slouken@756
    68
			fprintf(stderr,"GetOverlayBitmap failed height alignment\n");
slouken@756
    69
			fprintf(stderr,"- height = %lu, aligned_height = %lu\n",height,aligned_height);
slouken@756
    70
			delete bbitmap;
slouken@756
    71
			return 0;
slouken@756
    72
		}
slouken@756
    73
	}
slouken@756
    74
	if ((r.source.min_width > width) ||
slouken@756
    75
	    (r.source.min_height > height) ||
slouken@756
    76
	    (r.source.max_width < width) ||
slouken@756
    77
	    (r.source.max_height < height)) {
slouken@756
    78
		fprintf(stderr,"GetOverlayBitmap failed bounds tests\n");
slouken@756
    79
	    delete bbitmap;
slouken@756
    80
	    return 0;
slouken@756
    81
	}
slouken@756
    82
	if ((width_padding != 0) || (height_padding != 0)) {
slouken@756
    83
		delete bbitmap;
slouken@756
    84
		bounds.Set(bounds.left,bounds.top,bounds.right+width_padding,bounds.bottom+height_padding);
slouken@756
    85
		bbitmap = new BBitmap(bounds,B_BITMAP_WILL_OVERLAY,cs);
slouken@756
    86
		if (!bbitmap || bbitmap->InitCheck() != B_OK) {
slouken@756
    87
			fprintf(stderr,"GetOverlayBitmap failed late\n");
slouken@756
    88
			delete bbitmap;
slouken@756
    89
			return 0;
slouken@756
    90
		}
slouken@756
    91
	}		
slouken@756
    92
	return bbitmap;	    
slouken@756
    93
}
slouken@756
    94
slouken@756
    95
// See <GraphicsDefs.h> [btw: Cb=U, Cr=V]
slouken@756
    96
// See also http://www.fourcc.org/indexyuv.htm
slouken@4164
    97
color_space convert_color_space(Uint32 format) {
slouken@756
    98
	switch (format) {
slouken@756
    99
	case SDL_YV12_OVERLAY:
slouken@756
   100
		return B_YUV9;
slouken@756
   101
	case SDL_IYUV_OVERLAY:
slouken@756
   102
		return B_YUV12;
slouken@756
   103
	case SDL_YUY2_OVERLAY:
slouken@756
   104
		return B_YCbCr422;
slouken@756
   105
	case SDL_UYVY_OVERLAY:
slouken@756
   106
		return B_YUV422;
slouken@756
   107
	case SDL_YVYU_OVERLAY: // not supported on beos?
slouken@756
   108
		return B_NO_COLOR_SPACE;
slouken@756
   109
	default:
slouken@756
   110
		return B_NO_COLOR_SPACE;
slouken@756
   111
	}
slouken@756
   112
}
slouken@756
   113
slouken@756
   114
// See SDL_video.h
slouken@756
   115
int count_planes(Uint32 format) {
slouken@756
   116
	switch (format) {
slouken@756
   117
	case SDL_YV12_OVERLAY:
slouken@756
   118
	case SDL_IYUV_OVERLAY:
slouken@756
   119
		return 3;
slouken@756
   120
	case SDL_YUY2_OVERLAY:
slouken@756
   121
	case SDL_UYVY_OVERLAY:
slouken@756
   122
	case SDL_YVYU_OVERLAY:
slouken@756
   123
		return 1;
slouken@756
   124
	default:
slouken@756
   125
		return 0;
slouken@756
   126
	}
slouken@756
   127
}		
slouken@756
   128
slouken@756
   129
SDL_Overlay *BE_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) {
slouken@756
   130
	SDL_Overlay* overlay;
slouken@756
   131
	struct private_yuvhwdata* hwdata;
slouken@756
   132
	BBitmap *bbitmap;
slouken@756
   133
	int planes;
slouken@756
   134
	BRect bounds;
slouken@756
   135
	color_space cs;
slouken@756
   136
	
slouken@756
   137
	/* find the appropriate BeOS colorspace descriptor */
slouken@756
   138
	cs = convert_color_space(format);
slouken@756
   139
	if (cs == B_NO_COLOR_SPACE)
slouken@756
   140
	{
slouken@756
   141
		return NULL;
slouken@756
   142
	}
slouken@756
   143
	
slouken@756
   144
	/* count planes */
slouken@756
   145
	planes = count_planes(format);
slouken@756
   146
	if (planes == 0)
slouken@756
   147
	{
slouken@756
   148
		return NULL;
slouken@756
   149
	}
slouken@756
   150
	/* TODO: figure out planar modes, if anyone cares */
slouken@756
   151
	if (planes == 3)
slouken@756
   152
	{
slouken@756
   153
		return NULL;
slouken@756
   154
	}
slouken@756
   155
slouken@756
   156
    /* Create the overlay structure */
slouken@1338
   157
    overlay = (SDL_Overlay*)SDL_calloc(1, sizeof(SDL_Overlay));
slouken@756
   158
slouken@756
   159
    if (overlay == NULL)
slouken@756
   160
    {
slouken@756
   161
        SDL_OutOfMemory();
slouken@756
   162
        return NULL;
slouken@756
   163
    }
slouken@756
   164
slouken@756
   165
    /* Fill in the basic members */
slouken@756
   166
    overlay->format = format;
slouken@756
   167
    overlay->w = width;
slouken@756
   168
    overlay->h = height;
slouken@756
   169
    overlay->hwdata = NULL;
slouken@756
   170
	
slouken@756
   171
    /* Set up the YUV surface function structure */
slouken@756
   172
    overlay->hwfuncs = &be_yuvfuncs;
slouken@756
   173
slouken@756
   174
    /* Create the pixel data and lookup tables */
slouken@1338
   175
    hwdata = (struct private_yuvhwdata*)SDL_calloc(1, sizeof(struct private_yuvhwdata));
slouken@756
   176
slouken@756
   177
    if (hwdata == NULL)
slouken@756
   178
    {
slouken@756
   179
        SDL_OutOfMemory();
slouken@756
   180
        SDL_FreeYUVOverlay(overlay);
slouken@756
   181
        return NULL;
slouken@756
   182
    }
slouken@756
   183
slouken@756
   184
    overlay->hwdata = hwdata;
slouken@756
   185
	overlay->hwdata->display = display;
slouken@756
   186
	overlay->hwdata->bview = NULL;
slouken@756
   187
	overlay->hwdata->bbitmap = NULL;
slouken@756
   188
	overlay->hwdata->locked = 0;
slouken@756
   189
slouken@756
   190
	/* Create the BBitmap framebuffer */
slouken@756
   191
	bounds.top = 0;	bounds.left = 0;
slouken@756
   192
	bounds.right = width-1;
slouken@756
   193
	bounds.bottom = height-1;
slouken@756
   194
	
slouken@756
   195
	BView * bview = new BView(bounds,"overlay",B_FOLLOW_NONE,B_WILL_DRAW); 
slouken@756
   196
	if (!bview) {
slouken@756
   197
		SDL_OutOfMemory();
slouken@756
   198
        SDL_FreeYUVOverlay(overlay);
slouken@756
   199
        return NULL;
slouken@756
   200
	}
slouken@756
   201
	overlay->hwdata->bview = bview;
slouken@756
   202
	overlay->hwdata->first_display = true;
slouken@756
   203
	bview->Hide();
slouken@756
   204
	
slouken@756
   205
	bbitmap = BE_GetOverlayBitmap(bounds,cs);
slouken@756
   206
	if (!bbitmap) {
slouken@756
   207
		overlay->hwdata->bbitmap = NULL;
slouken@756
   208
		SDL_FreeYUVOverlay(overlay);
slouken@756
   209
		return NULL;
slouken@756
   210
	}
slouken@756
   211
	overlay->hwdata->bbitmap = bbitmap;
slouken@756
   212
	
slouken@756
   213
	overlay->planes = planes;
slouken@1338
   214
	overlay->pitches = (Uint16*)SDL_calloc(overlay->planes, sizeof(Uint16));
slouken@1338
   215
	overlay->pixels  = (Uint8**)SDL_calloc(overlay->planes, sizeof(Uint8*));
slouken@756
   216
	if (!overlay->pitches || !overlay->pixels)
slouken@756
   217
	{
slouken@756
   218
        SDL_OutOfMemory();
slouken@756
   219
        SDL_FreeYUVOverlay(overlay);
slouken@756
   220
        return(NULL);
slouken@756
   221
    }
slouken@756
   222
slouken@756
   223
   	overlay->pitches[0] = bbitmap->BytesPerRow();
slouken@756
   224
   	overlay->pixels[0]  = (Uint8 *)bbitmap->Bits();
slouken@756
   225
	overlay->hw_overlay = 1;
slouken@756
   226
	
slouken@756
   227
	if (SDL_Win->LockWithTimeout(1000000) != B_OK) {
slouken@756
   228
        SDL_FreeYUVOverlay(overlay);
slouken@756
   229
        return(NULL);
slouken@756
   230
    }
slouken@756
   231
	BView * view = SDL_Win->View();
slouken@756
   232
    view->AddChild(bview);
slouken@756
   233
    rgb_color key;
slouken@756
   234
    bview->SetViewOverlay(bbitmap,bounds,bview->Bounds(),&key,B_FOLLOW_ALL,
slouken@756
   235
                         B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL);
slouken@756
   236
    bview->SetViewColor(key);
slouken@756
   237
    bview->Flush();
slouken@756
   238
	SDL_Win->Unlock();
slouken@756
   239
	
slouken@756
   240
	current_overlay=overlay;
slouken@756
   241
        
slouken@756
   242
	return overlay;
slouken@756
   243
}
slouken@756
   244
slouken@756
   245
int BE_LockYUVOverlay(_THIS, SDL_Overlay* overlay)
slouken@756
   246
{
slouken@756
   247
    if (overlay == NULL)
slouken@756
   248
    {
slouken@756
   249
        return 0;
slouken@756
   250
    }
slouken@756
   251
slouken@756
   252
    overlay->hwdata->locked = 1;
slouken@756
   253
    return 0;
slouken@756
   254
}
slouken@756
   255
slouken@756
   256
void BE_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay)
slouken@756
   257
{
slouken@756
   258
    if (overlay == NULL)
slouken@756
   259
    {
slouken@756
   260
         return;
slouken@756
   261
    }
slouken@756
   262
slouken@756
   263
    overlay->hwdata->locked = 0;
slouken@756
   264
}
slouken@756
   265
slouken@1643
   266
int BE_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* src, SDL_Rect *dst)
slouken@756
   267
{
slouken@756
   268
    if ((overlay == NULL) || (overlay->hwdata==NULL)
slouken@756
   269
        || (overlay->hwdata->bview==NULL) || (SDL_Win->View() == NULL))
slouken@756
   270
    {
slouken@756
   271
        return -1;
slouken@756
   272
    }
slouken@756
   273
    if (SDL_Win->LockWithTimeout(50000) != B_OK) {
slouken@756
   274
        return 0;
slouken@756
   275
    }
slouken@756
   276
    BView * bview = overlay->hwdata->bview;
slouken@4012
   277
    if (SDL_Win->IsFullScreen()) {
slouken@4012
   278
    	int left,top;
slouken@4012
   279
    	SDL_Win->GetXYOffset(left,top);
slouken@4012
   280
	    bview->MoveTo(left+dst->x,top+dst->y);
slouken@4012
   281
    } else {
slouken@4012
   282
	    bview->MoveTo(dst->x,dst->y);
slouken@4012
   283
    }
slouken@1643
   284
    bview->ResizeTo(dst->w,dst->h);
slouken@756
   285
    bview->Flush();
slouken@756
   286
	if (overlay->hwdata->first_display) {
slouken@756
   287
		bview->Show();
slouken@756
   288
		overlay->hwdata->first_display = false;
slouken@756
   289
	}
slouken@756
   290
    SDL_Win->Unlock();
slouken@756
   291
    
slouken@756
   292
	return 0;
slouken@756
   293
}
slouken@756
   294
slouken@756
   295
void BE_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
slouken@756
   296
{
slouken@756
   297
    if (overlay == NULL)
slouken@756
   298
    {
slouken@756
   299
        return;
slouken@756
   300
    }
slouken@756
   301
slouken@756
   302
    if (overlay->hwdata == NULL)
slouken@756
   303
    {
slouken@756
   304
        return;
slouken@756
   305
    }
slouken@756
   306
slouken@756
   307
    current_overlay=NULL;
slouken@756
   308
slouken@756
   309
	delete overlay->hwdata->bbitmap;
slouken@756
   310
slouken@1336
   311
    SDL_free(overlay->hwdata);
slouken@756
   312
}
slouken@756
   313
slouken@756
   314
}; // extern "C"