xref: /haiku/src/apps/mediaplayer/VideoView.cpp (revision 1214ef1b2100f2b3299fc9d8d6142e46f70a4c3f)
1 /*
2  * VideoView.cpp - Media Player for the Haiku Operating System
3  *
4  * Copyright (C) 2006 Marcus Overhagen <marcus@overhagen.de>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * version 2 as published by the Free Software Foundation.
9  *
10  * This program 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
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  *
19  */
20 #include <Message.h>
21 #include <Bitmap.h>
22 #include "VideoView.h"
23 
24 #include <stdio.h>
25 #include <string.h>
26 
27 VideoView::VideoView(BRect frame, const char *name, uint32 resizeMask, uint32 flags)
28  :	BView(frame, name, resizeMask, flags)
29  ,	fController(NULL)
30  ,	fOverlayActive(false)
31 {
32 	SetViewColor(B_TRANSPARENT_COLOR);
33 //	SetViewColor(127,255,127);
34 	rgb_color r = {255, 0, 0, 255};
35 	fOverlayKeyColor = r;
36 }
37 
38 
39 VideoView::~VideoView()
40 {
41 }
42 
43 
44 void
45 VideoView::SetController(Controller *controller)
46 {
47 	fController = controller;
48 }
49 
50 
51 void
52 VideoView::AttachedToWindow()
53 {
54 }
55 
56 void
57 VideoView::OverlayLockAcquire()
58 {
59    printf("VideoView::OverlayLockAcquire\n");
60 }
61 
62 
63 void
64 VideoView::OverlayLockRelease()
65 {
66    printf("VideoView::OverlayLockRelease\n");
67 	// overlaybitmap->UnlockBits
68 }
69 
70 
71 void
72 VideoView::OverlayScreenshotPrepare()
73 {
74 	printf("OverlayScreenshotPrepare enter\n");
75 /*
76 	fController->LockBitmap();
77 	if (fOverlayActive) {
78 		BBitmap *bmp = fController->Bitmap();
79 		if (bmp) {
80 //			Window()->UpdateIfNeeded();
81 //			Sync();
82 			BBitmap *tmp = new BBitmap(bmp->Bounds(), 0, B_RGB32);
83 //			ConvertBitmap(tmp, bmp);
84 			ClearViewOverlay();
85 			DrawBitmap(tmp, Bounds());
86 			delete tmp;
87 //			Sync();
88 		}
89 	}
90 	fController->UnlockBitmap();
91 */
92 	printf("OverlayScreenshotPrepare leave\n");
93 }
94 
95 
96 void
97 VideoView::OverlayScreenshotCleanup()
98 {
99 	printf("OverlayScreenshotCleanup enter\n");
100 /*
101 	snooze(50000); // give app server some time to take the screenshot
102 	fController->LockBitmap();
103 	if (fOverlayActive) {
104 		BBitmap *bmp = fController->Bitmap();
105 		if (bmp) {
106 			DrawBitmap(bmp, Bounds());
107 			SetViewOverlay(bmp, bmp->Bounds(), Bounds(), &fOverlayKeyColor,
108 				B_FOLLOW_ALL, B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL);
109 			Invalidate();
110 		}
111 	}
112 	fController->UnlockBitmap();
113 */
114 	printf("OverlayScreenshotCleanup leave\n");
115 }
116 
117 
118 void
119 VideoView::RemoveVideoDisplay()
120 {
121 	printf("VideoView::RemoveVideoDisplay\n");
122 
123 	if (fOverlayActive) {
124 		ClearViewOverlay();
125 		fOverlayActive = false;
126 	}
127 	Invalidate();
128 }
129 
130 
131 void
132 VideoView::RemoveOverlay()
133 {
134 	printf("VideoView::RemoveOverlay\n");
135 	if (LockLooperWithTimeout(50000) == B_OK) {
136 		ClearViewOverlay();
137 		fOverlayActive = false;
138 		UnlockLooper();
139 	}
140 }
141 
142 
143 void
144 VideoView::Draw(BRect updateRect)
145 {
146 	if (fOverlayActive) {
147 		SetHighColor(fOverlayKeyColor);
148 		FillRect(updateRect);
149 	} else {
150 		fController->LockBitmap();
151 		BBitmap *bmp = fController->Bitmap();
152 		if (bmp)
153 			DrawBitmap(bmp, Bounds());
154 		fController->UnlockBitmap();
155 	}
156 }
157 
158 
159 void
160 VideoView::DrawFrame()
161 {
162 //	printf("VideoView::DrawFrame\n");
163 
164 	if (LockLooperWithTimeout(50000) != B_OK)
165 		return;
166 
167 	fController->LockBitmap();
168 	BBitmap *bmp = fController->Bitmap();
169 
170 	if (bmp) {
171 		bool want_overlay = bmp->ColorSpace() == B_YCbCr422;
172 
173 		if (!want_overlay && fOverlayActive) {
174 			if (LockLooperWithTimeout(50000) == B_OK) {
175 				ClearViewOverlay();
176 				UnlockLooper();
177 				fOverlayActive = false;
178 			} else {
179 				printf("can't ClearViewOverlay, as LockLooperWithTimeout failed\n");
180 				return;
181 			}
182 		}
183 
184 		if (want_overlay && !fOverlayActive ) {
185 printf("trying to activate overlay...");
186 			// reserve overlay channel
187 			status_t ret = SetViewOverlay(bmp, bmp->Bounds(), Bounds(),
188 				&fOverlayKeyColor, B_FOLLOW_ALL,
189 				B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL);
190 			if (ret == B_OK) {
191 printf("success\n");
192 				fOverlayActive = true;
193 				Invalidate();
194 			} else {
195 printf("failed: %s\n", strerror(ret));
196 			}
197 		} else if (fOverlayActive) {
198 			// transfer overlay channel
199 			rgb_color overlayKey;
200 			SetViewOverlay(bmp, bmp->Bounds(), Bounds(), &overlayKey,
201 				B_FOLLOW_ALL, B_OVERLAY_TRANSFER_CHANNEL
202 					| B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL);
203 		} else {
204 			// no overlay
205 			DrawBitmap(bmp, Bounds());
206 		}
207 	}
208 
209 	fController->UnlockBitmap();
210 
211 	UnlockLooper();
212 }
213 
214 
215 void
216 VideoView::MessageReceived(BMessage *msg)
217 {
218 	switch (msg->what) {
219 
220 		default:
221 			BView::MessageReceived(msg);
222 	}
223 }
224 
225 
226 bool
227 VideoView::IsOverlaySupported()
228 {
229 	struct colorcombo {
230 		color_space colspace;
231 		const char *name;
232 	} colspace[] = {
233 		{ B_RGB32,		"B_RGB32"},
234 		{ B_RGBA32,		"B_RGBA32"},
235 		{ B_RGB24,		"B_RGB24"},
236 		{ B_RGB16,		"B_RGB16"},
237 		{ B_RGB15,		"B_RGB15"},
238 		{ B_RGBA15,		"B_RGBA15"},
239 		{ B_RGB32_BIG,	"B_RGB32_BIG"},
240 		{ B_RGBA32_BIG,	"B_RGBA32_BIG "},
241 		{ B_RGB24_BIG,	"B_RGB24_BIG "},
242 		{ B_RGB16_BIG,	"B_RGB16_BIG "},
243 		{ B_RGB15_BIG,	"B_RGB15_BIG "},
244 		{ B_RGBA15_BIG, "B_RGBA15_BIG "},
245 		{ B_YCbCr422,	"B_YCbCr422"},
246 		{ B_YCbCr411,	"B_YCbCr411"},
247 		{ B_YCbCr444,	"B_YCbCr444"},
248 		{ B_YCbCr420,	"B_YCbCr420"},
249 		{ B_YUV422,		"B_YUV422"},
250 		{ B_YUV411,		"B_YUV411"},
251 		{ B_YUV444,		"B_YUV444"},
252 		{ B_YUV420,		"B_YUV420"},
253 		{ B_NO_COLOR_SPACE, NULL}
254 	};
255 
256 	bool supported = false;
257 	for (int i = 0; colspace[i].name; i++) {
258 		BBitmap *test = new BBitmap(BRect(0,0,319,239),	B_BITMAP_WILL_OVERLAY | B_BITMAP_RESERVE_OVERLAY_CHANNEL, colspace[i].colspace);
259 		if (test->InitCheck() == B_OK) {
260 			printf("Display supports %s (0x%08x) overlay\n", colspace[i].name, colspace[i].colspace);
261 			supported = true;
262 		}
263 		delete test;
264 //		if (supported)
265 //			break;
266 	}
267 	return supported;
268 }
269 
270