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