Mercurial > sdl-ios-xcode
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" |