Files
haiku-beta6/src/apps/mediaplayer/VideoView.cpp
T

270 lines
5.8 KiB
C++
Raw Normal View History

/*
* VideoView.cpp - Media Player for the Haiku Operating System
*
* Copyright (C) 2006 Marcus Overhagen <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include <Message.h>
#include <Bitmap.h>
#include "VideoView.h"
#include <stdio.h>
#include <string.h>
VideoView::VideoView(BRect frame, const char *name, uint32 resizeMask, uint32 flags)
: BView(frame, name, resizeMask, flags)
, fController(NULL)
, fOverlayActive(false)
{
SetViewColor(B_TRANSPARENT_COLOR);
// SetViewColor(127,255,127);
rgb_color r = {255, 0, 0, 255};
fOverlayKeyColor = r;
}
VideoView::~VideoView()
{
}
void
VideoView::SetController(Controller *controller)
{
fController = controller;
}
void
VideoView::AttachedToWindow()
{
}
void
VideoView::OverlayLockAcquire()
{
printf("VideoView::OverlayLockAcquire\n");
}
void
VideoView::OverlayLockRelease()
{
printf("VideoView::OverlayLockRelease\n");
// overlaybitmap->UnlockBits
}
void
VideoView::OverlayScreenshotPrepare()
{
printf("OverlayScreenshotPrepare enter\n");
/*
fController->LockBitmap();
if (fOverlayActive) {
BBitmap *bmp = fController->Bitmap();
if (bmp) {
// Window()->UpdateIfNeeded();
// Sync();
BBitmap *tmp = new BBitmap(bmp->Bounds(), 0, B_RGB32);
// ConvertBitmap(tmp, bmp);
ClearViewOverlay();
DrawBitmap(tmp, Bounds());
delete tmp;
// Sync();
}
}
fController->UnlockBitmap();
*/
printf("OverlayScreenshotPrepare leave\n");
}
void
VideoView::OverlayScreenshotCleanup()
{
printf("OverlayScreenshotCleanup enter\n");
/*
snooze(50000); // give app server some time to take the screenshot
fController->LockBitmap();
if (fOverlayActive) {
BBitmap *bmp = fController->Bitmap();
if (bmp) {
DrawBitmap(bmp, Bounds());
SetViewOverlay(bmp, bmp->Bounds(), Bounds(), &fOverlayKeyColor,
B_FOLLOW_ALL, B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL);
Invalidate();
}
}
fController->UnlockBitmap();
*/
printf("OverlayScreenshotCleanup leave\n");
}
void
VideoView::RemoveVideoDisplay()
{
printf("VideoView::RemoveVideoDisplay\n");
if (fOverlayActive) {
ClearViewOverlay();
fOverlayActive = false;
}
Invalidate();
}
void
VideoView::RemoveOverlay()
{
printf("VideoView::RemoveOverlay\n");
if (LockLooperWithTimeout(50000) == B_OK) {
ClearViewOverlay();
fOverlayActive = false;
UnlockLooper();
}
}
void
VideoView::Draw(BRect updateRect)
{
if (fOverlayActive) {
SetHighColor(fOverlayKeyColor);
FillRect(updateRect);
} else {
fController->LockBitmap();
BBitmap *bmp = fController->Bitmap();
if (bmp)
DrawBitmap(bmp, Bounds());
fController->UnlockBitmap();
}
}
void
VideoView::DrawFrame()
{
// printf("VideoView::DrawFrame\n");
if (LockLooperWithTimeout(50000) != B_OK)
return;
fController->LockBitmap();
BBitmap *bmp = fController->Bitmap();
if (bmp) {
bool want_overlay = bmp->ColorSpace() == B_YCbCr422;
if (!want_overlay && fOverlayActive) {
if (LockLooperWithTimeout(50000) == B_OK) {
ClearViewOverlay();
UnlockLooper();
fOverlayActive = false;
} else {
printf("can't ClearViewOverlay, as LockLooperWithTimeout failed\n");
return;
}
}
if (want_overlay && !fOverlayActive ) {
printf("trying to activate overlay...");
// reserve overlay channel
status_t ret = SetViewOverlay(bmp, bmp->Bounds(), Bounds(),
&fOverlayKeyColor, B_FOLLOW_ALL,
B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL);
if (ret == B_OK) {
printf("success\n");
fOverlayActive = true;
Invalidate();
} else {
printf("failed: %s\n", strerror(ret));
}
} else if (fOverlayActive) {
// transfer overlay channel
rgb_color overlayKey;
SetViewOverlay(bmp, bmp->Bounds(), Bounds(), &overlayKey,
B_FOLLOW_ALL, B_OVERLAY_TRANSFER_CHANNEL
| B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL);
} else {
// no overlay
DrawBitmap(bmp, Bounds());
}
}
fController->UnlockBitmap();
UnlockLooper();
}
void
VideoView::MessageReceived(BMessage *msg)
{
switch (msg->what) {
default:
BView::MessageReceived(msg);
}
}
bool
VideoView::IsOverlaySupported()
{
struct colorcombo {
color_space colspace;
const char *name;
} colspace[] = {
{ B_RGB32, "B_RGB32"},
{ B_RGBA32, "B_RGBA32"},
{ B_RGB24, "B_RGB24"},
{ B_RGB16, "B_RGB16"},
{ B_RGB15, "B_RGB15"},
{ B_RGBA15, "B_RGBA15"},
{ B_RGB32_BIG, "B_RGB32_BIG"},
{ B_RGBA32_BIG, "B_RGBA32_BIG "},
{ B_RGB24_BIG, "B_RGB24_BIG "},
{ B_RGB16_BIG, "B_RGB16_BIG "},
{ B_RGB15_BIG, "B_RGB15_BIG "},
{ B_RGBA15_BIG, "B_RGBA15_BIG "},
{ B_YCbCr422, "B_YCbCr422"},
{ B_YCbCr411, "B_YCbCr411"},
{ B_YCbCr444, "B_YCbCr444"},
{ B_YCbCr420, "B_YCbCr420"},
{ B_YUV422, "B_YUV422"},
{ B_YUV411, "B_YUV411"},
{ B_YUV444, "B_YUV444"},
{ B_YUV420, "B_YUV420"},
{ B_NO_COLOR_SPACE, NULL}
};
bool supported = false;
for (int i = 0; colspace[i].name; i++) {
BBitmap *test = new BBitmap(BRect(0,0,319,239), B_BITMAP_WILL_OVERLAY | B_BITMAP_RESERVE_OVERLAY_CHANNEL, colspace[i].colspace);
if (test->InitCheck() == B_OK) {
printf("Display supports %s (0x%08x) overlay\n", colspace[i].name, colspace[i].colspace);
supported = true;
}
delete test;
// if (supported)
// break;
}
return supported;
}