comparison src/video/bwindow/SDL_sysyuv.cc @ 756:10332c6fad2e

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