Commit 239e959a authored by Tony Castley's avatar Tony Castley

Improved scaling, correct aspect ratio even in full screen mode.

Duplicate code reduces and framework for Overlay and OpenGL modes in place.
parent e6315659
......@@ -2,7 +2,7 @@
* VideoWindow.h: BeOS video window class prototype
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: VideoWindow.h,v 1.11 2002/03/17 05:48:18 tcastley Exp $
* $Id: VideoWindow.h,v 1.12 2002/03/20 10:33:42 tcastley Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Tony Castley <tcastley@mail.powerup.com.au>
......@@ -22,6 +22,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define BITMAP 0
#define DIRECT 1
#define OVERLAY 2
#define OPENGL 3
class VLCView : public BView
{
public:
......@@ -41,24 +46,30 @@ public:
struct vout_thread_s *p_video_output);
~VideoWindow();
void drawBuffer(int bufferIndex);
void Zoom(BPoint origin, float width, float height);
void FrameResized(float width, float height);
void FrameMoved(BPoint origin);
void ScreenChanged(BRect frame, color_space mode);
void drawBuffer(int bufferIndex);
// this is the hook controling direct screen connection
int32 i_width; // incomming bitmap size
int32 i_height;
BRect winSize; // current window size
float width_scale, height_scale;
bool is_zoomed, resized;
float out_top, out_left, out_height, out_width;
bool is_zoomed, resized, vsync;
BBitmap *bitmap[2];
VLCView *view;
BWindow *voutWindow;
int i_buffer;
bool teardownwindow;
thread_id fDrawThreadID;
private:
// display_mode old_mode;
thread_id fDrawThreadID;
struct vout_thread_s *p_vout;
int mode;
};
......@@ -69,7 +80,10 @@ public:
~bitmapWindow();
// standard window member
virtual void FrameResized(float width, float height);
virtual void FrameMoved(BPoint origin);
virtual void Zoom(BPoint origin, float width, float height);
virtual void ScreenChanged(BRect frame, color_space mode);
void drawBuffer(int bufferIndex);
private:
VideoWindow *owner;
};
......@@ -84,8 +98,11 @@ public:
// standard window member
virtual void FrameResized(float width, float height);
virtual void FrameMoved(BPoint origin);
virtual void Zoom(BPoint origin, float width, float height);
virtual void DirectConnected(direct_buffer_info *info);
virtual void ScreenChanged(BRect frame, color_space mode);
void drawBuffer(int bufferIndex);
private:
VideoWindow *owner;
};
......@@ -2,7 +2,7 @@
* vout_beos.cpp: beos video output display method
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: vout_beos.cpp,v 1.46 2002/03/17 05:48:18 tcastley Exp $
* $Id: vout_beos.cpp,v 1.47 2002/03/20 10:33:42 tcastley Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
......@@ -96,82 +96,32 @@ BWindow *beos_GetAppWindow(char *name)
return window;
}
/****************************************************************************
* Modify Refresh : code to detect refresh changes
****************************************************************************/
void waitForRefreshIfRequired(BScreen *screen)
{
//rudolf: sync init:
display_mode disp_mode;
static uint32 refresh, oldrefresh = 0;
screen-> GetMode(&disp_mode);
refresh =
(disp_mode.timing.pixel_clock * 1000)/((disp_mode.timing.h_total)*
(disp_mode.timing.v_total));
if (!(refresh == oldrefresh))
{
oldrefresh = refresh;
}
//rudolf: sync:
if (refresh < 61)
{
screen-> WaitForRetrace(22000);//set timeout for < 45 Hz...
}
}
/****************************************************************************
* DrawingThread : thread that really does the drawing
****************************************************************************/
int32 Draw(void *data)
{
static float out_top, out_left, out_height, out_width;
BScreen *screen;
VideoWindow* p_win;
screen = new BScreen();
p_win = (VideoWindow *) data;
if ( p_win-> voutWindow-> LockLooper() )
{
waitForRefreshIfRequired(screen);
if (p_win->vsync)
{
BScreen *screen;
screen = new BScreen(p_win->voutWindow);
screen-> WaitForRetrace(22000);
delete screen;
}
if (p_win->resized)
{
p_win->resized = false;
p_win-> view-> FillRect(p_win-> voutWindow-> Bounds());
/* if the width is proportionally smaller */
if (p_win->width_scale <= p_win->height_scale)
{
out_width = p_win->i_width * p_win->width_scale;
out_height = p_win->i_height * p_win->width_scale;
out_left = 0;
if (p_win-> is_zoomed)
{
out_top = (screen-> Frame().Height() - out_height) / 2;
}
else
{
out_top = (p_win->winSize.Height() - out_height) / 2;
}
}
else /* if the height is proportionally smaller */
{
out_width = p_win->i_width * p_win->height_scale;
out_height = p_win->i_height * p_win->height_scale;
out_top = 0;
if (p_win-> is_zoomed)
{
out_left = (screen-> Frame().Width() - out_width) / 2;
}
else
{
out_left = (p_win->winSize.Width() - out_width) /2;
}
}
}
p_win-> view-> DrawBitmap( p_win-> bitmap[p_win-> i_buffer],
BRect(out_left, out_top,
out_left + out_width, out_top + out_height) );
BRect(p_win->out_left, p_win->out_top,
p_win->out_left + p_win->out_width,
p_win->out_top + p_win->out_height) );
p_win-> voutWindow-> UnlockLooper();
}
return B_OK;
......@@ -185,10 +135,6 @@ bitmapWindow::bitmapWindow(BRect frame, VideoWindow *theOwner)
B_NOT_CLOSABLE | B_NOT_MINIMIZABLE )
{
owner = theOwner;
owner->winSize = frame;
owner->width_scale = frame.Width() / owner->i_width;
owner->height_scale = frame.Height() / owner->i_height;
owner->resized = true;
SetTitle(VOUT_TITLE " (BBitmap output)");
}
......@@ -196,38 +142,35 @@ bitmapWindow::~bitmapWindow()
{
}
void bitmapWindow::FrameMoved(BPoint origin)
{
owner->FrameMoved(origin);
}
void bitmapWindow::FrameResized( float width, float height )
{
owner->winSize = Frame();
owner->width_scale = width / owner->i_width;
owner->height_scale = height / owner->i_height;
owner->resized = true;
owner->FrameResized(width, height);
}
void bitmapWindow::Zoom(BPoint origin, float width, float height )
{
if(owner-> is_zoomed)
{
MoveTo(owner->winSize.left, owner->winSize.top);
ResizeTo(owner->winSize.IntegerWidth(), owner->winSize.IntegerHeight());
owner->width_scale = owner->winSize.IntegerWidth() / owner->i_width;
owner->height_scale = owner->winSize.IntegerHeight() / owner->i_height;
be_app->ShowCursor();
}
else
{
BScreen *screen;
screen = new BScreen(this);
BRect rect = screen->Frame();
delete screen;
MoveTo(0,0);
ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
owner->width_scale = rect.IntegerWidth() / owner->i_width;
owner->height_scale = rect.IntegerHeight() / owner->i_height;
be_app->HideCursor();
}
owner-> is_zoomed = !owner-> is_zoomed;
owner->resized = true;
owner->Zoom( origin, width, height );
}
void bitmapWindow::ScreenChanged(BRect frame, color_space mode)
{
owner->ScreenChanged(frame, mode);
}
void bitmapWindow::drawBuffer(int bufferIndex)
{
status_t status;
owner->i_buffer = bufferIndex;
owner->fDrawThreadID = spawn_thread(Draw, "drawing_thread",
B_DISPLAY_PRIORITY, (void*) owner);
wait_for_thread(owner->fDrawThreadID, &status);
}
/*****************************************************************************
......@@ -238,10 +181,6 @@ directWindow::directWindow(BRect frame, VideoWindow *theOwner)
B_NOT_CLOSABLE | B_NOT_MINIMIZABLE )
{
owner = theOwner;
owner->winSize = frame;
owner->width_scale = frame.Width() / owner->i_width;
owner->height_scale = frame.Height() / owner->i_height;
owner->resized = true;
SetTitle(VOUT_TITLE " (DirectWindow output)");
}
......@@ -253,41 +192,34 @@ void directWindow::DirectConnected(direct_buffer_info *info)
{
}
void directWindow::FrameMoved(BPoint origin)
{
owner->FrameMoved(origin);
}
void directWindow::FrameResized( float width, float height )
{
owner->winSize = Frame();
owner->width_scale = width / owner->i_width;
owner->height_scale = height / owner->i_height;
owner->resized = true;
owner->FrameResized(width, height);
}
void directWindow::Zoom(BPoint origin, float width, float height )
{
if(owner-> is_zoomed)
{
SetFullScreen(false);
MoveTo(owner->winSize.left, owner->winSize.top);
ResizeTo(owner->winSize.Width(), owner->winSize.Height());
owner->width_scale = owner->winSize.Width() / owner->i_width;
owner->height_scale = owner->winSize.Height() / owner->i_height;
be_app->ShowCursor();
}
else
{
owner->winSize = Frame();
SetFullScreen(true);
BScreen *screen;
screen = new BScreen(this);
BRect rect = screen->Frame();
delete screen;
MoveTo(0,0);
ResizeTo(rect.Width(), rect.Height());
owner->width_scale = rect.Width() / owner->i_width;
owner->height_scale = rect.Height() / owner->i_height;
be_app->HideCursor();
}
owner-> is_zoomed = !owner-> is_zoomed;
owner->resized = true;
owner->Zoom( origin, width, height );
}
void directWindow::ScreenChanged(BRect frame, color_space mode)
{
owner->ScreenChanged(frame, mode);
}
void directWindow::drawBuffer(int bufferIndex)
{
status_t status;
owner->i_buffer = bufferIndex;
owner->fDrawThreadID = spawn_thread(Draw, "drawing_thread",
B_DISPLAY_PRIORITY, (void*) owner);
wait_for_thread(owner->fDrawThreadID, &status);
}
/*****************************************************************************
......@@ -300,17 +232,24 @@ VideoWindow::VideoWindow( int width, int height,
{
voutWindow = new directWindow( BRect( 80, 50,
80 + width, 50 + height ), this );
mode = DIRECT;
}
else
{
voutWindow = new bitmapWindow( BRect( 80, 50,
80 + width, 50 + height ), this );
mode = BITMAP;
}
/* set the VideoWindow variables */
teardownwindow = false;
is_zoomed = false;
resized = true;
/* call ScreenChanged to set vsync correctly */
BScreen *screen;
screen = new BScreen(voutWindow);
ScreenChanged(screen->Frame(), screen->ColorSpace());
delete screen;
/* create the view to do the display */
view = new VLCView( voutWindow->Bounds() );
......@@ -327,8 +266,13 @@ VideoWindow::VideoWindow( int width, int height,
i_height = bitmap[0]->Bounds().IntegerHeight();
winSize = voutWindow->Frame();
width_scale = winSize.Width() / i_width;
height_scale = winSize.Height() / i_height;
out_top = 0;
out_left = 0;
out_height = winSize.Height();
out_width = winSize.Width();
width_scale = out_width / i_width;
height_scale = out_height / i_height;
voutWindow->Show();
}
......@@ -349,13 +293,100 @@ VideoWindow::~VideoWindow()
void VideoWindow::drawBuffer(int bufferIndex)
{
status_t status;
switch( mode )
{
case DIRECT:
{
directWindow *dW = (directWindow*)voutWindow;
dW->drawBuffer(bufferIndex);
break;
}
case BITMAP:
default:
{
bitmapWindow *bW = (bitmapWindow*)voutWindow;
bW->drawBuffer(bufferIndex);
break;
}
}
}
void VideoWindow::Zoom(BPoint origin, float width, float height )
{
if(is_zoomed)
{
is_zoomed = !is_zoomed;
voutWindow->MoveTo(winSize.left, winSize.top);
voutWindow->ResizeTo(winSize.IntegerWidth(), winSize.IntegerHeight());
width_scale = winSize.IntegerWidth() / i_width;
height_scale = winSize.IntegerHeight() / i_height;
be_app->ShowCursor();
}
else
{
is_zoomed = !is_zoomed;
BScreen *screen;
screen = new BScreen(voutWindow);
BRect rect = screen->Frame();
delete screen;
voutWindow->MoveTo(0,0);
voutWindow->ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
width_scale = rect.IntegerWidth() / i_width;
height_scale = rect.IntegerHeight() / i_height;
be_app->HideCursor();
}
resized = true;
}
void VideoWindow::FrameMoved(BPoint origin)
{
if (is_zoomed) return ;
winSize = voutWindow->Frame();
resized = true;
}
void VideoWindow::FrameResized( float width, float height )
{
width_scale = width / i_width;
height_scale = height / i_height;
if (width_scale <= height_scale)
{
out_width = i_width * width_scale;
out_height = i_height * width_scale;
out_left = 0;
out_top = (voutWindow->Frame().Height() - out_height) / 2;
}
else /* if the height is proportionally smaller */
{
out_width = i_width * height_scale;
out_height = i_height * height_scale;
out_top = 0;
out_left = (voutWindow->Frame().Width() - out_width) /2;
}
if (is_zoomed) return ;
winSize = voutWindow->Frame();
width_scale = width / i_width;
height_scale = height / i_height;
resized = true;
}
void VideoWindow::ScreenChanged(BRect frame, color_space mode)
{
BScreen *screen;
float refresh;
i_buffer = bufferIndex;
screen = new BScreen(voutWindow);
display_mode disp_mode;
fDrawThreadID = spawn_thread(Draw, "drawing_thread",
B_DISPLAY_PRIORITY, (void*) this);
wait_for_thread(fDrawThreadID, &status);
screen-> GetMode(&disp_mode);
refresh =
(disp_mode.timing.pixel_clock * 1000)/((disp_mode.timing.h_total)*
(disp_mode.timing.v_total));
if (refresh < 61)
{
vsync = true;
}
}
/*****************************************************************************
......@@ -438,20 +469,9 @@ int vout_Create( vout_thread_t *p_vout )
return( 1 );
}
if( p_vout->render.i_height * p_vout->render.i_aspect
>= p_vout->render.i_width * VOUT_ASPECT_FACTOR )
{
p_vout->p_sys->i_width = p_vout->render.i_height
* p_vout->render.i_aspect / VOUT_ASPECT_FACTOR;
p_vout->p_sys->i_height = p_vout->render.i_height;
}
else
{
p_vout->p_sys->i_width = p_vout->render.i_width;
p_vout->p_sys->i_height = p_vout->render.i_width
* VOUT_ASPECT_FACTOR / p_vout->render.i_aspect;
}
p_vout->p_sys->i_width = p_vout->render.i_width;
p_vout->p_sys->i_height = p_vout->render.i_height;
return( 0 );
}
......@@ -471,7 +491,7 @@ int vout_Init( vout_thread_t *p_vout )
intf_ErrMsg("vout error: can't open display");
return 0;
}
/* Set the buffers */
p_vout->p_sys->pp_buffer[0] = (u8*)p_vout->p_sys->p_window->bitmap[0]->Bits();
p_vout->p_sys->pp_buffer[1] = (u8*)p_vout->p_sys->p_window->bitmap[1]->Bits();
......
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