2 * Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify,
8 * merge, publish, distribute, sublicense, and/or sell copies of
9 * the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
26 #include <MediaRoster.h>
27 #include <MessageRunner.h>
28 #include "VideoView.h"
29 #include "VideoNode.h"
30 #include "ConvertBitmap.h"
36 #define CHECK_ACTIVITY 'ChkA'
38 VideoView::VideoView(BRect frame
, const char *name
, uint32 resizeMask
,
40 : BView(frame
, name
, resizeMask
, flags
)
43 , fOverlayActive(false)
44 , fActivityCheckMsgRunner(0)
47 SetViewColor(B_TRANSPARENT_COLOR
);
50 BMediaRoster
*mroster
= BMediaRoster::Roster(&err
);
51 if (!mroster
|| err
) {
52 printf("VideoView::VideoView: media_server is dead\n");
55 fVideoNode
= new VideoNode("video in", this);
56 err
= mroster
->RegisterNode(fVideoNode
);
61 VideoView::~VideoView()
63 delete fActivityCheckMsgRunner
;
66 BMediaRoster::Roster()->UnregisterNode(fVideoNode
);
73 VideoView::AttachedToWindow()
75 BMessage
msg(CHECK_ACTIVITY
);
76 fActivityCheckMsgRunner
= new BMessageRunner(BMessenger(this), &msg
,
89 VideoView::OverlayLockAcquire()
91 printf("VideoView::OverlayLockAcquire\n");
96 VideoView::OverlayLockRelease()
97 { /* [19:54] <Francois> Rudolf forwarded me a mail once about it
98 * [19:55] <Francois> when you get relmease msg you are supposed to
99 UnlockBits() on the overlay bitmaps you use
100 * [19:55] <Francois> it's used when switching workspaces
101 * [19:55] <Francois> as the bits might get relocated
103 printf("VideoView::OverlayLockRelease\n");
109 VideoView::OverlayScreenshotPrepare()
111 printf("OverlayScreenshotPrepare enter\n");
113 fVideoNode->LockBitmap();
114 if (fOverlayActive) {
115 BBitmap *bmp = fVideoNode->Bitmap();
117 // Window()->UpdateIfNeeded();
119 BBitmap *tmp = new BBitmap(bmp->Bounds(), 0, B_RGB32);
120 // ConvertBitmap(tmp, bmp);
122 DrawBitmap(tmp, Bounds());
127 fVideoNode->UnlockBitmap();
129 printf("OverlayScreenshotPrepare leave\n");
134 VideoView::OverlayScreenshotCleanup()
136 printf("OverlayScreenshotCleanup enter\n");
138 snooze(50000); // give app server some time to take the screenshot
139 fVideoNode->LockBitmap();
140 if (fOverlayActive) {
141 BBitmap *bmp = fVideoNode->Bitmap();
143 DrawBitmap(bmp, Bounds());
144 SetViewOverlay(bmp, bmp->Bounds(), Bounds(), &fOverlayKeyColor,
145 B_FOLLOW_ALL, B_OVERLAY_FILTER_HORIZONTAL
146 | B_OVERLAY_FILTER_VERTICAL);
150 fVideoNode->UnlockBitmap();
152 printf("OverlayScreenshotCleanup leave\n");
157 VideoView::RemoveVideoDisplay()
159 printf("VideoView::RemoveVideoDisplay\n");
161 if (fOverlayActive
) {
163 fOverlayActive
= false;
165 fVideoActive
= false;
171 VideoView::RemoveOverlay()
173 printf("VideoView::RemoveOverlay\n");
174 if (LockLooperWithTimeout(50000) == B_OK
) {
176 fOverlayActive
= false;
183 VideoView::CheckActivity()
187 if (system_time() - fLastFrame
< 700000)
190 printf("VideoView::CheckActivity: lag detected\n");
192 fVideoActive
= false;
198 VideoView::Draw(BRect updateRect
)
204 if (fOverlayActive
) {
205 SetHighColor(fOverlayKeyColor
);
206 FillRect(updateRect
);
208 fVideoNode
->LockBitmap();
209 BBitmap
*bmp
= fVideoNode
->Bitmap();
211 DrawBitmap(bmp
, bmp
->Bounds(), Bounds(), B_FILTER_BITMAP_BILINEAR
);
212 fVideoNode
->UnlockBitmap();
218 VideoView::DrawFrame()
220 // printf("VideoView::DrawFrame\n");
223 if (LockLooperWithTimeout(50000) != B_OK
)
228 fLastFrame
= system_time();
230 bool want_overlay
= fVideoNode
->IsOverlayActive();
232 if (!want_overlay
&& fOverlayActive
) {
233 if (LockLooperWithTimeout(50000) == B_OK
) {
236 fOverlayActive
= false;
238 printf("can't ClearViewOverlay, as LockLooperWithTimeout "
242 if (want_overlay
&& !fOverlayActive
) {
243 fVideoNode
->LockBitmap();
244 BBitmap
*bmp
= fVideoNode
->Bitmap();
245 if (bmp
&& LockLooperWithTimeout(50000) == B_OK
) {
246 SetViewOverlay(bmp
, bmp
->Bounds(), Bounds(), &fOverlayKeyColor
,
247 B_FOLLOW_ALL
, B_OVERLAY_FILTER_HORIZONTAL
248 | B_OVERLAY_FILTER_VERTICAL
);
249 fOverlayActive
= true;
254 fVideoNode
->UnlockBitmap();
256 if (!fOverlayActive
) {
257 if (LockLooperWithTimeout(50000) != B_OK
)
266 VideoView::DrawTestImage()
268 static const rgb_color cols
[8] = {
269 {255,255,255}, {255,255,0}, {0,255,255}, {0,255,0},
270 {255,0,255}, {255,0,0}, {0,0,255}, {0,0,0}
271 // {255,255,255}, {255,255,0}, {0,255,255},
272 // {255,0,255}, {255,0,0}, {0,255,0}, {0,0,255}, {0,0,0}
278 BRect bnd
= Bounds();
279 int seperator_y1
= int(0.60 * (bnd
.Height() + 1));
280 int seperator_y2
= int(0.80 * (bnd
.Height() + 1));
283 bar_width
= bnd
.Width() / 8;
288 for (int i
= 0; i
< 8; i
++) {
289 SetHighColor(cols
[i
]);
290 right
= (i
!= 7) ? left
+ bar_width
- 1 : bnd
.right
;
291 FillRect(BRect(left
, 0, right
, seperator_y1
));
297 bar_width
= bnd
.Width() / steps
;
298 // if (bar_width < 1)
302 for (int i
= 0; i
< steps
; i
++) {
303 uint8 c
= i
* 255 / (steps
- 1);
304 SetHighColor(c
, c
, c
);
305 right
= (i
!= steps
- 1) ? left
+ bar_width
- 1 : bnd
.right
;
306 FillRect(BRect(left
, seperator_y1
+ 1, right
, seperator_y2
));
312 bar_width
= bnd
.Width() / steps
;
317 for (int i
= 0; i
< steps
; i
++) {
318 uint8 c
= 255 - (i
* 255 / (steps
- 1));
319 SetHighColor(c
, c
, c
);
320 right
= (i
!= steps
- 1) ? left
+ bar_width
- 1 : bnd
.right
;
321 FillRect(BRect(left
, seperator_y2
+ 1, right
, bnd
.bottom
));
328 VideoView::MessageReceived(BMessage
*msg
)
335 BView::MessageReceived(msg
);
341 VideoView::IsOverlaySupported()
344 color_space colspace
;
347 { B_RGB32
, "B_RGB32"},
348 { B_RGBA32
, "B_RGBA32"},
349 { B_RGB24
, "B_RGB24"},
350 { B_RGB16
, "B_RGB16"},
351 { B_RGB15
, "B_RGB15"},
352 { B_RGBA15
, "B_RGBA15"},
353 { B_RGB32_BIG
, "B_RGB32_BIG"},
354 { B_RGBA32_BIG
, "B_RGBA32_BIG "},
355 { B_RGB24_BIG
, "B_RGB24_BIG "},
356 { B_RGB16_BIG
, "B_RGB16_BIG "},
357 { B_RGB15_BIG
, "B_RGB15_BIG "},
358 { B_RGBA15_BIG
, "B_RGBA15_BIG "},
359 { B_YCbCr422
, "B_YCbCr422"},
360 { B_YCbCr411
, "B_YCbCr411"},
361 { B_YCbCr444
, "B_YCbCr444"},
362 { B_YCbCr420
, "B_YCbCr420"},
363 { B_YUV422
, "B_YUV422"},
364 { B_YUV411
, "B_YUV411"},
365 { B_YUV444
, "B_YUV444"},
366 { B_YUV420
, "B_YUV420"},
367 { B_NO_COLOR_SPACE
, NULL
}
370 bool supported
= false;
371 for (int i
= 0; colspace
[i
].name
; i
++) {
372 BBitmap
*test
= new BBitmap(BRect(0,0,320,240), B_BITMAP_WILL_OVERLAY
373 | B_BITMAP_RESERVE_OVERLAY_CHANNEL
, colspace
[i
].colspace
);
374 if (test
->InitCheck() == B_OK
) {
375 printf("Display supports %s (0x%08x) overlay\n", colspace
[i
].name
,
376 colspace
[i
].colspace
);
377 overlay_restrictions restrict
;
378 if (B_OK
== test
->GetOverlayRestrictions(&restrict
)) {
380 "Overlay restrictions: source horizontal_alignment %d\n",
381 restrict
.source
.horizontal_alignment
);
382 printf("Overlay restrictions: source vertical_alignment %d\n",
383 restrict
.source
.vertical_alignment
);
384 printf("Overlay restrictions: source width_alignment %d\n",
385 restrict
.source
.width_alignment
);
386 printf("Overlay restrictions: source height_alignment %d\n",
387 restrict
.source
.height_alignment
);
388 printf("Overlay restrictions: source min_width %d\n",
389 restrict
.source
.min_width
);
390 printf("Overlay restrictions: source max_width %d\n",
391 restrict
.source
.max_width
);
392 printf("Overlay restrictions: source min_height %d\n",
393 restrict
.source
.min_height
);
394 printf("Overlay restrictions: source max_height %d\n",
395 restrict
.source
.max_height
);
397 "Overlay restrictions: destination horizontal_alignment "
398 "%d\n", restrict
.destination
.horizontal_alignment
);
399 printf("Overlay restrictions: destination vertical_alignment "
400 "%d\n", restrict
.destination
.vertical_alignment
);
401 printf("Overlay restrictions: destination width_alignment "
402 "%d\n", restrict
.destination
.width_alignment
);
403 printf("Overlay restrictions: destination height_alignment "
404 "%d\n", restrict
.destination
.height_alignment
);
405 printf("Overlay restrictions: destination min_width %d\n",
406 restrict
.destination
.min_width
);
407 printf("Overlay restrictions: destination max_width %d\n",
408 restrict
.destination
.max_width
);
409 printf("Overlay restrictions: destination min_height %d\n",
410 restrict
.destination
.min_height
);
411 printf("Overlay restrictions: destination max_height %d\n",
412 restrict
.destination
.max_height
);
413 printf("Overlay restrictions: min_width_scale %.3f\n",
414 restrict
.min_width_scale
);
415 printf("Overlay restrictions: max_width_scale %.3f\n",
416 restrict
.max_width_scale
);
417 printf("Overlay restrictions: min_height_scale %.3f\n",
418 restrict
.min_height_scale
);
419 printf("Overlay restrictions: max_height_scale %.3f\n",
420 restrict
.max_height_scale
);