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 @@ ...@@ -2,7 +2,7 @@
* VideoWindow.h: BeOS video window class prototype * VideoWindow.h: BeOS video window class prototype
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN * 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> * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Tony Castley <tcastley@mail.powerup.com.au> * Tony Castley <tcastley@mail.powerup.com.au>
...@@ -22,6 +22,11 @@ ...@@ -22,6 +22,11 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * 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 class VLCView : public BView
{ {
public: public:
...@@ -41,24 +46,30 @@ public: ...@@ -41,24 +46,30 @@ public:
struct vout_thread_s *p_video_output); struct vout_thread_s *p_video_output);
~VideoWindow(); ~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 // this is the hook controling direct screen connection
int32 i_width; // incomming bitmap size int32 i_width; // incomming bitmap size
int32 i_height; int32 i_height;
BRect winSize; // current window size BRect winSize; // current window size
float width_scale, height_scale; 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]; BBitmap *bitmap[2];
VLCView *view; VLCView *view;
BWindow *voutWindow; BWindow *voutWindow;
int i_buffer; int i_buffer;
bool teardownwindow; bool teardownwindow;
thread_id fDrawThreadID;
private: private:
// display_mode old_mode; // display_mode old_mode;
thread_id fDrawThreadID;
struct vout_thread_s *p_vout; struct vout_thread_s *p_vout;
int mode;
}; };
...@@ -69,7 +80,10 @@ public: ...@@ -69,7 +80,10 @@ public:
~bitmapWindow(); ~bitmapWindow();
// standard window member // standard window member
virtual void FrameResized(float width, float height); virtual void FrameResized(float width, float height);
virtual void FrameMoved(BPoint origin);
virtual void Zoom(BPoint origin, float width, float height); virtual void Zoom(BPoint origin, float width, float height);
virtual void ScreenChanged(BRect frame, color_space mode);
void drawBuffer(int bufferIndex);
private: private:
VideoWindow *owner; VideoWindow *owner;
}; };
...@@ -84,8 +98,11 @@ public: ...@@ -84,8 +98,11 @@ public:
// standard window member // standard window member
virtual void FrameResized(float width, float height); virtual void FrameResized(float width, float height);
virtual void FrameMoved(BPoint origin);
virtual void Zoom(BPoint origin, float width, float height); virtual void Zoom(BPoint origin, float width, float height);
virtual void DirectConnected(direct_buffer_info *info); virtual void DirectConnected(direct_buffer_info *info);
virtual void ScreenChanged(BRect frame, color_space mode);
void drawBuffer(int bufferIndex);
private: private:
VideoWindow *owner; VideoWindow *owner;
}; };
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vout_beos.cpp: beos video output display method * vout_beos.cpp: beos video output display method
***************************************************************************** *****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN * 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> * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -96,82 +96,32 @@ BWindow *beos_GetAppWindow(char *name) ...@@ -96,82 +96,32 @@ BWindow *beos_GetAppWindow(char *name)
return window; 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 * DrawingThread : thread that really does the drawing
****************************************************************************/ ****************************************************************************/
int32 Draw(void *data) int32 Draw(void *data)
{ {
static float out_top, out_left, out_height, out_width;
BScreen *screen;
VideoWindow* p_win; VideoWindow* p_win;
screen = new BScreen();
p_win = (VideoWindow *) data; p_win = (VideoWindow *) data;
if ( p_win-> voutWindow-> LockLooper() ) 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) if (p_win->resized)
{ {
p_win->resized = false; p_win->resized = false;
p_win-> view-> FillRect(p_win-> voutWindow-> Bounds()); 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], p_win-> view-> DrawBitmap( p_win-> bitmap[p_win-> i_buffer],
BRect(out_left, out_top, BRect(p_win->out_left, p_win->out_top,
out_left + out_width, out_top + out_height) ); p_win->out_left + p_win->out_width,
p_win->out_top + p_win->out_height) );
p_win-> voutWindow-> UnlockLooper(); p_win-> voutWindow-> UnlockLooper();
} }
return B_OK; return B_OK;
...@@ -185,10 +135,6 @@ bitmapWindow::bitmapWindow(BRect frame, VideoWindow *theOwner) ...@@ -185,10 +135,6 @@ bitmapWindow::bitmapWindow(BRect frame, VideoWindow *theOwner)
B_NOT_CLOSABLE | B_NOT_MINIMIZABLE ) B_NOT_CLOSABLE | B_NOT_MINIMIZABLE )
{ {
owner = theOwner; 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)"); SetTitle(VOUT_TITLE " (BBitmap output)");
} }
...@@ -196,38 +142,35 @@ bitmapWindow::~bitmapWindow() ...@@ -196,38 +142,35 @@ bitmapWindow::~bitmapWindow()
{ {
} }
void bitmapWindow::FrameMoved(BPoint origin)
{
owner->FrameMoved(origin);
}
void bitmapWindow::FrameResized( float width, float height ) void bitmapWindow::FrameResized( float width, float height )
{ {
owner->winSize = Frame(); owner->FrameResized(width, height);
owner->width_scale = width / owner->i_width;
owner->height_scale = height / owner->i_height;
owner->resized = true;
} }
void bitmapWindow::Zoom(BPoint origin, float width, float height ) void bitmapWindow::Zoom(BPoint origin, float width, float height )
{ {
if(owner-> is_zoomed) owner->Zoom( origin, width, height );
{ }
MoveTo(owner->winSize.left, owner->winSize.top);
ResizeTo(owner->winSize.IntegerWidth(), owner->winSize.IntegerHeight()); void bitmapWindow::ScreenChanged(BRect frame, color_space mode)
owner->width_scale = owner->winSize.IntegerWidth() / owner->i_width; {
owner->height_scale = owner->winSize.IntegerHeight() / owner->i_height; owner->ScreenChanged(frame, mode);
be_app->ShowCursor(); }
}
else void bitmapWindow::drawBuffer(int bufferIndex)
{ {
BScreen *screen; status_t status;
screen = new BScreen(this);
BRect rect = screen->Frame(); owner->i_buffer = bufferIndex;
delete screen; owner->fDrawThreadID = spawn_thread(Draw, "drawing_thread",
MoveTo(0,0); B_DISPLAY_PRIORITY, (void*) owner);
ResizeTo(rect.IntegerWidth(), rect.IntegerHeight()); wait_for_thread(owner->fDrawThreadID, &status);
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;
} }
/***************************************************************************** /*****************************************************************************
...@@ -238,10 +181,6 @@ directWindow::directWindow(BRect frame, VideoWindow *theOwner) ...@@ -238,10 +181,6 @@ directWindow::directWindow(BRect frame, VideoWindow *theOwner)
B_NOT_CLOSABLE | B_NOT_MINIMIZABLE ) B_NOT_CLOSABLE | B_NOT_MINIMIZABLE )
{ {
owner = theOwner; 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)"); SetTitle(VOUT_TITLE " (DirectWindow output)");
} }
...@@ -253,41 +192,34 @@ void directWindow::DirectConnected(direct_buffer_info *info) ...@@ -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 ) void directWindow::FrameResized( float width, float height )
{ {
owner->winSize = Frame(); owner->FrameResized(width, height);
owner->width_scale = width / owner->i_width;
owner->height_scale = height / owner->i_height;
owner->resized = true;
} }
void directWindow::Zoom(BPoint origin, float width, float height ) void directWindow::Zoom(BPoint origin, float width, float height )
{ {
if(owner-> is_zoomed) owner->Zoom( origin, width, height );
{ }
SetFullScreen(false);
MoveTo(owner->winSize.left, owner->winSize.top); void directWindow::ScreenChanged(BRect frame, color_space mode)
ResizeTo(owner->winSize.Width(), owner->winSize.Height()); {
owner->width_scale = owner->winSize.Width() / owner->i_width; owner->ScreenChanged(frame, mode);
owner->height_scale = owner->winSize.Height() / owner->i_height; }
be_app->ShowCursor();
} void directWindow::drawBuffer(int bufferIndex)
else {
{ status_t status;
owner->winSize = Frame();
SetFullScreen(true); owner->i_buffer = bufferIndex;
BScreen *screen; owner->fDrawThreadID = spawn_thread(Draw, "drawing_thread",
screen = new BScreen(this); B_DISPLAY_PRIORITY, (void*) owner);
BRect rect = screen->Frame(); wait_for_thread(owner->fDrawThreadID, &status);
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;
} }
/***************************************************************************** /*****************************************************************************
...@@ -300,17 +232,24 @@ VideoWindow::VideoWindow( int width, int height, ...@@ -300,17 +232,24 @@ VideoWindow::VideoWindow( int width, int height,
{ {
voutWindow = new directWindow( BRect( 80, 50, voutWindow = new directWindow( BRect( 80, 50,
80 + width, 50 + height ), this ); 80 + width, 50 + height ), this );
mode = DIRECT;
} }
else else
{ {
voutWindow = new bitmapWindow( BRect( 80, 50, voutWindow = new bitmapWindow( BRect( 80, 50,
80 + width, 50 + height ), this ); 80 + width, 50 + height ), this );
mode = BITMAP;
} }
/* set the VideoWindow variables */ /* set the VideoWindow variables */
teardownwindow = false; teardownwindow = false;
is_zoomed = false; is_zoomed = false;
resized = true; 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 */ /* create the view to do the display */
view = new VLCView( voutWindow->Bounds() ); view = new VLCView( voutWindow->Bounds() );
...@@ -327,8 +266,13 @@ VideoWindow::VideoWindow( int width, int height, ...@@ -327,8 +266,13 @@ VideoWindow::VideoWindow( int width, int height,
i_height = bitmap[0]->Bounds().IntegerHeight(); i_height = bitmap[0]->Bounds().IntegerHeight();
winSize = voutWindow->Frame(); winSize = voutWindow->Frame();
width_scale = winSize.Width() / i_width; out_top = 0;
height_scale = winSize.Height() / i_height; 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(); voutWindow->Show();
} }
...@@ -349,13 +293,100 @@ VideoWindow::~VideoWindow() ...@@ -349,13 +293,100 @@ VideoWindow::~VideoWindow()
void VideoWindow::drawBuffer(int bufferIndex) 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", screen-> GetMode(&disp_mode);
B_DISPLAY_PRIORITY, (void*) this); refresh =
wait_for_thread(fDrawThreadID, &status); (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 ) ...@@ -438,20 +469,9 @@ int vout_Create( vout_thread_t *p_vout )
return( 1 ); return( 1 );
} }
if( p_vout->render.i_height * p_vout->render.i_aspect p_vout->p_sys->i_width = p_vout->render.i_width;
>= p_vout->render.i_width * VOUT_ASPECT_FACTOR ) p_vout->p_sys->i_height = p_vout->render.i_height;
{
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;
}
return( 0 ); return( 0 );
} }
...@@ -471,7 +491,7 @@ int vout_Init( vout_thread_t *p_vout ) ...@@ -471,7 +491,7 @@ int vout_Init( vout_thread_t *p_vout )
intf_ErrMsg("vout error: can't open display"); intf_ErrMsg("vout error: can't open display");
return 0; 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[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(); 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