comparison src/video/bwindow/SDL_sysyuv.cc @ 1662:782fd950bd46 SDL-1.3

Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API. WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid. The code is now run through a consistent indent format: indent -i4 -nut -nsc -br -ce The headers are being converted to automatically generate doxygen documentation.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 28 May 2006 13:04:16 +0000
parents 51038e80ae59
children 4da1ee79c9af
comparison
equal deleted inserted replaced
1661:281d3f4870e5 1662:782fd950bd46
25 25
26 #include "SDL_video.h" 26 #include "SDL_video.h"
27 #include "SDL_sysyuv.h" 27 #include "SDL_sysyuv.h"
28 #include "../SDL_yuvfuncs.h" 28 #include "../SDL_yuvfuncs.h"
29 29
30 extern "C" { 30 extern "C"
31 {
31 32
32 /* The functions used to manipulate software video overlays */ 33 /* The functions used to manipulate software video overlays */
33 static struct private_yuvhwfuncs be_yuvfuncs = 34 static struct private_yuvhwfuncs be_yuvfuncs = {
34 { 35 BE_LockYUVOverlay,
35 BE_LockYUVOverlay, 36 BE_UnlockYUVOverlay,
36 BE_UnlockYUVOverlay, 37 BE_DisplayYUVOverlay,
37 BE_DisplayYUVOverlay, 38 BE_FreeYUVOverlay
38 BE_FreeYUVOverlay 39 };
39 }; 40
40 41 BBitmap *BE_GetOverlayBitmap (BRect bounds, color_space cs)
41 BBitmap * BE_GetOverlayBitmap(BRect bounds, color_space cs) { 42 {
42 BBitmap *bbitmap; 43 BBitmap *bbitmap;
43 bbitmap = new BBitmap(bounds,B_BITMAP_WILL_OVERLAY,cs); 44 bbitmap = new BBitmap (bounds, B_BITMAP_WILL_OVERLAY, cs);
44 if (!bbitmap || bbitmap->InitCheck() != B_OK) { 45 if (!bbitmap || bbitmap->InitCheck () != B_OK) {
45 delete bbitmap; 46 delete bbitmap;
46 return 0; 47 return 0;
47 } 48 }
48 overlay_restrictions r; 49 overlay_restrictions r;
49 bbitmap->GetOverlayRestrictions(&r); 50 bbitmap->GetOverlayRestrictions (&r);
50 uint32 width = bounds.IntegerWidth() + 1; 51 uint32 width = bounds.IntegerWidth () + 1;
51 uint32 height = bounds.IntegerHeight() + 1; 52 uint32 height = bounds.IntegerHeight () + 1;
52 uint32 width_padding = 0; 53 uint32 width_padding = 0;
53 uint32 height_padding = 0; 54 uint32 height_padding = 0;
54 if ((r.source.horizontal_alignment != 0) || 55 if ((r.source.horizontal_alignment != 0) ||
55 (r.source.vertical_alignment != 0)) { 56 (r.source.vertical_alignment != 0)) {
56 delete bbitmap; 57 delete bbitmap;
57 return 0; 58 return 0;
58 } 59 }
59 if (r.source.width_alignment != 0) { 60 if (r.source.width_alignment != 0) {
60 uint32 aligned_width = r.source.width_alignment + 1; 61 uint32 aligned_width = r.source.width_alignment + 1;
61 if (width % aligned_width > 0) { 62 if (width % aligned_width > 0) {
62 width_padding = aligned_width - width % aligned_width; 63 width_padding = aligned_width - width % aligned_width;
63 } 64 }
64 } 65 }
65 if (r.source.height_alignment != 0) { 66 if (r.source.height_alignment != 0) {
66 uint32 aligned_height = r.source.height_alignment + 1; 67 uint32 aligned_height = r.source.height_alignment + 1;
67 if (height % aligned_height > 0) { 68 if (height % aligned_height > 0) {
68 fprintf(stderr,"GetOverlayBitmap failed height alignment\n"); 69 fprintf (stderr,
69 fprintf(stderr,"- height = %lu, aligned_height = %lu\n",height,aligned_height); 70 "GetOverlayBitmap failed height alignment\n");
70 delete bbitmap; 71 fprintf (stderr, "- height = %lu, aligned_height = %lu\n",
71 return 0; 72 height, aligned_height);
72 } 73 delete bbitmap;
73 } 74 return 0;
74 if ((r.source.min_width > width) || 75 }
75 (r.source.min_height > height) || 76 }
76 (r.source.max_width < width) || 77 if ((r.source.min_width > width) ||
77 (r.source.max_height < height)) { 78 (r.source.min_height > height) ||
78 fprintf(stderr,"GetOverlayBitmap failed bounds tests\n"); 79 (r.source.max_width < width) || (r.source.max_height < height)) {
79 delete bbitmap; 80 fprintf (stderr, "GetOverlayBitmap failed bounds tests\n");
80 return 0; 81 delete bbitmap;
81 } 82 return 0;
82 if ((width_padding != 0) || (height_padding != 0)) { 83 }
83 delete bbitmap; 84 if ((width_padding != 0) || (height_padding != 0)) {
84 bounds.Set(bounds.left,bounds.top,bounds.right+width_padding,bounds.bottom+height_padding); 85 delete bbitmap;
85 bbitmap = new BBitmap(bounds,B_BITMAP_WILL_OVERLAY,cs); 86 bounds.Set (bounds.left, bounds.top,
86 if (!bbitmap || bbitmap->InitCheck() != B_OK) { 87 bounds.right + width_padding,
87 fprintf(stderr,"GetOverlayBitmap failed late\n"); 88 bounds.bottom + height_padding);
88 delete bbitmap; 89 bbitmap = new BBitmap (bounds, B_BITMAP_WILL_OVERLAY, cs);
89 return 0; 90 if (!bbitmap || bbitmap->InitCheck () != B_OK) {
90 } 91 fprintf (stderr, "GetOverlayBitmap failed late\n");
91 } 92 delete bbitmap;
92 return bbitmap; 93 return 0;
93 } 94 }
95 }
96 return bbitmap;
97 }
94 98
95 // See <GraphicsDefs.h> [btw: Cb=U, Cr=V] 99 // See <GraphicsDefs.h> [btw: Cb=U, Cr=V]
96 // See also http://www.fourcc.org/indexyuv.htm 100 // See also http://www.fourcc.org/indexyuv.htm
97 enum color_space convert_color_space(Uint32 format) { 101 enum color_space convert_color_space (Uint32 format)
98 switch (format) { 102 {
99 case SDL_YV12_OVERLAY: 103 switch (format) {
100 return B_YUV9; 104 case SDL_YV12_OVERLAY:
101 case SDL_IYUV_OVERLAY: 105 return B_YUV9;
102 return B_YUV12; 106 case SDL_IYUV_OVERLAY:
103 case SDL_YUY2_OVERLAY: 107 return B_YUV12;
104 return B_YCbCr422; 108 case SDL_YUY2_OVERLAY:
105 case SDL_UYVY_OVERLAY: 109 return B_YCbCr422;
106 return B_YUV422; 110 case SDL_UYVY_OVERLAY:
107 case SDL_YVYU_OVERLAY: // not supported on beos? 111 return B_YUV422;
108 return B_NO_COLOR_SPACE; 112 case SDL_YVYU_OVERLAY: // not supported on beos?
109 default: 113 return B_NO_COLOR_SPACE;
110 return B_NO_COLOR_SPACE; 114 default:
111 } 115 return B_NO_COLOR_SPACE;
112 } 116 }
117 }
113 118
114 // See SDL_video.h 119 // See SDL_video.h
115 int count_planes(Uint32 format) { 120 int count_planes (Uint32 format)
116 switch (format) { 121 {
117 case SDL_YV12_OVERLAY: 122 switch (format) {
118 case SDL_IYUV_OVERLAY: 123 case SDL_YV12_OVERLAY:
119 return 3; 124 case SDL_IYUV_OVERLAY:
120 case SDL_YUY2_OVERLAY: 125 return 3;
121 case SDL_UYVY_OVERLAY: 126 case SDL_YUY2_OVERLAY:
122 case SDL_YVYU_OVERLAY: 127 case SDL_UYVY_OVERLAY:
123 return 1; 128 case SDL_YVYU_OVERLAY:
124 default: 129 return 1;
125 return 0; 130 default:
126 } 131 return 0;
127 } 132 }
128 133 }
129 SDL_Overlay *BE_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) { 134
130 SDL_Overlay* overlay; 135 SDL_Overlay *BE_CreateYUVOverlay (_THIS, int width, int height,
131 struct private_yuvhwdata* hwdata; 136 Uint32 format, SDL_Surface * display)
132 BBitmap *bbitmap; 137 {
133 int planes; 138 SDL_Overlay *overlay;
134 BRect bounds; 139 struct private_yuvhwdata *hwdata;
135 color_space cs; 140 BBitmap *bbitmap;
136 141 int planes;
137 /* find the appropriate BeOS colorspace descriptor */ 142 BRect bounds;
138 cs = convert_color_space(format); 143 color_space cs;
139 if (cs == B_NO_COLOR_SPACE) 144
140 { 145 /* find the appropriate BeOS colorspace descriptor */
141 return NULL; 146 cs = convert_color_space (format);
142 } 147 if (cs == B_NO_COLOR_SPACE) {
143 148 return NULL;
144 /* count planes */ 149 }
145 planes = count_planes(format); 150
146 if (planes == 0) 151 /* count planes */
147 { 152 planes = count_planes (format);
148 return NULL; 153 if (planes == 0) {
149 } 154 return NULL;
150 /* TODO: figure out planar modes, if anyone cares */ 155 }
151 if (planes == 3) 156 /* TODO: figure out planar modes, if anyone cares */
152 { 157 if (planes == 3) {
153 return NULL; 158 return NULL;
154 } 159 }
155 160
156 /* Create the overlay structure */ 161 /* Create the overlay structure */
157 overlay = (SDL_Overlay*)SDL_calloc(1, sizeof(SDL_Overlay)); 162 overlay = (SDL_Overlay *) SDL_calloc (1, sizeof (SDL_Overlay));
158 163
159 if (overlay == NULL) 164 if (overlay == NULL) {
160 { 165 SDL_OutOfMemory ();
161 SDL_OutOfMemory(); 166 return NULL;
162 return NULL; 167 }
163 } 168
164 169 /* Fill in the basic members */
165 /* Fill in the basic members */ 170 overlay->format = format;
166 overlay->format = format; 171 overlay->w = width;
167 overlay->w = width; 172 overlay->h = height;
168 overlay->h = height; 173 overlay->hwdata = NULL;
169 overlay->hwdata = NULL; 174
170 175 /* Set up the YUV surface function structure */
171 /* Set up the YUV surface function structure */ 176 overlay->hwfuncs = &be_yuvfuncs;
172 overlay->hwfuncs = &be_yuvfuncs; 177
173 178 /* Create the pixel data and lookup tables */
174 /* Create the pixel data and lookup tables */ 179 hwdata =
175 hwdata = (struct private_yuvhwdata*)SDL_calloc(1, sizeof(struct private_yuvhwdata)); 180 (struct private_yuvhwdata *) SDL_calloc (1,
176 181 sizeof (struct
177 if (hwdata == NULL) 182 private_yuvhwdata));
178 { 183
179 SDL_OutOfMemory(); 184 if (hwdata == NULL) {
180 SDL_FreeYUVOverlay(overlay); 185 SDL_OutOfMemory ();
181 return NULL; 186 SDL_FreeYUVOverlay (overlay);
182 } 187 return NULL;
183 188 }
184 overlay->hwdata = hwdata; 189
185 overlay->hwdata->display = display; 190 overlay->hwdata = hwdata;
186 overlay->hwdata->bview = NULL; 191 overlay->hwdata->display = display;
187 overlay->hwdata->bbitmap = NULL; 192 overlay->hwdata->bview = NULL;
188 overlay->hwdata->locked = 0; 193 overlay->hwdata->bbitmap = NULL;
189 194 overlay->hwdata->locked = 0;
190 /* Create the BBitmap framebuffer */ 195
191 bounds.top = 0; bounds.left = 0; 196 /* Create the BBitmap framebuffer */
192 bounds.right = width-1; 197 bounds.top = 0;
193 bounds.bottom = height-1; 198 bounds.left = 0;
194 199 bounds.right = width - 1;
195 BView * bview = new BView(bounds,"overlay",B_FOLLOW_NONE,B_WILL_DRAW); 200 bounds.bottom = height - 1;
196 if (!bview) { 201
197 SDL_OutOfMemory(); 202 BView *bview =
198 SDL_FreeYUVOverlay(overlay); 203 new BView (bounds, "overlay", B_FOLLOW_NONE, B_WILL_DRAW);
199 return NULL; 204 if (!bview) {
200 } 205 SDL_OutOfMemory ();
201 overlay->hwdata->bview = bview; 206 SDL_FreeYUVOverlay (overlay);
202 overlay->hwdata->first_display = true; 207 return NULL;
203 bview->Hide(); 208 }
204 209 overlay->hwdata->bview = bview;
205 bbitmap = BE_GetOverlayBitmap(bounds,cs); 210 overlay->hwdata->first_display = true;
206 if (!bbitmap) { 211 bview->Hide ();
207 overlay->hwdata->bbitmap = NULL; 212
208 SDL_FreeYUVOverlay(overlay); 213 bbitmap = BE_GetOverlayBitmap (bounds, cs);
209 return NULL; 214 if (!bbitmap) {
210 } 215 overlay->hwdata->bbitmap = NULL;
211 overlay->hwdata->bbitmap = bbitmap; 216 SDL_FreeYUVOverlay (overlay);
212 217 return NULL;
213 overlay->planes = planes; 218 }
214 overlay->pitches = (Uint16*)SDL_calloc(overlay->planes, sizeof(Uint16)); 219 overlay->hwdata->bbitmap = bbitmap;
215 overlay->pixels = (Uint8**)SDL_calloc(overlay->planes, sizeof(Uint8*)); 220
216 if (!overlay->pitches || !overlay->pixels) 221 overlay->planes = planes;
217 { 222 overlay->pitches =
218 SDL_OutOfMemory(); 223 (Uint16 *) SDL_calloc (overlay->planes, sizeof (Uint16));
219 SDL_FreeYUVOverlay(overlay); 224 overlay->pixels =
220 return(NULL); 225 (Uint8 **) SDL_calloc (overlay->planes, sizeof (Uint8 *));
221 } 226 if (!overlay->pitches || !overlay->pixels) {
222 227 SDL_OutOfMemory ();
223 overlay->pitches[0] = bbitmap->BytesPerRow(); 228 SDL_FreeYUVOverlay (overlay);
224 overlay->pixels[0] = (Uint8 *)bbitmap->Bits(); 229 return (NULL);
225 overlay->hw_overlay = 1; 230 }
226 231
227 if (SDL_Win->LockWithTimeout(1000000) != B_OK) { 232 overlay->pitches[0] = bbitmap->BytesPerRow ();
228 SDL_FreeYUVOverlay(overlay); 233 overlay->pixels[0] = (Uint8 *) bbitmap->Bits ();
229 return(NULL); 234 overlay->hw_overlay = 1;
230 } 235
231 BView * view = SDL_Win->View(); 236 if (SDL_Win->LockWithTimeout (1000000) != B_OK) {
232 view->AddChild(bview); 237 SDL_FreeYUVOverlay (overlay);
233 rgb_color key; 238 return (NULL);
234 bview->SetViewOverlay(bbitmap,bounds,bview->Bounds(),&key,B_FOLLOW_ALL, 239 }
235 B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL); 240 BView *view = SDL_Win->View ();
236 bview->SetViewColor(key); 241 view->AddChild (bview);
237 bview->Flush(); 242 rgb_color key;
238 SDL_Win->Unlock(); 243 bview->SetViewOverlay (bbitmap, bounds, bview->Bounds (), &key,
239 244 B_FOLLOW_ALL,
240 current_overlay=overlay; 245 B_OVERLAY_FILTER_HORIZONTAL |
241 246 B_OVERLAY_FILTER_VERTICAL);
242 return overlay; 247 bview->SetViewColor (key);
243 } 248 bview->Flush ();
244 249 SDL_Win->Unlock ();
245 int BE_LockYUVOverlay(_THIS, SDL_Overlay* overlay) 250
246 { 251 current_overlay = overlay;
247 if (overlay == NULL) 252
248 { 253 return overlay;
254 }
255
256 int BE_LockYUVOverlay (_THIS, SDL_Overlay * overlay)
257 {
258 if (overlay == NULL) {
259 return 0;
260 }
261
262 overlay->hwdata->locked = 1;
249 return 0; 263 return 0;
250 } 264 }
251 265
252 overlay->hwdata->locked = 1; 266 void BE_UnlockYUVOverlay (_THIS, SDL_Overlay * overlay)
253 return 0; 267 {
254 } 268 if (overlay == NULL) {
255 269 return;
256 void BE_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay) 270 }
257 { 271
258 if (overlay == NULL) 272 overlay->hwdata->locked = 0;
259 { 273 }
260 return; 274
261 } 275 int BE_DisplayYUVOverlay (_THIS, SDL_Overlay * overlay, SDL_Rect * src,
262 276 SDL_Rect * dst)
263 overlay->hwdata->locked = 0; 277 {
264 } 278 if ((overlay == NULL) || (overlay->hwdata == NULL)
265 279 || (overlay->hwdata->bview == NULL) || (SDL_Win->View () == NULL)) {
266 int BE_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* src, SDL_Rect *dst) 280 return -1;
267 { 281 }
268 if ((overlay == NULL) || (overlay->hwdata==NULL) 282 if (SDL_Win->LockWithTimeout (50000) != B_OK) {
269 || (overlay->hwdata->bview==NULL) || (SDL_Win->View() == NULL)) 283 return 0;
270 { 284 }
271 return -1; 285 BView *bview = overlay->hwdata->bview;
272 } 286 if (SDL_Win->IsFullScreen ()) {
273 if (SDL_Win->LockWithTimeout(50000) != B_OK) { 287 int left, top;
288 SDL_Win->GetXYOffset (left, top);
289 bview->MoveTo (left + dst->x, top + dst->y);
290 } else {
291 bview->MoveTo (dst->x, dst->y);
292 }
293 bview->ResizeTo (dst->w, dst->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
274 return 0; 301 return 0;
275 } 302 }
276 BView * bview = overlay->hwdata->bview; 303
277 if (SDL_Win->IsFullScreen()) { 304 void BE_FreeYUVOverlay (_THIS, SDL_Overlay * overlay)
278 int left,top; 305 {
279 SDL_Win->GetXYOffset(left,top); 306 if (overlay == NULL) {
280 bview->MoveTo(left+dst->x,top+dst->y); 307 return;
281 } else { 308 }
282 bview->MoveTo(dst->x,dst->y); 309
283 } 310 if (overlay->hwdata == NULL) {
284 bview->ResizeTo(dst->w,dst->h); 311 return;
285 bview->Flush(); 312 }
286 if (overlay->hwdata->first_display) { 313
287 bview->Show(); 314 current_overlay = NULL;
288 overlay->hwdata->first_display = false; 315
289 } 316 delete overlay->hwdata->bbitmap;
290 SDL_Win->Unlock(); 317
291 318 SDL_free (overlay->hwdata);
292 return 0; 319 }
293 } 320
294 321 }; // extern "C"
295 void BE_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) 322
296 { 323 /* vi: set ts=4 sw=4 expandtab: */
297 if (overlay == NULL)
298 {
299 return;
300 }
301
302 if (overlay->hwdata == NULL)
303 {
304 return;
305 }
306
307 current_overlay=NULL;
308
309 delete overlay->hwdata->bbitmap;
310
311 SDL_free(overlay->hwdata);
312 }
313
314 }; // extern "C"