xref: /haiku/src/apps/mediaplayer/VideoView.cpp (revision 079eccf655ba39812b421ae1b87a727d41b50354)
1 /*
2  * Copyright © 2006-2008 Stephan Aßmus <superstippi@gmx.de>
3  * All rights reserved. Distributed under the terms of the MIT license.
4  */
5 #include "VideoView.h"
6 
7 #include <stdio.h>
8 
9 #include <Bitmap.h>
10 
11 
12 VideoView::VideoView(BRect frame, const char* name, uint32 resizeMask)
13 	: BView(frame, name, resizeMask, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
14 	  fOverlayMode(false)
15 {
16 	SetViewColor(B_TRANSPARENT_COLOR);
17 		// might be reset to overlay key color if overlays are used
18 	SetHighColor(0, 0, 0);
19 
20 	// create some hopefully sensible default overlay restrictions
21 	fOverlayRestrictions.min_width_scale = 0.25;
22 	fOverlayRestrictions.max_width_scale = 8.0;
23 	fOverlayRestrictions.min_height_scale = 0.25;
24 	fOverlayRestrictions.max_height_scale = 8.0;
25 }
26 
27 
28 VideoView::~VideoView()
29 {
30 }
31 
32 
33 void
34 VideoView::Draw(BRect updateRect)
35 {
36 	bool fillBlack = true;
37 
38 	if (LockBitmap()) {
39 		BRect r(Bounds());
40 		if (const BBitmap* bitmap = GetBitmap()) {
41 			fillBlack = false;
42 			if (!fOverlayMode)
43 				DrawBitmap(bitmap, bitmap->Bounds(), r);
44 		}
45 		UnlockBitmap();
46 	}
47 
48 	if (fillBlack)
49 		FillRect(updateRect);
50 }
51 
52 
53 void
54 VideoView::SetBitmap(const BBitmap* bitmap)
55 {
56 	VideoTarget::SetBitmap(bitmap);
57 	// Attention: Don't lock the window, if the bitmap is NULL. Otherwise
58 	// we're going to deadlock when the window tells the node manager to
59 	// stop the nodes (Window -> NodeManager -> VideoConsumer -> VideoView
60 	// -> Window).
61 	if (bitmap && LockLooperWithTimeout(10000) == B_OK) {
62 		if (LockBitmap()) {
63 //			if (fOverlayMode || bitmap->Flags() & B_BITMAP_WILL_OVERLAY) {
64 			if (fOverlayMode || bitmap->ColorSpace() == B_YCbCr422) {
65 				if (!fOverlayMode) {
66 					// init overlay
67 					rgb_color key;
68 					status_t ret = SetViewOverlay(bitmap, bitmap->Bounds(),
69 						Bounds(), &key, B_FOLLOW_ALL,
70 						B_OVERLAY_FILTER_HORIZONTAL
71 						| B_OVERLAY_FILTER_VERTICAL);
72 					if (ret == B_OK) {
73 						fOverlayKeyColor = key;
74 						SetViewColor(key);
75 						SetLowColor(key);
76 						snooze(20000);
77 						FillRect(Bounds(), B_SOLID_LOW);
78 						Sync();
79 						// use overlay from here on
80 						fOverlayMode = true;
81 
82 						// update restrictions
83 						overlay_restrictions restrictions;
84 						if (bitmap->GetOverlayRestrictions(&restrictions)
85 								== B_OK)
86 							fOverlayRestrictions = restrictions;
87 					} else {
88 						// try again next time
89 						// synchronous draw
90 						FillRect(Bounds());
91 						Sync();
92 					}
93 				} else {
94 					// transfer overlay channel
95 					rgb_color key;
96 					SetViewOverlay(bitmap, bitmap->Bounds(), Bounds(),
97 						&key, B_FOLLOW_ALL, B_OVERLAY_FILTER_HORIZONTAL
98 							| B_OVERLAY_FILTER_VERTICAL
99 							| B_OVERLAY_TRANSFER_CHANNEL);
100 				}
101 			} else if (fOverlayMode && bitmap->ColorSpace() != B_YCbCr422) {
102 				fOverlayMode = false;
103 				ClearViewOverlay();
104 				SetViewColor(B_TRANSPARENT_COLOR);
105 			}
106 			if (!fOverlayMode)
107 				DrawBitmap(bitmap, bitmap->Bounds(), Bounds());
108 
109 			UnlockBitmap();
110 		}
111 		UnlockLooper();
112 	}
113 }
114 
115 
116 void
117 VideoView::GetOverlayScaleLimits(float* minScale, float* maxScale) const
118 {
119 	*minScale = max_c(fOverlayRestrictions.min_width_scale,
120 		fOverlayRestrictions.min_height_scale);
121 	*maxScale = max_c(fOverlayRestrictions.max_width_scale,
122 		fOverlayRestrictions.max_height_scale);
123 }
124 
125 
126 void
127 VideoView::OverlayScreenshotPrepare()
128 {
129 	// TODO: Do nothing if the current bitmap is in RGB color space
130 	// and no overlay. Otherwise, convert current bitmap to RGB color
131 	// space an draw it in place of the normal display.
132 }
133 
134 
135 void
136 VideoView::OverlayScreenshotCleanup()
137 {
138 	// TODO: Do nothing if the current bitmap is in RGB color space
139 	// and no overlay. Otherwise clean view area with overlay color.
140 }
141 
142 
143 bool
144 VideoView::IsOverlayActive()
145 {
146 	bool active = false;
147 	if (LockBitmap()) {
148 		active = fOverlayMode;
149 		UnlockBitmap();
150 	}
151 	return active;
152 }
153 
154 
155 void
156 VideoView::DisableOverlay()
157 {
158 	if (!fOverlayMode)
159 		return;
160 
161 	FillRect(Bounds());
162 	Sync();
163 
164 	ClearViewOverlay();
165 	snooze(20000);
166 	Sync();
167 	fOverlayMode = false;
168 }
169 
170