comparison src/video/bwindow/SDL_sysyuv.cc @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents 51038e80ae59
children 99210400e8b9
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
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, "GetOverlayBitmap failed height alignment\n");
69 fprintf(stderr,"- height = %lu, aligned_height = %lu\n",height,aligned_height); 70 fprintf(stderr, "- height = %lu, aligned_height = %lu\n",
70 delete bbitmap; 71 height, aligned_height);
71 return 0; 72 delete bbitmap;
72 } 73 return 0;
73 } 74 }
74 if ((r.source.min_width > width) || 75 }
75 (r.source.min_height > height) || 76 if ((r.source.min_width > width) ||
76 (r.source.max_width < width) || 77 (r.source.min_height > height) ||
77 (r.source.max_height < height)) { 78 (r.source.max_width < width) || (r.source.max_height < height)) {
78 fprintf(stderr,"GetOverlayBitmap failed bounds tests\n"); 79 fprintf(stderr, "GetOverlayBitmap failed bounds tests\n");
79 delete bbitmap; 80 delete bbitmap;
80 return 0; 81 return 0;
81 } 82 }
82 if ((width_padding != 0) || (height_padding != 0)) { 83 if ((width_padding != 0) || (height_padding != 0)) {
83 delete bbitmap; 84 delete bbitmap;
84 bounds.Set(bounds.left,bounds.top,bounds.right+width_padding,bounds.bottom+height_padding); 85 bounds.Set(bounds.left, bounds.top,
85 bbitmap = new BBitmap(bounds,B_BITMAP_WILL_OVERLAY,cs); 86 bounds.right + width_padding,
86 if (!bbitmap || bbitmap->InitCheck() != B_OK) { 87 bounds.bottom + height_padding);
87 fprintf(stderr,"GetOverlayBitmap failed late\n"); 88 bbitmap = new BBitmap(bounds, B_BITMAP_WILL_OVERLAY, cs);
88 delete bbitmap; 89 if (!bbitmap || bbitmap->InitCheck() != B_OK) {
89 return 0; 90 fprintf(stderr, "GetOverlayBitmap failed late\n");
90 } 91 delete bbitmap;
91 } 92 return 0;
92 return bbitmap; 93 }
93 } 94 }
95 return bbitmap;
96 }
94 97
95 // See <GraphicsDefs.h> [btw: Cb=U, Cr=V] 98 // See <GraphicsDefs.h> [btw: Cb=U, Cr=V]
96 // See also http://www.fourcc.org/indexyuv.htm 99 // See also http://www.fourcc.org/indexyuv.htm
97 enum color_space convert_color_space(Uint32 format) { 100 enum color_space convert_color_space(Uint32 format)
98 switch (format) { 101 {
99 case SDL_YV12_OVERLAY: 102 switch (format) {
100 return B_YUV9; 103 case SDL_YV12_OVERLAY:
101 case SDL_IYUV_OVERLAY: 104 return B_YUV9;
102 return B_YUV12; 105 case SDL_IYUV_OVERLAY:
103 case SDL_YUY2_OVERLAY: 106 return B_YUV12;
104 return B_YCbCr422; 107 case SDL_YUY2_OVERLAY:
105 case SDL_UYVY_OVERLAY: 108 return B_YCbCr422;
106 return B_YUV422; 109 case SDL_UYVY_OVERLAY:
107 case SDL_YVYU_OVERLAY: // not supported on beos? 110 return B_YUV422;
108 return B_NO_COLOR_SPACE; 111 case SDL_YVYU_OVERLAY: // not supported on beos?
109 default: 112 return B_NO_COLOR_SPACE;
110 return B_NO_COLOR_SPACE; 113 default:
111 } 114 return B_NO_COLOR_SPACE;
112 } 115 }
116 }
113 117
114 // See SDL_video.h 118 // See SDL_video.h
115 int count_planes(Uint32 format) { 119 int count_planes(Uint32 format)
116 switch (format) { 120 {
117 case SDL_YV12_OVERLAY: 121 switch (format) {
118 case SDL_IYUV_OVERLAY: 122 case SDL_YV12_OVERLAY:
119 return 3; 123 case SDL_IYUV_OVERLAY:
120 case SDL_YUY2_OVERLAY: 124 return 3;
121 case SDL_UYVY_OVERLAY: 125 case SDL_YUY2_OVERLAY:
122 case SDL_YVYU_OVERLAY: 126 case SDL_UYVY_OVERLAY:
123 return 1; 127 case SDL_YVYU_OVERLAY:
124 default: 128 return 1;
125 return 0; 129 default:
126 } 130 return 0;
127 } 131 }
128 132 }
129 SDL_Overlay *BE_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) { 133
130 SDL_Overlay* overlay; 134 SDL_Overlay *BE_CreateYUVOverlay(_THIS, int width, int height,
131 struct private_yuvhwdata* hwdata; 135 Uint32 format, SDL_Surface * display)
132 BBitmap *bbitmap; 136 {
133 int planes; 137 SDL_Overlay *overlay;
134 BRect bounds; 138 struct private_yuvhwdata *hwdata;
135 color_space cs; 139 BBitmap *bbitmap;
136 140 int planes;
137 /* find the appropriate BeOS colorspace descriptor */ 141 BRect bounds;
138 cs = convert_color_space(format); 142 color_space cs;
139 if (cs == B_NO_COLOR_SPACE) 143
140 { 144 /* find the appropriate BeOS colorspace descriptor */
141 return NULL; 145 cs = convert_color_space(format);
142 } 146 if (cs == B_NO_COLOR_SPACE) {
143 147 return NULL;
144 /* count planes */ 148 }
145 planes = count_planes(format); 149
146 if (planes == 0) 150 /* count planes */
147 { 151 planes = count_planes(format);
148 return NULL; 152 if (planes == 0) {
149 } 153 return NULL;
150 /* TODO: figure out planar modes, if anyone cares */ 154 }
151 if (planes == 3) 155 /* TODO: figure out planar modes, if anyone cares */
152 { 156 if (planes == 3) {
153 return NULL; 157 return NULL;
154 } 158 }
155 159
156 /* Create the overlay structure */ 160 /* Create the overlay structure */
157 overlay = (SDL_Overlay*)SDL_calloc(1, sizeof(SDL_Overlay)); 161 overlay = (SDL_Overlay *) SDL_calloc(1, sizeof(SDL_Overlay));
158 162
159 if (overlay == NULL) 163 if (overlay == NULL) {
160 { 164 SDL_OutOfMemory();
161 SDL_OutOfMemory(); 165 return NULL;
162 return NULL; 166 }
163 } 167
164 168 /* Fill in the basic members */
165 /* Fill in the basic members */ 169 overlay->format = format;
166 overlay->format = format; 170 overlay->w = width;
167 overlay->w = width; 171 overlay->h = height;
168 overlay->h = height; 172 overlay->hwdata = NULL;
169 overlay->hwdata = NULL; 173
170 174 /* Set up the YUV surface function structure */
171 /* Set up the YUV surface function structure */ 175 overlay->hwfuncs = &be_yuvfuncs;
172 overlay->hwfuncs = &be_yuvfuncs; 176
173 177 /* Create the pixel data and lookup tables */
174 /* Create the pixel data and lookup tables */ 178 hwdata =
175 hwdata = (struct private_yuvhwdata*)SDL_calloc(1, sizeof(struct private_yuvhwdata)); 179 (struct private_yuvhwdata *) SDL_calloc(1,
176 180 sizeof(struct
177 if (hwdata == NULL) 181 private_yuvhwdata));
178 { 182
179 SDL_OutOfMemory(); 183 if (hwdata == NULL) {
180 SDL_FreeYUVOverlay(overlay); 184 SDL_OutOfMemory();
181 return NULL; 185 SDL_FreeYUVOverlay(overlay);
182 } 186 return NULL;
183 187 }
184 overlay->hwdata = hwdata; 188
185 overlay->hwdata->display = display; 189 overlay->hwdata = hwdata;
186 overlay->hwdata->bview = NULL; 190 overlay->hwdata->display = display;
187 overlay->hwdata->bbitmap = NULL; 191 overlay->hwdata->bview = NULL;
188 overlay->hwdata->locked = 0; 192 overlay->hwdata->bbitmap = NULL;
189 193 overlay->hwdata->locked = 0;
190 /* Create the BBitmap framebuffer */ 194
191 bounds.top = 0; bounds.left = 0; 195 /* Create the BBitmap framebuffer */
192 bounds.right = width-1; 196 bounds.top = 0;
193 bounds.bottom = height-1; 197 bounds.left = 0;
194 198 bounds.right = width - 1;
195 BView * bview = new BView(bounds,"overlay",B_FOLLOW_NONE,B_WILL_DRAW); 199 bounds.bottom = height - 1;
196 if (!bview) { 200
197 SDL_OutOfMemory(); 201 BView *bview =
198 SDL_FreeYUVOverlay(overlay); 202 new BView(bounds, "overlay", B_FOLLOW_NONE, B_WILL_DRAW);
199 return NULL; 203 if (!bview) {
200 } 204 SDL_OutOfMemory();
201 overlay->hwdata->bview = bview; 205 SDL_FreeYUVOverlay(overlay);
202 overlay->hwdata->first_display = true; 206 return NULL;
203 bview->Hide(); 207 }
204 208 overlay->hwdata->bview = bview;
205 bbitmap = BE_GetOverlayBitmap(bounds,cs); 209 overlay->hwdata->first_display = true;
206 if (!bbitmap) { 210 bview->Hide();
207 overlay->hwdata->bbitmap = NULL; 211
208 SDL_FreeYUVOverlay(overlay); 212 bbitmap = BE_GetOverlayBitmap(bounds, cs);
209 return NULL; 213 if (!bbitmap) {
210 } 214 overlay->hwdata->bbitmap = NULL;
211 overlay->hwdata->bbitmap = bbitmap; 215 SDL_FreeYUVOverlay(overlay);
212 216 return NULL;
213 overlay->planes = planes; 217 }
214 overlay->pitches = (Uint16*)SDL_calloc(overlay->planes, sizeof(Uint16)); 218 overlay->hwdata->bbitmap = bbitmap;
215 overlay->pixels = (Uint8**)SDL_calloc(overlay->planes, sizeof(Uint8*)); 219
216 if (!overlay->pitches || !overlay->pixels) 220 overlay->planes = planes;
217 { 221 overlay->pitches =
218 SDL_OutOfMemory(); 222 (Uint16 *) SDL_calloc(overlay->planes, sizeof(Uint16));
219 SDL_FreeYUVOverlay(overlay); 223 overlay->pixels =
220 return(NULL); 224 (Uint8 **) SDL_calloc(overlay->planes, sizeof(Uint8 *));
221 } 225 if (!overlay->pitches || !overlay->pixels) {
222 226 SDL_OutOfMemory();
223 overlay->pitches[0] = bbitmap->BytesPerRow(); 227 SDL_FreeYUVOverlay(overlay);
224 overlay->pixels[0] = (Uint8 *)bbitmap->Bits(); 228 return (NULL);
225 overlay->hw_overlay = 1; 229 }
226 230
227 if (SDL_Win->LockWithTimeout(1000000) != B_OK) { 231 overlay->pitches[0] = bbitmap->BytesPerRow();
228 SDL_FreeYUVOverlay(overlay); 232 overlay->pixels[0] = (Uint8 *) bbitmap->Bits();
229 return(NULL); 233 overlay->hw_overlay = 1;
230 } 234
231 BView * view = SDL_Win->View(); 235 if (SDL_Win->LockWithTimeout(1000000) != B_OK) {
232 view->AddChild(bview); 236 SDL_FreeYUVOverlay(overlay);
233 rgb_color key; 237 return (NULL);
234 bview->SetViewOverlay(bbitmap,bounds,bview->Bounds(),&key,B_FOLLOW_ALL, 238 }
235 B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL); 239 BView *view = SDL_Win->View();
236 bview->SetViewColor(key); 240 view->AddChild(bview);
237 bview->Flush(); 241 rgb_color key;
238 SDL_Win->Unlock(); 242 bview->SetViewOverlay(bbitmap, bounds, bview->Bounds(), &key,
239 243 B_FOLLOW_ALL,
240 current_overlay=overlay; 244 B_OVERLAY_FILTER_HORIZONTAL |
241 245 B_OVERLAY_FILTER_VERTICAL);
242 return overlay; 246 bview->SetViewColor(key);
243 } 247 bview->Flush();
244 248 SDL_Win->Unlock();
245 int BE_LockYUVOverlay(_THIS, SDL_Overlay* overlay) 249
246 { 250 current_overlay = overlay;
247 if (overlay == NULL) 251
248 { 252 return overlay;
253 }
254
255 int BE_LockYUVOverlay(_THIS, SDL_Overlay * overlay)
256 {
257 if (overlay == NULL) {
258 return 0;
259 }
260
261 overlay->hwdata->locked = 1;
249 return 0; 262 return 0;
250 } 263 }
251 264
252 overlay->hwdata->locked = 1; 265 void BE_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay)
253 return 0; 266 {
254 } 267 if (overlay == NULL) {
255 268 return;
256 void BE_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay) 269 }
257 { 270
258 if (overlay == NULL) 271 overlay->hwdata->locked = 0;
259 { 272 }
260 return; 273
261 } 274 int BE_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay, SDL_Rect * src,
262 275 SDL_Rect * dst)
263 overlay->hwdata->locked = 0; 276 {
264 } 277 if ((overlay == NULL) || (overlay->hwdata == NULL)
265 278 || (overlay->hwdata->bview == NULL) || (SDL_Win->View() == NULL)) {
266 int BE_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* src, SDL_Rect *dst) 279 return -1;
267 { 280 }
268 if ((overlay == NULL) || (overlay->hwdata==NULL) 281 if (SDL_Win->LockWithTimeout(50000) != B_OK) {
269 || (overlay->hwdata->bview==NULL) || (SDL_Win->View() == NULL)) 282 return 0;
270 { 283 }
271 return -1; 284 BView *bview = overlay->hwdata->bview;
272 } 285 if (SDL_Win->IsFullScreen()) {
273 if (SDL_Win->LockWithTimeout(50000) != B_OK) { 286 int left, top;
287 SDL_Win->GetXYOffset(left, top);
288 bview->MoveTo(left + dst->x, top + dst->y);
289 } else {
290 bview->MoveTo(dst->x, dst->y);
291 }
292 bview->ResizeTo(dst->w, dst->h);
293 bview->Flush();
294 if (overlay->hwdata->first_display) {
295 bview->Show();
296 overlay->hwdata->first_display = false;
297 }
298 SDL_Win->Unlock();
299
274 return 0; 300 return 0;
275 } 301 }
276 BView * bview = overlay->hwdata->bview; 302
277 if (SDL_Win->IsFullScreen()) { 303 void BE_FreeYUVOverlay(_THIS, SDL_Overlay * overlay)
278 int left,top; 304 {
279 SDL_Win->GetXYOffset(left,top); 305 if (overlay == NULL) {
280 bview->MoveTo(left+dst->x,top+dst->y); 306 return;
281 } else { 307 }
282 bview->MoveTo(dst->x,dst->y); 308
283 } 309 if (overlay->hwdata == NULL) {
284 bview->ResizeTo(dst->w,dst->h); 310 return;
285 bview->Flush(); 311 }
286 if (overlay->hwdata->first_display) { 312
287 bview->Show(); 313 current_overlay = NULL;
288 overlay->hwdata->first_display = false; 314
289 } 315 delete overlay->hwdata->bbitmap;
290 SDL_Win->Unlock(); 316
291 317 SDL_free(overlay->hwdata);
292 return 0; 318 }
293 } 319
294 320 }; // extern "C"
295 void BE_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) 321
296 { 322 /* 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"