1/*
2 * Copyright (C) 2006 Marcus Overhagen <marcus@overhagen.de>. All rights reserved.
3 *
4 * Distributed under the terms of the MIT License.
5 */
6#include "VideoNode.h"
7#include "VideoView.h"
8#include "debug.h"
9
10#include <Bitmap.h>
11#include <Locker.h>
12#include <MediaRoster.h>
13#include <Message.h>
14
15
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19
20
21VideoView::VideoView(BRect frame, const char *name, uint32 resizeMask, uint32 flags, VideoNode *node)
22 :	BView(frame, name, resizeMask, flags)
23 ,	fVideoNode(node)
24 ,	fOverlayActive(false)
25{
26	SetViewColor(B_TRANSPARENT_COLOR);
27}
28
29
30VideoView::~VideoView()
31{
32}
33
34
35void
36VideoView::AttachedToWindow()
37{
38}
39
40
41VideoNode *
42VideoView::Node()
43{
44	return fVideoNode;
45}
46
47
48void
49VideoView::OverlayLockAcquire()
50{
51	CALLED();
52}
53
54
55void
56VideoView::OverlayLockRelease()
57{
58	CALLED();
59	// overlaybitmap->UnlockBits
60}
61
62
63void
64VideoView::OverlayScreenshotPrepare()
65{
66	CALLED();
67/*
68	fVideoNode->LockBitmap();
69	if (fOverlayActive) {
70		BBitmap *bmp = fVideoNode->Bitmap();
71		if (bmp) {
72//			Window()->UpdateIfNeeded();
73//			Sync();
74			BBitmap *tmp = new BBitmap(bmp->Bounds(), 0, B_RGB32);
75//			ConvertBitmap(tmp, bmp);
76			ClearViewOverlay();
77			DrawBitmap(tmp, Bounds());
78			delete tmp;
79//			Sync();
80		}
81	}
82	fVideoNode->UnlockBitmap();
83*/
84}
85
86
87void
88VideoView::OverlayScreenshotCleanup()
89{
90	CALLED();
91/*
92	snooze(50000); // give app server some time to take the screenshot
93	fVideoNode->LockBitmap();
94	if (fOverlayActive) {
95		BBitmap *bmp = fVideoNode->Bitmap();
96		if (bmp) {
97			DrawBitmap(bmp, Bounds());
98			SetViewOverlay(bmp, bmp->Bounds(), Bounds(), &fOverlayKeyColor,
99				B_FOLLOW_ALL, B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL);
100			Invalidate();
101		}
102	}
103	fVideoNode->UnlockBitmap();
104*/
105}
106
107
108void
109VideoView::RemoveVideoDisplay()
110{
111	CALLED();
112
113	if (fOverlayActive) {
114		ClearViewOverlay();
115		fOverlayActive = false;
116	}
117	Invalidate();
118}
119
120
121void
122VideoView::RemoveOverlay()
123{
124	CALLED();
125	if (LockLooperWithTimeout(50000) == B_OK) {
126		ClearViewOverlay();
127		fOverlayActive = false;
128		UnlockLooper();
129	}
130}
131
132
133void
134VideoView::Draw(BRect updateRect)
135{
136	if (fOverlayActive) {
137		SetHighColor(fOverlayKeyColor);
138		FillRect(updateRect);
139	} else {
140		fVideoNode->LockBitmap();
141		BBitmap *bmp = fVideoNode->Bitmap();
142		if (!bmp) {
143			SetHighColor(0, 0, 0, 0);
144			FillRect(updateRect);
145		} else
146			DrawBitmap(bmp, Bounds());
147		fVideoNode->UnlockBitmap();
148	}
149}
150
151
152void
153VideoView::DrawFrame()
154{
155	//CALLED();
156
157	bool want_overlay = fVideoNode->IsOverlayActive();
158
159	if (!want_overlay && fOverlayActive) {
160		if (LockLooperWithTimeout(50000) == B_OK) {
161			ClearViewOverlay();
162			UnlockLooper();
163			fOverlayActive = false;
164		} else {
165			fprintf(stderr, "VideoView::DrawFrame: cannot ClearViewOverlay, as LockLooperWithTimeout failed\n");
166		}
167	}
168
169	if (want_overlay && !fOverlayActive) {
170		fVideoNode->LockBitmap();
171		BBitmap *bmp = fVideoNode->Bitmap();
172		if (bmp && LockLooperWithTimeout(50000) == B_OK) {
173			SetViewOverlay(bmp, bmp->Bounds(), Bounds(), &fOverlayKeyColor,
174				B_FOLLOW_ALL, B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL);
175			fOverlayActive = true;
176
177			Invalidate();
178			UnlockLooper();
179		}
180		fVideoNode->UnlockBitmap();
181	}
182	if (!fOverlayActive) {
183		if (LockLooperWithTimeout(50000) != B_OK)
184			return;
185		Invalidate();
186		UnlockLooper();
187	}
188}
189
190
191void
192VideoView::MessageReceived(BMessage *msg)
193{
194	switch (msg->what) {
195
196		default:
197			BView::MessageReceived(msg);
198	}
199}
200
201
202bool
203VideoView::IsOverlaySupported()
204{
205	struct colorcombo {
206		color_space colspace;
207		const char *name;
208	} colspace[] = {
209		{ B_RGB32,		"B_RGB32"},
210		{ B_RGBA32,		"B_RGBA32"},
211		{ B_RGB24,		"B_RGB24"},
212		{ B_RGB16,		"B_RGB16"},
213		{ B_RGB15,		"B_RGB15"},
214		{ B_RGBA15,		"B_RGBA15"},
215		{ B_RGB32_BIG,	"B_RGB32_BIG"},
216		{ B_RGBA32_BIG,	"B_RGBA32_BIG "},
217		{ B_RGB24_BIG,	"B_RGB24_BIG "},
218		{ B_RGB16_BIG,	"B_RGB16_BIG "},
219		{ B_RGB15_BIG,	"B_RGB15_BIG "},
220		{ B_RGBA15_BIG, "B_RGBA15_BIG "},
221		{ B_YCbCr422,	"B_YCbCr422"},
222		{ B_YCbCr411,	"B_YCbCr411"},
223		{ B_YCbCr444,	"B_YCbCr444"},
224		{ B_YCbCr420,	"B_YCbCr420"},
225		{ B_YUV422,		"B_YUV422"},
226		{ B_YUV411,		"B_YUV411"},
227		{ B_YUV444,		"B_YUV444"},
228		{ B_YUV420,		"B_YUV420"},
229		{ B_NO_COLOR_SPACE, NULL}
230	};
231
232	bool supported = false;
233	for (int i = 0; colspace[i].name; i++) {
234		BBitmap *test = new BBitmap(BRect(0,0,320,240),	B_BITMAP_WILL_OVERLAY | B_BITMAP_RESERVE_OVERLAY_CHANNEL, colspace[i].colspace);
235		if (test->InitCheck() == B_OK) {
236			printf("Display supports %s (0x%08x) overlay\n", colspace[i].name, colspace[i].colspace);
237			supported = true;
238		}
239		delete test;
240//		if (supported)
241//			break;
242	}
243	return supported;
244}
245