2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2009 Sam Lantinga
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
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 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "SDL_config.h"
24 /* This is the BeOS version of SDL YUV video overlays */
26 #include "SDL_video.h"
27 #include "SDL_sysyuv.h"
28 #include "../SDL_yuvfuncs.h"
32 /* The functions used to manipulate software video overlays */
33 static struct private_yuvhwfuncs be_yuvfuncs =
41 BBitmap * BE_GetOverlayBitmap(BRect bounds, color_space cs) {
43 bbitmap = new BBitmap(bounds,B_BITMAP_WILL_OVERLAY,cs);
44 if (!bbitmap || bbitmap->InitCheck() != B_OK) {
48 overlay_restrictions r;
49 bbitmap->GetOverlayRestrictions(&r);
50 uint32 width = bounds.IntegerWidth() + 1;
51 uint32 height = bounds.IntegerHeight() + 1;
52 uint32 width_padding = 0;
53 uint32 height_padding = 0;
54 if ((r.source.horizontal_alignment != 0) ||
55 (r.source.vertical_alignment != 0)) {
59 if (r.source.width_alignment != 0) {
60 uint32 aligned_width = r.source.width_alignment + 1;
61 if (width % aligned_width > 0) {
62 width_padding = aligned_width - width % aligned_width;
65 if (r.source.height_alignment != 0) {
66 uint32 aligned_height = r.source.height_alignment + 1;
67 if (height % aligned_height > 0) {
68 fprintf(stderr,"GetOverlayBitmap failed height alignment\n");
69 fprintf(stderr,"- height = %lu, aligned_height = %lu\n",height,aligned_height);
74 if ((r.source.min_width > width) ||
75 (r.source.min_height > height) ||
76 (r.source.max_width < width) ||
77 (r.source.max_height < height)) {
78 fprintf(stderr,"GetOverlayBitmap failed bounds tests\n");
82 if ((width_padding != 0) || (height_padding != 0)) {
84 bounds.Set(bounds.left,bounds.top,bounds.right+width_padding,bounds.bottom+height_padding);
85 bbitmap = new BBitmap(bounds,B_BITMAP_WILL_OVERLAY,cs);
86 if (!bbitmap || bbitmap->InitCheck() != B_OK) {
87 fprintf(stderr,"GetOverlayBitmap failed late\n");
95 // See <GraphicsDefs.h> [btw: Cb=U, Cr=V]
96 // See also http://www.fourcc.org/indexyuv.htm
97 color_space convert_color_space(Uint32 format) {
99 case SDL_YV12_OVERLAY:
101 case SDL_IYUV_OVERLAY:
103 case SDL_YUY2_OVERLAY:
105 case SDL_UYVY_OVERLAY:
107 case SDL_YVYU_OVERLAY: // not supported on beos?
108 return B_NO_COLOR_SPACE;
110 return B_NO_COLOR_SPACE;
115 int count_planes(Uint32 format) {
117 case SDL_YV12_OVERLAY:
118 case SDL_IYUV_OVERLAY:
120 case SDL_YUY2_OVERLAY:
121 case SDL_UYVY_OVERLAY:
122 case SDL_YVYU_OVERLAY:
129 SDL_Overlay *BE_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) {
130 SDL_Overlay* overlay;
131 struct private_yuvhwdata* hwdata;
137 /* find the appropriate BeOS colorspace descriptor */
138 cs = convert_color_space(format);
139 if (cs == B_NO_COLOR_SPACE)
145 planes = count_planes(format);
150 /* TODO: figure out planar modes, if anyone cares */
156 /* Create the overlay structure */
157 overlay = (SDL_Overlay*)SDL_calloc(1, sizeof(SDL_Overlay));
165 /* Fill in the basic members */
166 overlay->format = format;
169 overlay->hwdata = NULL;
171 /* Set up the YUV surface function structure */
172 overlay->hwfuncs = &be_yuvfuncs;
174 /* Create the pixel data and lookup tables */
175 hwdata = (struct private_yuvhwdata*)SDL_calloc(1, sizeof(struct private_yuvhwdata));
180 SDL_FreeYUVOverlay(overlay);
184 overlay->hwdata = hwdata;
185 overlay->hwdata->display = display;
186 overlay->hwdata->bview = NULL;
187 overlay->hwdata->bbitmap = NULL;
188 overlay->hwdata->locked = 0;
190 /* Create the BBitmap framebuffer */
191 bounds.top = 0; bounds.left = 0;
192 bounds.right = width-1;
193 bounds.bottom = height-1;
195 BView * bview = new BView(bounds,"overlay",B_FOLLOW_NONE,B_WILL_DRAW);
198 SDL_FreeYUVOverlay(overlay);
201 overlay->hwdata->bview = bview;
202 overlay->hwdata->first_display = true;
205 bbitmap = BE_GetOverlayBitmap(bounds,cs);
207 overlay->hwdata->bbitmap = NULL;
208 SDL_FreeYUVOverlay(overlay);
211 overlay->hwdata->bbitmap = bbitmap;
213 overlay->planes = planes;
214 overlay->pitches = (Uint16*)SDL_calloc(overlay->planes, sizeof(Uint16));
215 overlay->pixels = (Uint8**)SDL_calloc(overlay->planes, sizeof(Uint8*));
216 if (!overlay->pitches || !overlay->pixels)
219 SDL_FreeYUVOverlay(overlay);
223 overlay->pitches[0] = bbitmap->BytesPerRow();
224 overlay->pixels[0] = (Uint8 *)bbitmap->Bits();
225 overlay->hw_overlay = 1;
227 if (SDL_Win->LockWithTimeout(1000000) != B_OK) {
228 SDL_FreeYUVOverlay(overlay);
231 BView * view = SDL_Win->View();
232 view->AddChild(bview);
234 bview->SetViewOverlay(bbitmap,bounds,bview->Bounds(),&key,B_FOLLOW_ALL,
235 B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL);
236 bview->SetViewColor(key);
240 current_overlay=overlay;
245 int BE_LockYUVOverlay(_THIS, SDL_Overlay* overlay)
252 overlay->hwdata->locked = 1;
256 void BE_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay)
263 overlay->hwdata->locked = 0;
266 int BE_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* src, SDL_Rect *dst)
268 if ((overlay == NULL) || (overlay->hwdata==NULL)
269 || (overlay->hwdata->bview==NULL) || (SDL_Win->View() == NULL))
273 if (SDL_Win->LockWithTimeout(50000) != B_OK) {
276 BView * bview = overlay->hwdata->bview;
277 if (SDL_Win->IsFullScreen()) {
279 SDL_Win->GetXYOffset(left,top);
280 bview->MoveTo(left+dst->x,top+dst->y);
282 bview->MoveTo(dst->x,dst->y);
284 bview->ResizeTo(dst->w,dst->h);
286 if (overlay->hwdata->first_display) {
288 overlay->hwdata->first_display = false;
295 void BE_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
302 if (overlay->hwdata == NULL)
307 current_overlay=NULL;
309 delete overlay->hwdata->bbitmap;
311 SDL_free(overlay->hwdata);