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