Commit 9014b460 authored by Sam Hocevar's avatar Sam Hocevar

   Commited BeOS changes by Richard Shepherd and Tony Castley.

   include/video_output.h
    * Added boolean_t b_YCbr to vout_thread_s structure to flag YUV-YCbCr
      decoding needed instead of YUV-RGB
    * Will be removed later when video_output.c rewritten

   src/video_output.c
    * vout_CreateThread() initialises b_YCbr to zero

   plugins/beos/*
    * New BeOS video plugin that supports hardware overlays and new
      MediaPlayer compatible interface

   plugins/*
    * Added YUV-YCbCr transforms
parent 3fab36dc
......@@ -22,3 +22,6 @@
Renaud Dartus <reno@via.ecp.fr>
Henri Fallon <henri@via.ecp.fr>
Richard Shepherd <richard@rshepherd.demon.co.uk>
Tony Castley <tcastley@mail.powerup.com.au>
......@@ -288,7 +288,9 @@ PLUGIN_ALSA = plugins/alsa/alsa.o \
PLUGIN_BEOS = plugins/beos/beos.o \
plugins/beos/aout_beos.o \
plugins/beos/intf_beos.o \
plugins/beos/vout_beos.o
plugins/beos/vout_beos.o \
plugins/beos/DrawingTidbits.o \
plugins/beos/TransportButton.o
PLUGIN_DSP = plugins/dsp/dsp.o \
plugins/dsp/aout_dsp.o
......
......@@ -56,9 +56,9 @@ typedef void (yuv_end_t) ( p_vout_thread_t p_vout );
typedef struct vout_yuv_s
{
/* conversion functions */
vout_yuv_convert_t * p_Convert420; /* YUV 4:2:0 converter */
vout_yuv_convert_t * p_Convert422; /* YUV 4:2:2 converter */
vout_yuv_convert_t * p_Convert444; /* YUV 4:4:4 converter */
vout_yuv_convert_t *pf_yuv420; /* YUV 4:2:0 converter */
vout_yuv_convert_t *pf_yuv422; /* YUV 4:2:2 converter */
vout_yuv_convert_t *pf_yuv444; /* YUV 4:4:4 converter */
/* Pre-calculated conversion tables */
void * p_base; /* base for all conversion tables */
......@@ -166,6 +166,7 @@ typedef struct vout_thread_s
/* Pictures and rendering properties */
boolean_t b_grayscale; /* color or grayscale display */
boolean_t b_YCbr; /* use YUV to YCbr instead of RGB */
boolean_t b_info; /* print additional information */
boolean_t b_interface; /* render interface */
boolean_t b_scale; /* allow picture scaling */
......@@ -197,7 +198,9 @@ typedef struct vout_thread_s
p_vout_font_t p_default_font; /* default font */
p_vout_font_t p_large_font; /* large font */
#ifdef STATS
count_t c_loops;
#endif
} vout_thread_t;
/* Flags for changes - these flags are set in the i_changes field when another
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/*****************************************************************************
* DrawingTidbits.cpp
*****************************************************************************
* Copyright (C) 2001 VideoLAN
*
* Authors:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <Bitmap.h>
#include <Debug.h>
#include <Screen.h>
#include "DrawingTidbits.h"
inline uchar
ShiftComponent(uchar component, float percent)
{
// change the color by <percent>, make sure we aren't rounding
// off significant bits
if (percent >= 1)
return (uchar)(component * (2 - percent));
else
return (uchar)(255 - percent * (255 - component));
}
rgb_color
ShiftColor(rgb_color color, float percent)
{
rgb_color result = {
ShiftComponent(color.red, percent),
ShiftComponent(color.green, percent),
ShiftComponent(color.blue, percent),
0
};
return result;
}
static bool
CompareColors(const rgb_color a, const rgb_color b)
{
return a.red == b.red
&& a.green == b.green
&& a.blue == b.blue
&& a.alpha == b.alpha;
}
bool
operator==(const rgb_color &a, const rgb_color &b)
{
return CompareColors(a, b);
}
bool
operator!=(const rgb_color &a, const rgb_color &b)
{
return !CompareColors(a, b);
}
void
ReplaceColor(BBitmap *bitmap, rgb_color from, rgb_color to)
{
ASSERT(bitmap->ColorSpace() == B_COLOR_8_BIT); // other color spaces not implemented yet
BScreen screen(B_MAIN_SCREEN_ID);
uint32 fromIndex = screen.IndexForColor(from);
uint32 toIndex = screen.IndexForColor(to);
uchar *bits = (uchar *)bitmap->Bits();
int32 bitsLength = bitmap->BitsLength();
for (int32 index = 0; index < bitsLength; index++)
if (bits[index] == fromIndex)
bits[index] = toIndex;
}
void
ReplaceTransparentColor(BBitmap *bitmap, rgb_color with)
{
ASSERT(bitmap->ColorSpace() == B_COLOR_8_BIT); // other color spaces not implemented yet
BScreen screen(B_MAIN_SCREEN_ID);
uint32 withIndex = screen.IndexForColor(with);
uchar *bits = (uchar *)bitmap->Bits();
int32 bitsLength = bitmap->BitsLength();
for (int32 index = 0; index < bitsLength; index++)
if (bits[index] == B_TRANSPARENT_8_BIT)
bits[index] = withIndex;
}
/*****************************************************************************
* DrawingTidbits.h
*****************************************************************************
* Copyright (C) 2001 VideoLAN
*
* Authors:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#ifndef __DRAWING_TIBITS__
#define __DRAWING_TIBITS__
#include <GraphicsDefs.h>
rgb_color ShiftColor(rgb_color , float );
bool operator==(const rgb_color &, const rgb_color &);
bool operator!=(const rgb_color &, const rgb_color &);
inline rgb_color
Color(int32 r, int32 g, int32 b, int32 alpha = 255)
{
rgb_color result;
result.red = r;
result.green = g;
result.blue = b;
result.alpha = alpha;
return result;
}
const rgb_color kWhite = { 255, 255, 255, 255};
const rgb_color kBlack = { 0, 0, 0, 255};
const float kDarkness = 1.06;
const float kDimLevel = 0.6;
void ReplaceColor(BBitmap *bitmap, rgb_color from, rgb_color to);
void ReplaceTransparentColor(BBitmap *bitmap, rgb_color with);
#endif
/*****************************************************************************
* window.h: BeOS window class prototype
* InterfaceWindow.h: BeOS interface window class prototype
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* Copyright (C) 1999, 2000, 2001 VideoLAN
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
*
......@@ -20,26 +20,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
class VideoWindow : public BWindow
{
public:
// standard constructor and destructor
VideoWindow( BRect frame, const char *name,
struct vout_thread_s *p_video_output);
~VideoWindow();
// standard window member
virtual bool QuitRequested();
virtual void FrameResized(float width, float height);
virtual void MessageReceived(BMessage *message);
struct vout_thread_s *p_vout;
BView * p_view;
// additional events
bool b_resized;
};
class InterfaceWindow : public BWindow
{
public:
......@@ -51,6 +31,11 @@ public:
virtual void MessageReceived(BMessage *message);
intf_thread_t *p_intf;
BSlider * p_vol;
BSlider * p_seek;
BCheckBox * p_mute;
sem_id fScrubSem;
bool fSeeking;
};
class InterfaceView : public BView
......@@ -60,5 +45,24 @@ public:
~InterfaceView();
virtual void MessageReceived(BMessage *message);
};
class SeekSlider : public BSlider
{
public:
SeekSlider(BRect frame,
InterfaceWindow *owner,
int32 minValue,
int32 maxValue,
thumb_style thumbType = B_TRIANGLE_THUMB);
~SeekSlider();
virtual void MouseDown(BPoint);
virtual void MouseUp(BPoint pt);
virtual void MouseMoved(BPoint pt, uint32 c, const BMessage *m);
private:
InterfaceWindow* fOwner;
bool fMouseDown;
};
/*****************************************************************************
* MsgVals.h
*****************************************************************************
* Copyright (C) 2001 VideoLAN
*
* Authors:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/* MsgVals.h */
#define PLAYING 0
#define PAUSED 1
const uint32 OPEN_DVD = 'OPDV';
const uint32 STOP_PLAYBACK = 'STPL';
const uint32 START_PLAYBACK = 'PLAY';
const uint32 PAUSE_PLAYBACK = 'PAPL';
const uint32 FASTER_PLAY = 'FAPL';
const uint32 SLOWER_PLAY = 'SLPL';
const uint32 SEEK_PLAYBACK = 'SEEK';
const uint32 VOLUME_CHG = 'VOCH';
const uint32 VOLUME_MUTE = 'MUTE';
const uint32 SELECT_CHANNEL = 'CHAN';
/*****************************************************************************
* TransportButton.cpp
*****************************************************************************
* Copyright (C) 2001 VideoLAN
*
* Authors:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <Bitmap.h>
#include <Debug.h>
#include <MessageFilter.h>
#include <Screen.h>
#include <Window.h>
#include <map>
#include "TransportButton.h"
#include "DrawingTidbits.h"
class BitmapStash {
// Bitmap stash is a simple class to hold all the lazily-allocated
// bitmaps that the TransportButton needs when rendering itself.
// signature is a combination of the different enabled, pressed, playing, etc.
// flavors of a bitmap. If the stash does not have a particular bitmap,
// it turns around to ask the button to create one and stores it for next time.
public:
BitmapStash(TransportButton *);
~BitmapStash();
BBitmap *GetBitmap(uint32 signature);
private:
TransportButton *owner;
map<uint32, BBitmap *> stash;
};
BitmapStash::BitmapStash(TransportButton *owner)
: owner(owner)
{
}
BBitmap *
BitmapStash::GetBitmap(uint32 signature)
{
if (stash.find(signature) == stash.end()) {
BBitmap *newBits = owner->MakeBitmap(signature);
ASSERT(newBits);
stash[signature] = newBits;
}
return stash[signature];
}
BitmapStash::~BitmapStash()
{
// delete all the bitmaps
for (map<uint32, BBitmap *>::iterator i = stash.begin(); i != stash.end(); i++)
delete (*i).second;
}
class PeriodicMessageSender {
// used to send a specified message repeatedly when holding down a button
public:
static PeriodicMessageSender *Launch(BMessenger target,
const BMessage *message, bigtime_t period);
void Quit();
private:
PeriodicMessageSender(BMessenger target, const BMessage *message,
bigtime_t period);
~PeriodicMessageSender() {}
// use quit
static status_t TrackBinder(void *);
void Run();
BMessenger target;
BMessage message;
bigtime_t period;
bool requestToQuit;
};
PeriodicMessageSender::PeriodicMessageSender(BMessenger target,
const BMessage *message, bigtime_t period)
: target(target),
message(*message),
period(period),
requestToQuit(false)
{
}
PeriodicMessageSender *
PeriodicMessageSender::Launch(BMessenger target, const BMessage *message,
bigtime_t period)
{
PeriodicMessageSender *result = new PeriodicMessageSender(target, message, period);
thread_id thread = spawn_thread(&PeriodicMessageSender::TrackBinder,
"ButtonRepeatingThread", B_NORMAL_PRIORITY, result);
if (thread <= 0 || resume_thread(thread) != B_OK) {
// didn't start, don't leak self
delete result;
result = 0;
}
return result;
}
void
PeriodicMessageSender::Quit()
{
requestToQuit = true;
}
status_t
PeriodicMessageSender::TrackBinder(void *castToThis)
{
((PeriodicMessageSender *)castToThis)->Run();
return 0;
}
void
PeriodicMessageSender::Run()
{
for (;;) {
snooze(period);
if (requestToQuit)
break;
target.SendMessage(&message);
}
delete this;
}
class SkipButtonKeypressFilter : public BMessageFilter {
public:
SkipButtonKeypressFilter(uint32 shortcutKey, uint32 shortcutModifier,
TransportButton *target);
protected:
filter_result Filter(BMessage *message, BHandler **handler);
private:
uint32 shortcutKey;
uint32 shortcutModifier;
TransportButton *target;
};
SkipButtonKeypressFilter::SkipButtonKeypressFilter(uint32 shortcutKey,
uint32 shortcutModifier, TransportButton *target)
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE),
shortcutKey(shortcutKey),
shortcutModifier(shortcutModifier),
target(target)
{
}
filter_result
SkipButtonKeypressFilter::Filter(BMessage *message, BHandler **handler)
{
if (target->IsEnabled()
&& (message->what == B_KEY_DOWN || message->what == B_KEY_UP)) {
uint32 modifiers;
uint32 rawKeyChar = 0;
uint8 byte = 0;
int32 key = 0;
if (message->FindInt32("modifiers", (int32 *)&modifiers) != B_OK
|| message->FindInt32("raw_char", (int32 *)&rawKeyChar) != B_OK
|| message->FindInt8("byte", (int8 *)&byte) != B_OK
|| message->FindInt32("key", &key) != B_OK)
return B_DISPATCH_MESSAGE;
modifiers &= B_SHIFT_KEY | B_COMMAND_KEY | B_CONTROL_KEY
| B_OPTION_KEY | B_MENU_KEY;
// strip caps lock, etc.
if (modifiers == shortcutModifier && rawKeyChar == shortcutKey) {
if (message->what == B_KEY_DOWN)
target->ShortcutKeyDown();
else
target->ShortcutKeyUp();
return B_SKIP_MESSAGE;
}
}
// let others deal with this
return B_DISPATCH_MESSAGE;
}
TransportButton::TransportButton(BRect frame, const char *name,
const unsigned char *normalBits,
const unsigned char *pressedBits,
const unsigned char *disabledBits,
BMessage *invokeMessage, BMessage *startPressingMessage,
BMessage *pressingMessage, BMessage *donePressingMessage, bigtime_t period,
uint32 key, uint32 modifiers, uint32 resizeFlags)
: BControl(frame, name, "", invokeMessage, resizeFlags, B_WILL_DRAW | B_NAVIGABLE),
bitmaps(new BitmapStash(this)),
normalBits(normalBits),
pressedBits(pressedBits),
disabledBits(disabledBits),
startPressingMessage(startPressingMessage),
pressingMessage(pressingMessage),
donePressingMessage(donePressingMessage),
pressingPeriod(period),
mouseDown(false),
keyDown(false),
messageSender(0),
keyPressFilter(0)
{
if (key)
keyPressFilter = new SkipButtonKeypressFilter(key, modifiers, this);
}
void
TransportButton::AttachedToWindow()
{
_inherited::AttachedToWindow();
if (keyPressFilter)
Window()->AddCommonFilter(keyPressFilter);
// transparent to reduce flicker
SetViewColor(B_TRANSPARENT_COLOR);
}
void
TransportButton::DetachedFromWindow()
{
if (keyPressFilter) {
Window()->RemoveCommonFilter(keyPressFilter);
delete keyPressFilter;
}
_inherited::DetachedFromWindow();
}
TransportButton::~TransportButton()
{
delete startPressingMessage;
delete pressingMessage;
delete donePressingMessage;
delete bitmaps;
}
void
TransportButton::WindowActivated(bool state)
{
if (!state)
ShortcutKeyUp();
_inherited::WindowActivated(state);
}
void
TransportButton::SetEnabled(bool on)
{
_inherited::SetEnabled(on);
if (!on)
ShortcutKeyUp();
}
const unsigned char *
TransportButton::BitsForMask(uint32 mask) const
{
switch (mask) {
case 0:
return normalBits;
case kDisabledMask:
return disabledBits;
case kPressedMask:
return pressedBits;
default:
break;
}
TRESPASS();
return 0;
}
BBitmap *
TransportButton::MakeBitmap(uint32 mask)
{
BBitmap *result = new BBitmap(Bounds(), B_COLOR_8_BIT);
result->SetBits(BitsForMask(mask), (Bounds().Width() + 1) * (Bounds().Height() + 1),
0, B_COLOR_8_BIT);
ReplaceTransparentColor(result, Parent()->ViewColor());
return result;
}
uint32
TransportButton::ModeMask() const
{
return (IsEnabled() ? 0 : kDisabledMask)
| (Value() ? kPressedMask : 0);
}
void
TransportButton::Draw(BRect)
{
DrawBitmapAsync(bitmaps->GetBitmap(ModeMask()));
}
void
TransportButton::StartPressing()
{
SetValue(1);
if (startPressingMessage)
Invoke(startPressingMessage);
if (pressingMessage) {
ASSERT(pressingMessage);
messageSender = PeriodicMessageSender::Launch(Messenger(),
pressingMessage, pressingPeriod);
}
}
void
TransportButton::MouseCancelPressing()
{
if (!mouseDown || keyDown)
return;
mouseDown = false;
if (pressingMessage) {
ASSERT(messageSender);
PeriodicMessageSender *sender = messageSender;
messageSender = 0;
sender->Quit();
}
if (donePressingMessage)
Invoke(donePressingMessage);
SetValue(0);
}
void
TransportButton::DonePressing()
{
if (pressingMessage) {
ASSERT(messageSender);
PeriodicMessageSender *sender = messageSender;
messageSender = 0;
sender->Quit();
}
Invoke();
SetValue(0);
}
void
TransportButton::MouseStartPressing()
{
if (mouseDown)
return;
mouseDown = true;
if (!keyDown)
StartPressing();
}
void
TransportButton::MouseDonePressing()
{
if (!mouseDown)
return;
mouseDown = false;
if (!keyDown)
DonePressing();
}
void
TransportButton::ShortcutKeyDown()
{
if (!IsEnabled())
return;
if (keyDown)
return;
keyDown = true;
if (!mouseDown)
StartPressing();
}
void
TransportButton::ShortcutKeyUp()
{
if (!keyDown)
return;
keyDown = false;
if (!mouseDown)
DonePressing();
}
void
TransportButton::MouseDown(BPoint)
{
if (!IsEnabled())
return;
ASSERT(Window()->Flags() & B_ASYNCHRONOUS_CONTROLS);
SetTracking(true);
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
MouseStartPressing();
}
void
TransportButton::MouseMoved(BPoint point, uint32 code, const BMessage *)
{
if (IsTracking() && Bounds().Contains(point) != Value()) {
if (!Value())
MouseStartPressing();
else
MouseCancelPressing();
}
}
void
TransportButton::MouseUp(BPoint point)
{
if (IsTracking()) {
if (Bounds().Contains(point))
MouseDonePressing();
else
MouseCancelPressing();
SetTracking(false);
}
}
void
TransportButton::SetStartPressingMessage(BMessage *message)
{
delete startPressingMessage;
startPressingMessage = message;
}
void
TransportButton::SetPressingMessage(BMessage *message)
{
delete pressingMessage;
pressingMessage = message;
}
void
TransportButton::SetDonePressingMessage(BMessage *message)
{
delete donePressingMessage;
donePressingMessage = message;
}
void
TransportButton::SetPressingPeriod(bigtime_t newTime)
{
pressingPeriod = newTime;
}
PlayPauseButton::PlayPauseButton(BRect frame, const char *name,
const unsigned char *normalBits, const unsigned char *pressedBits,
const unsigned char *disabledBits, const unsigned char *normalPlayingBits,
const unsigned char *pressedPlayingBits, const unsigned char *normalPausedBits,
const unsigned char *pressedPausedBits,
BMessage *invokeMessage, uint32 key, uint32 modifiers, uint32 resizeFlags)
: TransportButton(frame, name, normalBits, pressedBits,
disabledBits, invokeMessage, 0,
0, 0, 0, key, modifiers, resizeFlags),
normalPlayingBits(normalPlayingBits),
pressedPlayingBits(pressedPlayingBits),
normalPausedBits(normalPausedBits),
pressedPausedBits(pressedPausedBits),
state(PlayPauseButton::kStopped),
lastPauseBlinkTime(0),
lastModeMask(0)
{
}
void
PlayPauseButton::SetStopped()
{
if (state == kStopped || state == kAboutToPlay)
return;
state = kStopped;
Invalidate();
}
void
PlayPauseButton::SetPlaying()
{
if (state == kPlaying || state == kAboutToPause)
return;
state = kPlaying;
Invalidate();
}
const bigtime_t kPauseBlinkPeriod = 600000;
void
PlayPauseButton::SetPaused()
{
if (state == kAboutToPlay)
return;
// in paused state blink the LED on and off
bigtime_t now = system_time();
if (state == kPausedLedOn || state == kPausedLedOff) {
if (now - lastPauseBlinkTime < kPauseBlinkPeriod)
return;
if (state == kPausedLedOn)
state = kPausedLedOff;
else
state = kPausedLedOn;
} else
state = kPausedLedOn;
lastPauseBlinkTime = now;
Invalidate();
}
uint32
PlayPauseButton::ModeMask() const
{
if (!IsEnabled())
return kDisabledMask;
uint32 result = 0;
if (Value())
result = kPressedMask;
if (state == kPlaying || state == kAboutToPlay)
result |= kPlayingMask;
else if (state == kAboutToPause || state == kPausedLedOn)
result |= kPausedMask;
return result;
}
const unsigned char *
PlayPauseButton::BitsForMask(uint32 mask) const
{
switch (mask) {
case kPlayingMask:
return normalPlayingBits;
case kPlayingMask | kPressedMask:
return pressedPlayingBits;
case kPausedMask:
return normalPausedBits;
case kPausedMask | kPressedMask:
return pressedPausedBits;
default:
return _inherited::BitsForMask(mask);
}
TRESPASS();
return 0;
}
void
PlayPauseButton::StartPressing()
{
if (state == kPlaying)
state = kAboutToPause;
else
state = kAboutToPlay;
_inherited::StartPressing();
}
void
PlayPauseButton::MouseCancelPressing()
{
if (state == kAboutToPause)
state = kPlaying;
else
state = kStopped;
_inherited::MouseCancelPressing();
}
void
PlayPauseButton::DonePressing()
{
if (state == kAboutToPause) {
state = kPausedLedOn;
lastPauseBlinkTime = system_time();
} else if (state == kAboutToPlay)
state = kPlaying;
_inherited::DonePressing();
}
/*****************************************************************************
* TransportButton.h
*****************************************************************************
* Copyright (C) 2001 VideoLAN
*
* Authors:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#ifndef __MEDIA_BUTTON__
#define __MEDIA_BUTTON__
#include <Control.h>
class BMessage;
class BBitmap;
class PeriodicMessageSender;
class BitmapStash;
// TransportButton must be installed into a window with B_ASYNCHRONOUS_CONTROLS on
// currently no button focus drawing
class TransportButton : public BControl {
public:
TransportButton(BRect frame, const char *name,
const unsigned char *normalBits,
const unsigned char *pressedBits,
const unsigned char *disabledBits,
BMessage *invokeMessage, // done pressing over button
BMessage *startPressingMessage = 0, // just clicked button
BMessage *pressingMessage = 0, // periodical still pressing
BMessage *donePressing = 0, // tracked out of button/didn't invoke
bigtime_t period = 0, // pressing message period
uint32 key = 0, // optional shortcut key
uint32 modifiers = 0, // optional shortcut key modifier
uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP);
virtual ~TransportButton();
void SetStartPressingMessage(BMessage *);
void SetPressingMessage(BMessage *);
void SetDonePressingMessage(BMessage *);
void SetPressingPeriod(bigtime_t);
virtual void SetEnabled(bool);
protected:
enum {
kDisabledMask = 0x1,
kPressedMask = 0x2
};
virtual void AttachedToWindow();
virtual void DetachedFromWindow();
virtual void Draw(BRect);
virtual void MouseDown(BPoint);
virtual void MouseMoved(BPoint, uint32 code, const BMessage *);
virtual void MouseUp(BPoint);
virtual void WindowActivated(bool);
virtual BBitmap *MakeBitmap(uint32);
// lazy bitmap builder
virtual uint32 ModeMask() const;
// mode mask corresponding to the current button state
// - determines which bitmap will be used
virtual const unsigned char *BitsForMask(uint32) const;
// pick the right bits based on a mode mask
// overriding class can add swapping between two pairs of bitmaps, etc.
virtual void StartPressing();
virtual void MouseCancelPressing();
virtual void DonePressing();
private:
void ShortcutKeyDown();
void ShortcutKeyUp();
void MouseStartPressing();
void MouseDonePressing();
BitmapStash *bitmaps;
// using BitmapStash * here instead of a direct member so that the class can be private in
// the .cpp file
// bitmap bits used to build bitmaps for the different states
const unsigned char *normalBits;
const unsigned char *pressedBits;
const unsigned char *disabledBits;
BMessage *startPressingMessage;
BMessage *pressingMessage;
BMessage *donePressingMessage;
bigtime_t pressingPeriod;
bool mouseDown;
bool keyDown;
PeriodicMessageSender *messageSender;
BMessageFilter *keyPressFilter;
typedef BControl _inherited;
friend class SkipButtonKeypressFilter;
friend class BitmapStash;
};
class PlayPauseButton : public TransportButton {
// Knows about playing and paused states, blinks
// the pause LED during paused state
public:
PlayPauseButton(BRect frame, const char *name,
const unsigned char *normalBits,
const unsigned char *pressedBits,
const unsigned char *disabledBits,
const unsigned char *normalPlayingBits,
const unsigned char *pressedPlayingBits,
const unsigned char *normalPausedBits,
const unsigned char *pressedPausedBits,
BMessage *invokeMessage, // done pressing over button
uint32 key = 0, // optional shortcut key
uint32 modifiers = 0, // optional shortcut key modifier
uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP);
// These need get called periodically to update the button state
// OK to call them over and over - once the state is correct, the call
// is very low overhead
void SetStopped();
void SetPlaying();
void SetPaused();
protected:
virtual uint32 ModeMask() const;
virtual const unsigned char *BitsForMask(uint32) const;
virtual void StartPressing();
virtual void MouseCancelPressing();
virtual void DonePressing();
private:
const unsigned char *normalPlayingBits;
const unsigned char *pressedPlayingBits;
const unsigned char *normalPausedBits;
const unsigned char *pressedPausedBits;
enum PlayState {
kStopped,
kAboutToPlay,
kPlaying,
kAboutToPause,
kPausedLedOn,
kPausedLedOff
};
enum {
kPlayingMask = 0x4,
kPausedMask = 0x8
};
PlayState state;
bigtime_t lastPauseBlinkTime;
uint32 lastModeMask;
typedef TransportButton _inherited;
};
#endif
/*****************************************************************************
* VideoWindow.h: BeOS video window class prototype
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <Slider.h>
#include <Accelerant.h>
#include <Bitmap.h>
class VLCView : public BView
{
public:
VLCView( BRect bounds);
~VLCView();
virtual void MouseDown(BPoint point);
};
class VideoWindow : public BWindow
{
public:
// standard constructor and destructor
VideoWindow( BRect frame, const char *name,
struct vout_thread_s *p_video_output);
~VideoWindow();
// standard window member
virtual bool QuitRequested();
virtual void FrameResized(float width, float height);
virtual void MessageReceived(BMessage *message);
virtual void Zoom(BPoint origin, float width, float height);
// this is the hook controling direct screen connection
int32 i_bytes_per_pixel;
int32 i_screen_depth;
struct vout_thread_s *p_vout;
int32 fRowBytes;
uint32 fNumClipRects;
int i_buffer_index;
bool fDirty;
thread_id fDrawThreadID;
BBitmap *bitmap[2];
VLCView *view;
bool teardownwindow;
bool is_zoomed;
bool fUsingOverlay;
private:
display_mode old_mode;
BRect rect;
};
......@@ -2,7 +2,7 @@
* intf_beos.cpp: beos interface
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: intf_beos.cpp,v 1.11 2001/02/26 12:16:28 sam Exp $
* $Id: intf_beos.cpp,v 1.12 2001/03/04 16:20:16 sam Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
......@@ -35,7 +35,12 @@
#include <kernel/OS.h>
#include <storage/Path.h>
#include <Alert.h>
#include <View.h>
#include <CheckBox.h>
#include <Button.h>
#include <Slider.h>
#include <StatusBar.h>
#include <Application.h>
#include <Message.h>
#include <NodeInfo.h>
......@@ -54,14 +59,22 @@ extern "C"
#include "tests.h"
#include "modules.h"
#include "intf_msg.h"
#include "intf_plst.h"
#include "stream_control.h"
#include "input_ext-intf.h"
#include "interface.h"
#include "intf_plst.h"
#include "intf_msg.h"
#include "audio_output.h"
#include "MsgVals.h"
#include "main.h"
}
#include "window.h"
#include "InterfaceWindow.h"
#include "Bitmaps.h"
#include "TransportButton.h"
/*****************************************************************************
* intf_sys_t: description and status of FB interface
......@@ -77,16 +90,95 @@ typedef struct intf_sys_s
*****************************************************************************/
InterfaceWindow::InterfaceWindow( BRect frame, const char *name , intf_thread_t *p_interface )
: BWindow(frame, name, B_TITLED_WINDOW, B_NOT_ZOOMABLE)
: BWindow(frame, name, B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK |B_ASYNCHRONOUS_CONTROLS)
{
p_intf = p_interface;
BRect ButtonRect;
float xStart = 2.0;
float yStart = 10.0;
SetName( "interface" );
SetTitle("VideoLan Client for BeOS");
BView * p_view;
BView* p_view;
/* Add the view */
p_view = new BView( Bounds(), "", B_FOLLOW_ALL, B_WILL_DRAW );
p_view->SetViewColor(216,216,216);
/* Buttons */
/* Slow play */
ButtonRect.SetLeftTop(BPoint(xStart, yStart));
ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kSkipButtonSize);
xStart += kRewindBitmapWidth;
TransportButton* p_slow = new TransportButton(ButtonRect, B_EMPTY_STRING,
kSkipBackBitmapBits,
kPressedSkipBackBitmapBits,
kDisabledSkipBackBitmapBits,
new BMessage(SLOWER_PLAY));
p_view->AddChild( p_slow );
/* Play Pause */
ButtonRect.SetLeftTop(BPoint(xStart, yStart));
ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kPlayButtonSize);
xStart += kPlayPauseBitmapWidth + 1.0;
PlayPauseButton* p_play = new PlayPauseButton(ButtonRect, B_EMPTY_STRING,
kPlayButtonBitmapBits,
kPressedPlayButtonBitmapBits,
kDisabledPlayButtonBitmapBits,
kPlayingPlayButtonBitmapBits,
kPressedPlayingPlayButtonBitmapBits,
kPausedPlayButtonBitmapBits,
kPressedPausedPlayButtonBitmapBits,
new BMessage(START_PLAYBACK));
p_view->AddChild( p_play );
p_play->SetPlaying();
/* Fast Foward */
ButtonRect.SetLeftTop(BPoint(xStart, yStart));
ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kSkipButtonSize);
xStart += kRewindBitmapWidth;
TransportButton* p_fast = new TransportButton(ButtonRect, B_EMPTY_STRING,
kSkipForwardBitmapBits,
kPressedSkipForwardBitmapBits,
kDisabledSkipForwardBitmapBits,
new BMessage(FASTER_PLAY));
p_view->AddChild( p_fast );
/* Stop */
ButtonRect.SetLeftTop(BPoint(xStart, yStart));
ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kStopButtonSize);
xStart += kStopBitmapWidth;
TransportButton* p_stop = new TransportButton(ButtonRect, B_EMPTY_STRING,
kStopButtonBitmapBits,
kPressedStopButtonBitmapBits,
kDisabledStopButtonBitmapBits,
new BMessage(STOP_PLAYBACK));
p_view->AddChild( p_stop );
/* Seek Status */
p_seek = new SeekSlider(BRect(5,35,355,65), this, 0, 100,
B_TRIANGLE_THUMB);
p_seek->SetValue(0);
p_seek->UseFillColor(TRUE);
p_view->AddChild( p_seek );
/* Volume Slider */
p_vol = new BSlider(BRect(xStart,2,300,20), "vol", "Volume",
new BMessage(VOLUME_CHG), 0, VOLUME_MAX);
p_vol->SetValue(VOLUME_DEFAULT);
p_view->AddChild( p_vol );
/* Volume Mute */
p_mute = new BCheckBox(BRect(300,10,355,25), "mute", "Mute",
new BMessage(VOLUME_MUTE));
p_view->AddChild( p_mute );
/* Set size and Show */
AddChild( p_view );
ResizeTo(360,70);
Show();
}
......@@ -97,18 +189,109 @@ InterfaceWindow::~InterfaceWindow()
/*****************************************************************************
* InterfaceWindow::MessageReceived
*****************************************************************************/
void InterfaceWindow::MessageReceived( BMessage * p_message )
{
char * psz_key;
int vol_val = p_vol->Value(); // remember the current volume
static int playback_status; // remember playback state
Activate();
switch( p_message->what )
{
case B_KEY_DOWN:
p_message->FindString( "bytes", (const char **)&psz_key );
p_intf->p_sys->i_key = psz_key[0];
case OPEN_DVD:
break;
case STOP_PLAYBACK:
// this currently stops playback not nicely
if (p_intf->p_input != NULL )
{
// silence the sound, otherwise very horrible
p_main->p_aout->vol = 0;
snooze(400000);
input_SetStatus(p_intf->p_input, INPUT_STATUS_END);
}
break;
case START_PLAYBACK:
// starts playing in normal mode
// if (p_intf->p_input != NULL )
// {
// p_main->p_aout->vol = vol_val;
// snooze(400000);
// input_SetStatus(p_intf->p_input, INPUT_STATUS_PLAY);
// playback_status = PLAYING;
// }
// break;
case PAUSE_PLAYBACK:
// pause the playback
if (p_intf->p_input != NULL )
{
// mute the volume if currently playing
if (playback_status == PLAYING)
{
p_main->p_aout->vol = 0;
playback_status = PAUSED;
}
else
// restore the volume
{
p_main->p_aout->vol = vol_val;
playback_status = PLAYING;
}
snooze(400000);
input_SetStatus(p_intf->p_input, INPUT_STATUS_PAUSE);
}
break;
case FASTER_PLAY:
// cycle the fast playback modes
if (p_intf->p_input != NULL )
{
p_main->p_aout->vol = 0;
snooze(400000);
input_SetStatus(p_intf->p_input, INPUT_STATUS_FASTER);
}
break;
case SLOWER_PLAY:
// cycle the slow playback modes
if (p_intf->p_input != NULL )
{
p_main->p_aout->vol = 0;
snooze(400000);
input_SetStatus(p_intf->p_input, INPUT_STATUS_SLOWER);
}
break;
case SEEK_PLAYBACK:
// handled by semaphores;
/* if( p_intf->p_input != NULL )
{
float new_position;
if (p_message->FindFloat("be:value", &new_position) == B_OK)
{
printf("%e\n", new_position);
input_Seek( p_intf->p_input, new_position * 100 );
}
} */
break;
case VOLUME_CHG:
// adjust the volume
if (p_main->p_aout != NULL)
{
p_main->p_aout->vol = vol_val;
}
break;
case VOLUME_MUTE:
// mute
if (p_main->p_aout != NULL)
{
if (p_mute->Value() == B_CONTROL_OFF)
{
p_main->p_aout->vol = vol_val;
}
else
{
p_main->p_aout->vol = 0;
}
}
break;
case SELECT_CHANNEL:
break;
case B_SIMPLE_DATA:
{
entry_ref ref;
......@@ -123,7 +306,6 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
}
break;
default:
BWindow::MessageReceived( p_message );
break;
......@@ -141,6 +323,58 @@ bool InterfaceWindow::QuitRequested()
return( false );
}
/*****************************************************************************
* SeekSlider
*****************************************************************************/
SeekSlider::SeekSlider(BRect frame,
InterfaceWindow *owner,
int32 minValue,
int32 maxValue,
thumb_style thumbType = B_TRIANGLE_THUMB)
:BSlider(frame, B_EMPTY_STRING, B_EMPTY_STRING,
NULL, minValue, maxValue, thumbType)
{
fOwner = owner;
fMouseDown = false;
}
SeekSlider::~SeekSlider()
{
}
/*****************************************************************************
* SeekSlider::MouseDown
*****************************************************************************/
void SeekSlider::MouseDown(BPoint where)
{
BSlider::MouseDown(where);
fOwner->fScrubSem = create_sem(1, "Vlc::fScrubSem");
fMouseDown = true;
}
/*****************************************************************************
* SeekSlider::MouseUp
*****************************************************************************/
void SeekSlider::MouseMoved(BPoint where, uint32 code, const BMessage *message)
{
BSlider::MouseMoved(where, code, message);
if (!fMouseDown)
return;
release_sem(fOwner->fScrubSem);
}
/*****************************************************************************
* SeekSlider::MouseUp
*****************************************************************************/
void SeekSlider::MouseUp(BPoint where)
{
BSlider::MouseUp(where);
delete_sem(fOwner->fScrubSem);
fOwner->fScrubSem = B_ERROR;
fMouseDown = false;
}
extern "C"
{
......@@ -181,7 +415,7 @@ static int intf_Probe( probedata_t *p_data )
}
/*****************************************************************************
* intf_Open: initialize dummy interface
* intf_Open: initialize interface
*****************************************************************************/
static int intf_Open( intf_thread_t *p_intf )
{
......@@ -205,9 +439,6 @@ static int intf_Open( intf_thread_t *p_intf )
return( 1 );
}
/* Bind normal keys. */
intf_AssignNormalKeys( p_intf );
return( 0 );
}
......@@ -230,16 +461,38 @@ static void intf_Close( intf_thread_t *p_intf )
*****************************************************************************/
static void intf_Run( intf_thread_t *p_intf )
{
float progress;
bool seekNeeded = false;
while( !p_intf->b_die )
{
/* Manage core vlc functions through the callback */
p_intf->pf_manage( p_intf );
/* Manage keys */
if( p_intf->p_sys->i_key != -1 )
/* Manage the slider */
if( p_intf->p_input != NULL && p_intf->p_sys->p_window != NULL)
{
intf_ProcessKey( p_intf, p_intf->p_sys->i_key );
p_intf->p_sys->i_key = -1;
if (acquire_sem(p_intf->p_sys->p_window->fScrubSem) == B_OK)
{
seekNeeded = true;
}
if (seekNeeded)
{
uint32 seekTo = (p_intf->p_sys->p_window->p_seek->Value() *
p_intf->p_input->stream.p_selected_area->i_size) / 100;
input_Seek( p_intf->p_input, seekTo );
seekNeeded = false;
}
else if (p_intf->p_sys->p_window->Lock())
{
progress = (100. * p_intf->p_input->stream.p_selected_area->i_tell) /
p_intf->p_input->stream.p_selected_area->i_size;
p_intf->p_sys->p_window->p_seek->SetValue(progress);
p_intf->p_sys->p_window->Unlock();
}
}
/* Wait a bit */
......
......@@ -5,6 +5,7 @@
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* Richard Shepherd <richard@rshepherd.demon.co.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -34,11 +35,11 @@
#include <stdio.h>
#include <string.h> /* strerror() */
#include <kernel/OS.h>
#include <Message.h>
#include <View.h>
#include <Window.h>
#include <Bitmap.h>
#include <Application.h>
#include <Window.h>
#include <Locker.h>
#include <Screen.h>
#include <malloc.h>
#include <string.h>
......@@ -54,13 +55,14 @@ extern "C"
#include "video.h"
#include "video_output.h"
#include "interface.h" /* XXX maybe to remove if window.h is splitted */
#include "interface.h"
#include "intf_msg.h"
#include "main.h"
}
#include "window.h"
#include "VideoWindow.h"
#include <Screen.h>
#define WIDTH 128
#define HEIGHT 64
......@@ -78,10 +80,9 @@ typedef struct vout_sys_s
{
VideoWindow * p_window;
BBitmap * pp_bitmap[2];
byte_t * pp_buffer[2];
s32 i_width;
s32 i_height;
boolean_t b_overlay_enabled;
} vout_sys_t;
......@@ -112,33 +113,149 @@ BWindow *beos_GetAppWindow(char *name)
return window;
}
/*****************************************************************************
* DrawingThread : thread that really does the drawing
*****************************************************************************/
int32 DrawingThread(void *data)
{
VideoWindow *w;
w = (VideoWindow*) data;
while(!w->teardownwindow)
{
w->Lock();
if( w->fDirty )
{
if(!w->fUsingOverlay)
w->view->DrawBitmap(w->bitmap[w->i_buffer_index], w->bitmap[w->i_buffer_index]->Bounds(), w->Bounds());
w->fDirty = false;
}
w->Unlock();
snooze(20000);
}
return B_OK;
}
/*****************************************************************************
* VideoWindow constructor and destructor
*****************************************************************************/
VideoWindow::VideoWindow(BRect frame, const char *name, vout_thread_t *p_video_output )
: BWindow(frame, name, B_TITLED_WINDOW, 0)
: BWindow(frame, name, B_TITLED_WINDOW, NULL)
{
float minWidth, minHeight, maxWidth, maxHeight;
teardownwindow = false;
is_zoomed = false;
p_vout = p_video_output;
p_view = new BView(Bounds(), "", B_FOLLOW_ALL, B_WILL_DRAW);
p_view->SetViewColor(0,0,0); /* set the background to black */
AddChild(p_view);
rect = Frame();
view = new VLCView(Bounds());
AddChild(view);
bitmap[0] = new BBitmap(Bounds(), B_BITMAP_WILL_OVERLAY|B_BITMAP_RESERVE_OVERLAY_CHANNEL, B_YCbCr422);
fUsingOverlay = true;
i_screen_depth = 32;
p_vout->b_YCbr = true;
if (bitmap[0]->InitCheck() != B_OK)
{
delete bitmap[0];
p_vout->b_YCbr = false;
fUsingOverlay = false;
BScreen *screen;
screen = new BScreen();
color_space space = screen->ColorSpace();
delete screen;
if(space == B_RGB15)
{
bitmap[0] = new BBitmap(Bounds(), B_RGB15);
bitmap[1] = new BBitmap(Bounds(), B_RGB15);
i_screen_depth = 15;
}
else if(space == B_RGB16)
{
bitmap[0] = new BBitmap(Bounds(), B_RGB16);
bitmap[1] = new BBitmap(Bounds(), B_RGB16);
i_screen_depth = 16;
}
else //default to 32bpp
{
bitmap[0] = new BBitmap(Bounds(), B_RGB32);
bitmap[1] = new BBitmap(Bounds(), B_RGB32);
i_screen_depth = 32;
}
memset(bitmap[0]->Bits(), 0, bitmap[0]->BitsLength());
memset(bitmap[1]->Bits(), 0, bitmap[1]->BitsLength());
SetTitle("VideoLAN (BBitmap)");
}
if(fUsingOverlay)
{
memset(bitmap[0]->Bits(), 0, bitmap[0]->BitsLength());
rgb_color key;
view->SetViewOverlay(bitmap[0], bitmap[0]->Bounds(), Bounds(), &key, B_FOLLOW_ALL,
B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL);
view->SetViewColor(key);
SetTitle("VideoLAN (Overlay)");
GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
SetSizeLimits((float) Bounds().IntegerWidth(), maxWidth, (float) Bounds().IntegerHeight(), maxHeight);
}
i_bytes_per_pixel = bitmap[0]->BytesPerRow()/bitmap[0]->Bounds().IntegerWidth();
fRowBytes = bitmap[0]->BytesPerRow();
fDirty = false;
fDrawThreadID = spawn_thread(DrawingThread, "drawing_thread",
B_DISPLAY_PRIORITY, (void*) this);
resume_thread(fDrawThreadID);
Show();
}
VideoWindow::~VideoWindow()
{
}
int32 result;
Hide();
Sync();
wait_for_thread(fDrawThreadID, &result);
delete bitmap[0];
if(!fUsingOverlay)
delete bitmap[1];
}
/*****************************************************************************
* VideoWindow::FrameResized
*****************************************************************************/
void VideoWindow::FrameResized( float width, float height )
{
//b_resized = 1;
}
/*****************************************************************************
* VideoWindow::Zoom
*****************************************************************************/
void VideoWindow::Zoom(BPoint origin, float width, float height )
{
if(is_zoomed)
{
MoveTo(rect.left, rect.top);
ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
be_app->ShowCursor();
}
else
{
rect = Frame();
BScreen *screen;
screen = new BScreen(this);
BRect rect = screen->Frame();
delete screen;
MoveTo(0,0);
ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
be_app->HideCursor();
}
is_zoomed = !is_zoomed;
}
/*****************************************************************************
......@@ -175,10 +292,39 @@ bool VideoWindow::QuitRequested()
{
/* FIXME: send a message ! */
p_main->p_intf->b_die = 1;
teardownwindow = true;
return( false );
}
/*****************************************************************************
* VLCView::VLCView
*****************************************************************************/
VLCView::VLCView(BRect bounds) : BView(bounds, "", B_FOLLOW_ALL, B_WILL_DRAW)
{
SetViewColor(B_TRANSPARENT_32_BIT);
}
/*****************************************************************************
* VLCView::~VLCView
*****************************************************************************/
VLCView::~VLCView()
{
}
/*****************************************************************************
* VLCVIew::~VLCView
*****************************************************************************/
void VLCView::MouseDown(BPoint point)
{
VideoWindow *w = (VideoWindow *) Window();
if(w->is_zoomed)
{
BWindow *win = Window();
win->Zoom();
}
}
extern "C"
{
......@@ -266,64 +412,24 @@ int vout_Create( vout_thread_t *p_vout )
int vout_Init( vout_thread_t *p_vout )
{
VideoWindow * p_win = p_vout->p_sys->p_window;
BBitmap **const & p_bmp = p_vout->p_sys->pp_bitmap;
u32 i_page_size;
p_win->Lock();
i_page_size = p_vout->i_width * p_vout->i_height * p_vout->i_bytes_per_pixel;
p_vout->p_sys->i_width = p_vout->i_width;
p_vout->p_sys->i_height = p_vout->i_height;
p_vout->p_sys->b_overlay_enabled = false;
/*
* Create the two bitmaps we need for double buffering
*/
BRect bounds = BRect( 0, 0, p_vout->i_width-1, p_vout->i_height-1 );
/* First we try to create an overlay bitmap */
p_bmp[0] = new BBitmap( bounds,
B_BITMAP_WILL_OVERLAY | B_BITMAP_RESERVE_OVERLAY_CHANNEL,
B_YCbCr420 );
p_bmp[1] = new BBitmap( bounds,
B_BITMAP_WILL_OVERLAY | B_BITMAP_RESERVE_OVERLAY_CHANNEL,
B_YCbCr420 );
if( p_bmp[0]->InitCheck() == B_OK && p_bmp[1]->InitCheck() == B_OK )
if(p_win->fUsingOverlay)
{
p_vout->p_sys->b_overlay_enabled = true;
vout_SetBuffers( p_vout, (byte_t *)p_win->bitmap[0]->Bits(),
(byte_t *)p_win->bitmap[0]->Bits());
}
else
{
delete p_bmp[0];
delete p_bmp[1];
}
/* We failed to create overlay bitmaps, use standard bmp instead */
if( !p_vout->p_sys->b_overlay_enabled )
{
p_bmp[0] = new BBitmap( bounds, B_RGB32 );
p_bmp[1] = new BBitmap( bounds, B_RGB32 );
if( p_bmp[0]->InitCheck() != B_OK || p_bmp[1]->InitCheck() != B_OK )
{
delete p_bmp[0];
delete p_bmp[1];
intf_ErrMsg( "vout error: failed to create BBitmap" );
return( 1 );
vout_SetBuffers( p_vout, (byte_t *)p_win->bitmap[0]->Bits(),
(byte_t *)p_win->bitmap[1]->Bits());
}
}
p_vout->b_need_render = !p_vout->p_sys->b_overlay_enabled;
intf_Msg( "vout: YUV acceleration %s",
p_vout->p_sys->b_overlay_enabled ? "activated" : "unavailable !" );
/* Initialize the bitmap buffers to black (0,0,0) */
memset( p_bmp[0]->Bits(), 0, p_bmp[0]->BitsLength() );
memset( p_bmp[1]->Bits(), 0, p_bmp[1]->BitsLength() );
/* Set and initialize buffers */
vout_SetBuffers( p_vout, p_bmp[0]->Bits(), p_bmp[1]->Bits() );
p_win->Unlock();
return( 0 );
}
......@@ -332,14 +438,6 @@ int vout_Init( vout_thread_t *p_vout )
*****************************************************************************/
void vout_End( vout_thread_t *p_vout )
{
VideoWindow * p_win = p_vout->p_sys->p_window;
p_win->Lock();
delete p_vout->p_sys->pp_bitmap[0];
delete p_vout->p_sys->pp_bitmap[1];
p_win->Unlock();
}
/*****************************************************************************
......@@ -362,39 +460,6 @@ void vout_Destroy( vout_thread_t *p_vout )
*****************************************************************************/
int vout_Manage( vout_thread_t *p_vout )
{
if( p_vout->p_sys->p_window->b_resized )
{
p_vout->p_sys->p_window->b_resized = 0;
p_vout->i_changes |= VOUT_SIZE_CHANGE;
}
/* XXX: I doubt that this code is working correctly (Polux) */
if( p_vout->i_changes & VOUT_SIZE_CHANGE )
{
intf_WarnMsg( 1, "resizing window" );
p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
/* Resize window */
p_vout->p_sys->p_window->ResizeTo( p_vout->i_width, p_vout->i_height );
/* Destroy XImages to change their size */
vout_End( p_vout );
/* Recreate XImages. If SysInit failed, the thread can't go on. */
if( vout_Init( p_vout ) )
{
intf_ErrMsg( "error: can't resize display" );
return( 1 );
}
/* Tell the video output thread that it will need to rebuild YUV
* tables. This is needed since convertion buffer size may have
* changed */
p_vout->i_changes |= VOUT_YUV_CHANGE;
intf_Msg( "vout: video display resized (%dx%d)",
p_vout->i_width, p_vout->i_height );
}
return( 0 );
}
......@@ -407,58 +472,44 @@ int vout_Manage( vout_thread_t *p_vout )
void vout_Display( vout_thread_t *p_vout )
{
VideoWindow * p_win = p_vout->p_sys->p_window;
BBitmap **const & p_bmp = p_vout->p_sys->pp_bitmap;
p_win->Lock();
p_win->i_buffer_index = p_vout->i_buffer_index;
p_vout->i_buffer_index = ++p_vout->i_buffer_index & 1;
if( p_vout->p_sys->b_overlay_enabled )
{
rgb_color key;
p_win->p_view->ClearViewOverlay();
p_win->p_view->SetViewOverlay( p_bmp[p_vout->i_buffer_index],
p_bmp[p_vout->i_buffer_index]->Bounds(),
p_win->p_view->Bounds(), &key, B_FOLLOW_ALL,
B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL );
p_win->p_view->SetViewColor( key );
}
else
{
p_win->p_view->DrawBitmap( p_bmp[p_vout->i_buffer_index],
p_win->p_view->Bounds() );
}
p_win->Unlock();
p_win->fDirty = true;
}
/* following functions are local */
/*****************************************************************************
* BeosOpenDisplay: open and initialize BeOS device
*****************************************************************************
* XXX?? The framebuffer mode is only provided as a fast and efficient way to
* display video, providing the card is configured and the mode ok. It is
* not portable, and is not supposed to work with many cards. Use at your
* own risk !
*****************************************************************************/
static int BeosOpenDisplay( vout_thread_t *p_vout )
{
/* Create the video window */
p_vout->p_sys->p_window =
new VideoWindow( BRect( 50, 150, 50+p_vout->i_width-1, 150+p_vout->i_height-1 ), VOUT_TITLE " (BeOS output) - drop a file here to play it !", p_vout );
new VideoWindow( BRect( 50, 150, 50+p_vout->i_width-1, 150+p_vout->i_height-1 ), NULL, p_vout );
if( p_vout->p_sys->p_window == 0 )
{
free( p_vout->p_sys );
intf_ErrMsg( "error: cannot allocate memory for VideoWindow" );
return( 1 );
}
VideoWindow * p_win = p_vout->p_sys->p_window;
/* XXX: 32 is only chosen for test purposes */
p_vout->i_screen_depth = 32;
p_vout->i_bytes_per_pixel = 4;
p_vout->i_bytes_per_line = p_vout->i_width*p_vout->i_bytes_per_pixel;
p_vout->i_screen_depth = p_win->i_screen_depth;
p_vout->i_bytes_per_pixel = p_win->i_bytes_per_pixel;
p_vout->i_bytes_per_line = p_vout->i_width*p_win->i_bytes_per_pixel;
switch( p_vout->i_screen_depth )
{
case 8:
intf_ErrMsg( "vout error: 8 bit mode not fully supported" );
return( 1 );
break;
case 15:
p_vout->i_red_mask = 0x7c00;
p_vout->i_green_mask = 0x03e0;
......@@ -477,7 +528,6 @@ static int BeosOpenDisplay( vout_thread_t *p_vout )
p_vout->i_blue_mask = 0x0000ff;
break;
}
return( 0 );
}
......
/*****************************************************************************
* transforms_yuv.c: C YUV transformation functions
* Provides functions to perform the YUV conversion. The functions provided here
* are a complete and portable C implementation, and may be replaced in certain
* case by optimized functions.
* Provides functions to perform the YUV conversion. The functions provided
* here are a complete and portable C implementation, and may be replaced in
* certain cases by optimized functions.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* Copyright (C) 1999, 2000, 2001 VideoLAN
*
* Authors:
* Authors: Vincent Seguin <ptyx@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* Richard Shepherd <richard@rshepherd.demon.co.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -691,3 +693,102 @@ void ConvertYUV444RGB32( YUV_ARGS_32BPP )
}
}
static __inline__ void yuv2YCbCr422_inner( u8 *p_y, u8 *p_u, u8 *p_v,
u8 *p_out, int i_width_by_4 )
{
int i_x;
for( i_x = 0 ; i_x < 4 * i_width_by_4 ; ++i_x )
{
*p_out++ = p_y[ 2 * i_x ];
*p_out++ = p_u[ i_x ];
*p_out++ = p_y[ 2 * i_x + 1 ];
*p_out++ = p_v[ i_x ];
}
}
void ConvertYUV420YCbr8 ( YUV_ARGS_8BPP )
{
intf_ErrMsg( "yuv error: unhandled function, chroma = 420, YCbr = 8" );
}
void ConvertYUV422YCbr8 ( YUV_ARGS_8BPP )
{
intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 8" );
}
void ConvertYUV444YCbr8 ( YUV_ARGS_8BPP )
{
intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 8" );
}
/*****************************************************************************
* yuv2YCbCr422: color YUV 4:2:0 to color YCbCr 16bpp
*****************************************************************************/
void ConvertYUV420YCbr16 ( YUV_ARGS_16BPP )
{
int i_y;
for( i_y = 0 ; i_y < i_height ; ++i_y )
{
yuv2YCbCr422_inner( p_y, p_u, p_v, (u8 *)p_pic, i_width / 8 );
p_pic += i_width * 2;
p_y += i_width;
if( i_y & 0x1 )
{
p_u += i_width / 2;
p_v += i_width / 2;
}
}
}
void ConvertYUV422YCbr16 ( YUV_ARGS_16BPP )
{
intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 16" );
}
void ConvertYUV444YCbr16 ( YUV_ARGS_16BPP )
{
intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 16" );
}
void ConvertYUV420YCbr24 ( YUV_ARGS_24BPP )
{
intf_ErrMsg( "yuv error: unhandled function, chroma = 420, YCbr = 24" );
}
void ConvertYUV422YCbr24 ( YUV_ARGS_24BPP )
{
intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 24" );
}
void ConvertYUV444YCbr24 ( YUV_ARGS_24BPP )
{
intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 24" );
}
void ConvertYUV420YCbr32 ( YUV_ARGS_32BPP )
{
intf_ErrMsg( "yuv error: unhandled function, chroma = 420, YCbr = 32" );
}
void ConvertYUV422YCbr32 ( YUV_ARGS_32BPP )
{
intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 32" );
}
void ConvertYUV444YCbr32 ( YUV_ARGS_32BPP )
{
intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 32" );
}
......@@ -168,8 +168,6 @@ void ConvertYUV420RGB16( YUV_ARGS_16BPP )
i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
for( i_y = 0; i_y < i_height; i_y++ )
{
/* Mark beginnning of line for possible later line copy, and initialize
* buffer */
p_pic_start = p_pic;
p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
......@@ -189,12 +187,12 @@ void ConvertYUV420RGB16( YUV_ARGS_16BPP )
p_v += 4;
p_buffer += 8;
}
SCALE_WIDTH;
SCALE_HEIGHT( 420, 2 );
}
}
/*****************************************************************************
* ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
*****************************************************************************/
......@@ -251,6 +249,7 @@ void ConvertY4Gray32( YUV_ARGS_32BPP )
intf_ErrMsg( "yuvmmx error: unhandled function, grayscale, bpp = 32" );
}
/*****************************************************************************
* ConvertYUV420RGB32: color YUV 4:2:0 to RGB 4 Bpp
*****************************************************************************/
......@@ -277,14 +276,9 @@ void ConvertYUV420RGB32( YUV_ARGS_32BPP )
SetOffset( i_width, i_height, i_pic_width, i_pic_height,
&b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
/*
* Perform conversion
*/
i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
for( i_y = 0; i_y < i_height; i_y++ )
{
/* Mark beginnning of line for possible later line copy, and initialize
* buffer */
p_pic_start = p_pic;
p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
......@@ -309,6 +303,7 @@ void ConvertYUV420RGB32( YUV_ARGS_32BPP )
SCALE_WIDTH;
SCALE_HEIGHT( 420, 4 );
}
}
/*****************************************************************************
......@@ -327,3 +322,150 @@ void ConvertYUV444RGB32( YUV_ARGS_32BPP )
intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 32" );
}
/*****************************************************************************
* ConvertYUV420YCbr8: color YUV 4:2:0 to YCbr 8 Bpp
*****************************************************************************/
void ConvertYUV420YCbr8 ( YUV_ARGS_8BPP )
{
intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, YCbr = 8" );
}
/*****************************************************************************
* ConvertYUV422YCbr8: color YUV 4:2:2 to YCbr 8 Bpp
*****************************************************************************/
void ConvertYUV422YCbr8 ( YUV_ARGS_8BPP )
{
intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, YCbr = 8" );
}
/*****************************************************************************
* ConvertYUV444YCbr8: color YUV 4:4:4 to YCbr 8 Bpp
*****************************************************************************/
void ConvertYUV444YCbr8 ( YUV_ARGS_8BPP )
{
intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, YCbr = 8" );
}
/*****************************************************************************
* ConvertYUV420YCbr16: color YUV 4:2:0 to YCbr 16 Bpp
*****************************************************************************/
void ConvertYUV420YCbr16 ( YUV_ARGS_16BPP )
{
boolean_t b_horizontal_scaling; /* horizontal scaling type */
int i_vertical_scaling; /* vertical scaling type */
int i_x, i_y; /* horizontal and vertical indexes */
int i_scale_count; /* scale modulo counter */
int i_chroma_width; /* chroma width */
u16 * p_pic_start; /* beginning of the current line for copy */
u16 * p_buffer_start; /* conversion buffer start */
u16 * p_buffer; /* conversion buffer pointer */
int * p_offset_start; /* offset array start */
int * p_offset; /* offset array pointer */
i_pic_line_width -= i_pic_width;
i_chroma_width = i_width / 2;
p_buffer_start = p_vout->yuv.p_buffer;
p_offset_start = p_vout->yuv.p_offset;
SetOffset( i_width, i_height, i_pic_width, i_pic_height,
&b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
for( i_y = 0; i_y < i_height; i_y++ )
{
p_pic_start = p_pic;
p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
for ( i_x = i_width / 8; i_x--; )
{
__asm__( MMX_INIT_16
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
__asm__( ".align 8"
MMX_YUV_YCBR_422
: : "r" (p_y), "r" (p_u), "r" (p_v), "r" (p_buffer) );
p_y += 8;
p_u += 4;
p_v += 4;
p_buffer += 8;
}
SCALE_WIDTH;
SCALE_HEIGHT( 420, 2 );
}
}
/*****************************************************************************
* ConvertYUV422YCbr8: color YUV 4:2:2 to YCbr 16 Bpp
*****************************************************************************/
void ConvertYUV422YCbr16 ( YUV_ARGS_16BPP )
{
intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, YCbr = 16" );
}
/*****************************************************************************
* ConvertYUV424YCbr8: color YUV 4:4:4 to YCbr 16 Bpp
*****************************************************************************/
void ConvertYUV444YCbr16 ( YUV_ARGS_16BPP )
{
intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, YCbr = 16" );
}
/*****************************************************************************
* ConvertYUV420YCbr24: color YUV 4:2:0 to YCbr 24 Bpp
*****************************************************************************/
void ConvertYUV420YCbr24 ( YUV_ARGS_24BPP )
{
intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, YCbr = 24" );
}
/*****************************************************************************
* ConvertYUV422YCbr24: color YUV 4:2:2 to YCbr 24 Bpp
*****************************************************************************/
void ConvertYUV422YCbr24 ( YUV_ARGS_24BPP )
{
intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, YCbr = 24" );
}
/*****************************************************************************
* ConvertYUV444YCbr24: color YUV 4:4:4 to YCbr 24 Bpp
*****************************************************************************/
void ConvertYUV444YCbr24 ( YUV_ARGS_24BPP )
{
intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, YCbr = 24" );
}
/*****************************************************************************
* ConvertYUV420YCbr32: color YUV 4:2:0 to YCbr 32 Bpp
*****************************************************************************/
void ConvertYUV420YCbr32 ( YUV_ARGS_32BPP )
{
intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 420, YCbr = 32" );
}
/*****************************************************************************
* ConvertYUV422YCbr32: color YUV 4:2:2 to YCbr 32 Bpp
*****************************************************************************/
void ConvertYUV422YCbr32 ( YUV_ARGS_32BPP )
{
intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 422, YCbr = 32" );
}
/*****************************************************************************
* ConvertYUV444YCbr32: color YUV 4:4:4 to YCbr 32 Bpp
*****************************************************************************/
void ConvertYUV444YCbr32 ( YUV_ARGS_32BPP )
{
intf_ErrMsg( "yuvmmx error: unhandled function, chroma = 444, YCbr = 32" );
}
......@@ -105,6 +105,16 @@ pmulhw mmx_Y_coeff, %%mm6 # Mul 4 Y even 00 y6 00 y4 00 y2 00 y0 \n\
pmulhw mmx_Y_coeff, %%mm7 # Mul 4 Y odd 00 y7 00 y5 00 y3 00 y1 \n\
"
#define MMX_YUV_YCBR_422 " \n\
\n\
punpcklbw %%mm1, %%mm0 \n\
movq %%mm6, %%mm2 \n\
punpckhbw %%mm0, %%mm6 \n\
punpcklbw %%mm0, %%mm2 \n\
movq %%mm2, (%3) \n\
movq %%mm6, 8(%3) \n\
"
/*
* Do the addition part of the conversion for even and odd pixels,
* register usage:
......
......@@ -91,3 +91,20 @@ void ConvertYUV420RGB32 ( YUV_ARGS_32BPP );
void ConvertYUV422RGB32 ( YUV_ARGS_32BPP );
void ConvertYUV444RGB32 ( YUV_ARGS_32BPP );
void ConvertYUV420YCbr8 ( YUV_ARGS_8BPP );
void ConvertYUV422YCbr8 ( YUV_ARGS_8BPP );
void ConvertYUV444YCbr8 ( YUV_ARGS_8BPP );
void ConvertYUV420YCbr16 ( YUV_ARGS_16BPP );
void ConvertYUV422YCbr16 ( YUV_ARGS_16BPP );
void ConvertYUV444YCbr16 ( YUV_ARGS_16BPP );
void ConvertYUV420YCbr24 ( YUV_ARGS_24BPP );
void ConvertYUV422YCbr24 ( YUV_ARGS_24BPP );
void ConvertYUV444YCbr24 ( YUV_ARGS_24BPP );
void ConvertYUV420YCbr32 ( YUV_ARGS_32BPP );
void ConvertYUV422YCbr32 ( YUV_ARGS_32BPP );
void ConvertYUV444YCbr32 ( YUV_ARGS_32BPP );
......@@ -436,30 +436,59 @@ static void SetYUV( vout_thread_t *p_vout )
/*
* Set functions pointers
*/
if( p_vout->b_grayscale )
if( p_vout->b_YCbr)
{
switch( p_vout->i_bytes_per_pixel)
{
case 1:
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420YCbr8;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertYUV422YCbr8;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertYUV444YCbr8;
break;
case 2:
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420YCbr16;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertYUV422YCbr16;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertYUV444YCbr16;
break;
case 3:
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420YCbr24;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertYUV422YCbr24;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertYUV444YCbr24;
break;
case 4:
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420YCbr32;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertYUV422YCbr32;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertYUV444YCbr32;
break;
}
}
else if( p_vout->b_grayscale )
{
/* Grayscale */
switch( p_vout->i_bytes_per_pixel )
{
case 1:
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray8;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray8;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray8;
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertY4Gray8;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertY4Gray8;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertY4Gray8;
break;
case 2:
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray16;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray16;
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertY4Gray16;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertY4Gray16;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertY4Gray16;
break;
case 3:
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray24;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray24;
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertY4Gray24;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertY4Gray24;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertY4Gray24;
break;
case 4:
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray32;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray32;
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertY4Gray32;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertY4Gray32;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertY4Gray32;
break;
}
}
......@@ -469,26 +498,27 @@ static void SetYUV( vout_thread_t *p_vout )
switch( p_vout->i_bytes_per_pixel )
{
case 1:
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB8;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB8;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB8;
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420RGB8;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertYUV422RGB8;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertYUV444RGB8;
break;
case 2:
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB16;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB16;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB16;
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420RGB16;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertYUV422RGB16;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertYUV444RGB16;
break;
case 3:
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB24;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB24;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB24;
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420RGB24;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertYUV422RGB24;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertYUV444RGB24;
break;
case 4:
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB32;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB32;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB32;
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420RGB32;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertYUV422RGB32;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertYUV444RGB32;
break;
}
}
}
......
......@@ -324,30 +324,59 @@ static void SetYUV( vout_thread_t *p_vout )
/*
* Set functions pointers
*/
if( p_vout->b_grayscale )
if( p_vout->b_YCbr)
{
switch( p_vout->i_bytes_per_pixel)
{
case 1:
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420YCbr8;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertYUV422YCbr8;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertYUV444YCbr8;
break;
case 2:
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420YCbr16;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertYUV422YCbr16;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertYUV444YCbr16;
break;
case 3:
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420YCbr24;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertYUV422YCbr24;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertYUV444YCbr24;
break;
case 4:
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420YCbr32;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertYUV422YCbr32;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertYUV444YCbr32;
break;
}
}
else if( p_vout->b_grayscale )
{
/* Grayscale */
switch( p_vout->i_bytes_per_pixel )
{
case 1:
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray8;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray8;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray8;
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertY4Gray8;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertY4Gray8;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertY4Gray8;
break;
case 2:
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray16;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray16;
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertY4Gray16;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertY4Gray16;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertY4Gray16;
break;
case 3:
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB24;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray24;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray24;
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420RGB24;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertY4Gray24;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertY4Gray24;
break;
case 4:
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB32;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray32;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray32;
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420RGB32;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertY4Gray32;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertY4Gray32;
break;
}
}
......@@ -357,24 +386,24 @@ static void SetYUV( vout_thread_t *p_vout )
switch( p_vout->i_bytes_per_pixel )
{
case 1:
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB8;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB8;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB8;
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420RGB8;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertYUV422RGB8;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertYUV444RGB8;
break;
case 2:
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB16;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB16;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB16;
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420RGB16;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertYUV422RGB16;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertYUV444RGB16;
break;
case 3:
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB24;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB24;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB24;
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420RGB24;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertYUV422RGB24;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertYUV444RGB24;
break;
case 4:
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB32;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB32;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB32;
p_vout->yuv.pf_yuv420 = (vout_yuv_convert_t *) ConvertYUV420RGB32;
p_vout->yuv.pf_yuv422 = (vout_yuv_convert_t *) ConvertYUV422RGB32;
p_vout->yuv.pf_yuv444 = (vout_yuv_convert_t *) ConvertYUV444RGB32;
break;
}
}
......
......@@ -3,8 +3,7 @@
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
* Authors:
* Jean-Marc Dressler
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......
......@@ -6,7 +6,7 @@
*****************************************************************************
* Copyright (C) 2000 VideoLAN
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Authors:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -154,6 +154,7 @@ vout_thread_t * vout_CreateThread ( int *pi_status )
p_vout->i_bytes_per_pixel = 2;
p_vout->f_gamma = VOUT_GAMMA;
p_vout->b_need_render = 1;
p_vout->b_YCbr = 0;
p_vout->b_grayscale = main_GetIntVariable( VOUT_GRAYSCALE_VAR,
VOUT_GRAYSCALE_DEFAULT );
......@@ -979,27 +980,14 @@ static void RunThread( vout_thread_t *p_vout)
p_subpic = NULL;
display_date = 0;
current_date = mdate();
#ifdef STATS
p_vout->c_loops++;
if( !(p_vout->c_loops % VOUT_STATS_NB_LOOPS) )
{
#ifdef STATS
intf_Msg("vout stats: picture heap: %d/%d",
p_vout->i_pictures, VOUT_MAX_PICTURES);
#endif
if( p_vout->b_info )
{
long i_fps = VOUT_FPS_SAMPLES * 1000000 * 10 /
( p_vout->p_fps_sample[ (p_vout->c_fps_samples - 1)
% VOUT_FPS_SAMPLES ] -
p_vout->p_fps_sample[ p_vout->c_fps_samples
% VOUT_FPS_SAMPLES ] );
intf_Msg( "vout stats: %li.%i fps",
i_fps / 10, (int)i_fps % 10 );
}
}
#endif
/*
* Find the picture to display - this operation does not need lock,
......@@ -1487,7 +1475,7 @@ static void SetBufferArea( vout_thread_t *p_vout, int i_x, int i_y, int i_w, int
if( i_area_copy != i_area )
{
/* Merge with last possible areas */
p_buffer->pi_area_end[i_area] = MAX( i_h, p_buffer->pi_area_end[i_area_copy] );
//p_buffer->pi_area_end[i_area] = MAX( i_h, p_buffer->pi_area_end[i_area_copy] );
/* Shift lower areas upward */
i_area_shift = i_area_copy - i_area;
......@@ -1699,7 +1687,7 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
switch( p_pic->i_type )
{
case YUV_420_PICTURE:
p_vout->yuv.p_Convert420( p_vout, p_pic_data,
p_vout->yuv.pf_yuv420( p_vout, p_pic_data,
p_pic->p_y, p_pic->p_u, p_pic->p_v,
p_pic->i_width, p_pic->i_height,
p_buffer->i_pic_width, p_buffer->i_pic_height,
......@@ -1707,7 +1695,7 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
p_pic->i_matrix_coefficients );
break;
case YUV_422_PICTURE:
p_vout->yuv.p_Convert422( p_vout, p_pic_data,
p_vout->yuv.pf_yuv422( p_vout, p_pic_data,
p_pic->p_y, p_pic->p_u, p_pic->p_v,
p_pic->i_width, p_pic->i_height,
p_buffer->i_pic_width, p_buffer->i_pic_height,
......@@ -1715,7 +1703,7 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
p_pic->i_matrix_coefficients );
break;
case YUV_444_PICTURE:
p_vout->yuv.p_Convert444( p_vout, p_pic_data,
p_vout->yuv.pf_yuv444( p_vout, p_pic_data,
p_pic->p_y, p_pic->p_u, p_pic->p_v,
p_pic->i_width, p_pic->i_height,
p_buffer->i_pic_width, p_buffer->i_pic_height,
......
......@@ -33,6 +33,10 @@
#include <fcntl.h> /* open() */
#include <unistd.h> /* read(), close() */
#ifdef SYS_BEOS
#include "beos_specific.h"
#endif
#include "config.h"
#include "common.h"
#include "video_text.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment