* vout_beos.cpp: beos video output display method
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
+ * $Id: vout_beos.cpp,v 1.26 2001/05/30 17:03:11 sam Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
+ * Tony Castley <tcastley@mail.powerup.com.au>
+ * 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
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
+#define MODULE_NAME beos
+#include "modules_inner.h"
+
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <kernel/OS.h>
#include <View.h>
#include <Application.h>
-#include <DirectWindow.h>
+#include <Window.h>
#include <Locker.h>
+#include <Screen.h>
#include <malloc.h>
#include <string.h>
#include "video.h"
#include "video_output.h"
-#include "interface.h" /* XXX maybe to remove if beos_window.h is splitted */
+#include "interface.h"
#include "intf_msg.h"
#include "main.h"
}
-#include "beos_window.h"
+#include "VideoWindow.h"
+#include <Screen.h>
#define WIDTH 128
#define HEIGHT 64
#define BYTES_PER_PIXEL 2
/*****************************************************************************
- * vout_sys_t: dummy video output method descriptor
+ * vout_sys_t: BeOS video output method descriptor
*****************************************************************************
* This structure is part of the video output thread descriptor.
- * It describes the dummy specific properties of an output thread.
+ * It describes the BeOS specific properties of an output thread.
*****************************************************************************/
typedef struct vout_sys_s
{
VideoWindow * p_window;
-
+
byte_t * pp_buffer[2];
s32 i_width;
s32 i_height;
int32 DrawingThread(void *data)
{
- uint32 i, j, y;
- uint64 *pp, *qq;
- uint8 *p, *q;
- uint32 byte_width;
- uint32 height, bytes_per_line;
- clipping_rect *clip;
-
- VideoWindow *w;
- w = (VideoWindow*) data;
+ VideoWindow *w;
+ w = (VideoWindow*) data;
- while(!w->fConnectionDisabled)
+ while(!w->teardownwindow)
+ {
+ if (w->Lock())
{
- w->locker->Lock();
- if( w->fConnected )
+ if( w->fDirty )
+ {
+ if(w->fUsingOverlay)
{
- if( w->fDirty && (!w->fReady || w->i_screen_depth != w->p_vout->i_screen_depth) )
- {
- bytes_per_line = w->fRowBytes;
- for( i=0 ; i < w->fNumClipRects ; i++ )
- {
- clip = &(w->fClipList[i]);
- height = clip->bottom - clip->top +1;
- byte_width = w->i_bytes_per_pixel * ((clip->right - clip->left)+1);
- p = w->fBits + clip->top*w->fRowBytes + clip->left * w->i_bytes_per_pixel;
- for( y=0 ; y < height ; )
- {
- pp = (uint64*) p;
- for( j=0 ; j < byte_width/64 ; j++ )
- {
- *pp++ = 0;
- *pp++ = 0;
- *pp++ = 0;
- *pp++ = 0;
- *pp++ = 0;
- *pp++ = 0;
- *pp++ = 0;
- *pp++ = 0;
- }
- memset( pp , 0, byte_width & 63 );
- y++;
- p += bytes_per_line;
- }
- }
- }
- else if( w->fDirty )
- {
- bytes_per_line = w->fRowBytes;
- for( i=0 ; i < w->fNumClipRects ; i++ )
- {
- clip = &(w->fClipList[i]);
- height = clip->bottom - clip->top +1;
- byte_width = w->i_bytes_per_pixel * ((clip->right - clip->left)+1);
- p = w->fBits + clip->top * bytes_per_line + clip->left * w->i_bytes_per_pixel;
- q = w->p_vout->p_sys->pp_buffer[ !w->p_vout->i_buffer_index ] +
- clip->top * w->p_vout->i_bytes_per_line + clip->left *
- w->p_vout->i_bytes_per_pixel;
- for( y=0 ; y < height ; )
- {
- pp = (uint64*) p;
- qq = (uint64*) q;
- for( j=0 ; j < byte_width/64 ; j++ )
- {
- *pp++ = *qq++;
- *pp++ = *qq++;
- *pp++ = *qq++;
- *pp++ = *qq++;
- *pp++ = *qq++;
- *pp++ = *qq++;
- *pp++ = *qq++;
- *pp++ = *qq++;
- }
- memcpy( pp , qq, byte_width & 63 );
- y++;
- p += bytes_per_line;
- q += w->p_vout->p_sys->i_width * w->p_vout->i_bytes_per_pixel;
- }
- }
- }
- w->fDirty = false;
- }
- w->locker->Unlock();
- snooze( 20000 );
- }
- return B_OK;
+ rgb_color key;
+ w->view->SetViewOverlay( w->bitmap[w->i_buffer_index],
+ w->bitmap[w->i_buffer_index]->Bounds(),
+ w->Bounds(),
+ &key,
+ B_FOLLOW_ALL,
+ B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL
+ | B_OVERLAY_TRANSFER_CHANNEL );
+ w->view->SetViewColor(key);
+ }
+ else
+ {
+ w->view->DrawBitmap( w->bitmap[w->i_buffer_index],
+ w->bitmap[w->i_buffer_index]->Bounds(),
+ w->Bounds());
+ }
+
+ w->fDirty = false;
+ }
+ w->Unlock();
+ }
+ else // we couldn't lock the window, it probably closed.
+ return B_ERROR;
+
+ snooze (20000);
+ } // while
+
+ return B_OK;
}
/*****************************************************************************
*****************************************************************************/
VideoWindow::VideoWindow(BRect frame, const char *name, vout_thread_t *p_video_output )
- : BDirectWindow(frame, name, B_TITLED_WINDOW, B_NOT_RESIZABLE|B_NOT_ZOOMABLE)
+ : BWindow(frame, name, B_TITLED_WINDOW, NULL)
{
- BView * view;
-
- fReady = false;
- fConnected = false;
- fConnectionDisabled = false;
- locker = new BLocker();
- fClipList = NULL;
- fNumClipRects = 0;
- p_vout = p_video_output;
+ float minWidth, minHeight, maxWidth, maxHeight;
- view = new BView(Bounds(), "", B_FOLLOW_ALL, B_WILL_DRAW);
- view->SetViewColor(B_TRANSPARENT_32_BIT);
+ teardownwindow = false;
+ is_zoomed = false;
+ p_vout = p_video_output;
+ fDrawThreadID = NULL;
+ bitmap[0] = NULL;
+ bitmap[1] = NULL;
+
+ rect = Frame();
+ view = new VLCView(Bounds());
AddChild(view);
-/*
- if(!SupportsWindowMode())
- {
- SetFullScreen(true);
- }
-*/
- fDirty = false;
- fDrawThreadID = spawn_thread(DrawingThread, "drawing_thread",
+ bitmap[0] = new BBitmap(Bounds(), B_BITMAP_WILL_OVERLAY|B_BITMAP_RESERVE_OVERLAY_CHANNEL, B_YCbCr422);
+ bitmap[1] = new BBitmap(Bounds(), B_BITMAP_WILL_OVERLAY, B_YCbCr422);
+ fUsingOverlay = true;
+ i_screen_depth = 16;
+ p_vout->b_YCbr = true;
+
+ if ((bitmap[0]->InitCheck() != B_OK) || (bitmap[1]->InitCheck() != B_OK))
+ {
+ delete bitmap[0];
+ delete bitmap[1];
+ 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;
+ }
+ SetTitle(VOUT_TITLE " (BBitmap output)");
+ }
+
+ if(fUsingOverlay)
+ {
+ 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(VOUT_TITLE " (Overlay output)");
+ GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
+ SetSizeLimits((float) Bounds().IntegerWidth(), maxWidth, (float) Bounds().IntegerHeight(), maxHeight);
+ }
+// else
+ {
+ fDrawThreadID = spawn_thread(DrawingThread, "drawing_thread",
B_DISPLAY_PRIORITY, (void*) this);
- resume_thread(fDrawThreadID);
+ resume_thread(fDrawThreadID);
+ }
+
+ memset(bitmap[0]->Bits(), 0, bitmap[0]->BitsLength());
+ memset(bitmap[1]->Bits(), 0, bitmap[1]->BitsLength());
+ i_bytes_per_pixel = bitmap[0]->BytesPerRow()/bitmap[0]->Bounds().IntegerWidth();
+ fRowBytes = bitmap[0]->BytesPerRow();
+ fDirty = false;
Show();
}
{
int32 result;
- fConnectionDisabled = true;
Hide();
Sync();
- wait_for_thread(fDrawThreadID, &result);
- free(fClipList);
- delete locker;
-}
+// if(!fUsingOverlay)
+// {
+ teardownwindow = true;
+ wait_for_thread(fDrawThreadID, &result);
+ delete bitmap[0];
+ delete bitmap[1];
+// }
+ }
+
/*****************************************************************************
- * VideoWindow::DirectConnected
+ * VideoWindow::FrameResized
*****************************************************************************/
-
-void VideoWindow::DirectConnected(direct_buffer_info *info)
+void VideoWindow::FrameResized( float width, float height )
{
- unsigned int i;
+}
- if(!fConnected && fConnectionDisabled)
- {
- return;
- }
- locker->Lock();
+/*****************************************************************************
+ * VideoWindow::Zoom
+ *****************************************************************************/
- switch(info->buffer_state & B_DIRECT_MODE_MASK)
- {
- case B_DIRECT_START:
- fConnected = true;
- case B_DIRECT_MODIFY:
- fBits = (uint8*)((char*)info->bits +
- (info->window_bounds.top) * info->bytes_per_row +
- (info->window_bounds.left) * (info->bits_per_pixel>>3));;
-
- i_bytes_per_pixel = info->bits_per_pixel >> 3;
- i_screen_depth = info->bits_per_pixel;
-
- fRowBytes = info->bytes_per_row;
- fFormat = info->pixel_format;
- fBounds = info->window_bounds;
- fDirty = true;
-
- if(fClipList)
- {
- free(fClipList);
- fClipList = NULL;
- }
- fNumClipRects = info->clip_list_count;
- fClipList = (clipping_rect*) malloc(fNumClipRects*sizeof(clipping_rect));
- for( i=0 ; i<info->clip_list_count ; i++ )
- {
- fClipList[i].top = info->clip_list[i].top - info->window_bounds.top;
- fClipList[i].left = info->clip_list[i].left - info->window_bounds.left;
- fClipList[i].bottom = info->clip_list[i].bottom - info->window_bounds.top;
- fClipList[i].right = info->clip_list[i].right - info->window_bounds.left;
- }
- break;
- case B_DIRECT_STOP:
- fConnected = false;
- break;
- }
- locker->Unlock();
+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;
}
/*****************************************************************************
switch( p_message->what )
{
case B_KEY_DOWN:
+ case B_SIMPLE_DATA:
// post the message to the interface window which will handle it
p_win = beos_GetAppWindow( "interface" );
if( p_win != NULL )
bool VideoWindow::QuitRequested()
{
- return( true );
+ /* 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"
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
*****************************************************************************/
-void vout_getfunctions( function_list_t * p_function_list )
+void _M( vout_getfunctions )( function_list_t * p_function_list )
{
p_function_list->pf_probe = vout_Probe;
p_function_list->functions.vout.pf_create = vout_Create;
}
/*****************************************************************************
- * vout_Create: allocates dummy video thread output method
+ * vout_Create: allocates BeOS video thread output method
*****************************************************************************
- * This function allocates and initializes a dummy vout method.
+ * This function allocates and initializes a BeOS vout method.
*****************************************************************************/
int vout_Create( vout_thread_t *p_vout )
{
}
/*****************************************************************************
- * vout_Init: initialize dummy video thread output method
+ * vout_Init: initialize BeOS video thread output method
*****************************************************************************/
int vout_Init( vout_thread_t *p_vout )
{
VideoWindow * p_win = p_vout->p_sys->p_window;
u32 i_page_size;
- p_win->locker->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;
- /* Allocate memory for the 2 display buffers */
- p_vout->p_sys->pp_buffer[0] = (byte_t*) malloc( i_page_size );
- p_vout->p_sys->pp_buffer[1] = (byte_t*) malloc( i_page_size );
- if( p_vout->p_sys->pp_buffer[0] == NULL || p_vout->p_sys->pp_buffer[0] == NULL )
- {
- intf_ErrMsg("vout error: can't allocate video memory (%s)", strerror(errno) );
- if( p_vout->p_sys->pp_buffer[0] != NULL ) free( p_vout->p_sys->pp_buffer[0] );
- if( p_vout->p_sys->pp_buffer[1] != NULL ) free( p_vout->p_sys->pp_buffer[1] );
- p_win->locker->Unlock();
- return( 1 );
- }
-
- /* Set and initialize buffers */
- vout_SetBuffers( p_vout, p_vout->p_sys->pp_buffer[0],
- p_vout->p_sys->pp_buffer[1] );
-
- p_win->locker->Unlock();
+/* if(p_win->fUsingOverlay)
+ {
+ if(p_win->bitmap[0] != NULL)
+ {
+ p_vout->pf_setbuffers( p_vout,
+ (byte_t *)p_win->bitmap[0]->Bits(),
+ (byte_t *)p_win->bitmap[0]->Bits());
+ delete p_win->bitmap[0];
+ p_win->bitmap[0] = NULL;
+ }
+ }
+ else
+ {
+ if((p_win->bitmap[0] != NULL) && (p_win->bitmap[1] != NULL))
+ {
+ p_vout->pf_setbuffers( p_vout,
+ (byte_t *)p_win->bitmap[0]->Bits(),
+ (byte_t *)p_win->bitmap[1]->Bits());
+ }
+ }*/
+ if((p_win->bitmap[0] != NULL) && (p_win->bitmap[1] != NULL))
+ {
+ p_vout->pf_setbuffers( p_vout,
+ (byte_t *)p_win->bitmap[0]->Bits(),
+ (byte_t *)p_win->bitmap[1]->Bits());
+ }
+
return( 0 );
}
/*****************************************************************************
- * vout_End: terminate dummy video thread output method
+ * vout_End: terminate BeOS video thread output method
*****************************************************************************/
void vout_End( vout_thread_t *p_vout )
{
- VideoWindow * p_win = p_vout->p_sys->p_window;
-
- p_win->Lock();
-
- free( p_vout->p_sys->pp_buffer[0] );
- free( p_vout->p_sys->pp_buffer[1] );
-
- p_win->fReady = false;
- p_win->Unlock();
}
/*****************************************************************************
- * vout_Destroy: destroy dummy video thread output method
+ * vout_Destroy: destroy BeOS video thread output method
*****************************************************************************
* Terminate an output method created by DummyCreateOutputMethod
*****************************************************************************/
}
/*****************************************************************************
- * vout_Manage: handle dummy events
+ * vout_Manage: handle BeOS events
*****************************************************************************
* This function should be called regularly by video output thread. It manages
* console events. It returns a non null value on error.
*****************************************************************************/
int vout_Manage( vout_thread_t *p_vout )
{
- if( p_vout->i_changes & VOUT_SIZE_CHANGE )
- {
- intf_DbgMsg( "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 );
+VideoWindow * p_win = p_vout->p_sys->p_window;
+rgb_color key;
+float minWidth, minHeight, maxWidth, maxHeight;
- /* 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 );
+if( (p_vout->i_width != p_vout->p_sys->i_width) ||
+ (p_vout->i_height != p_vout->p_sys->i_height) )
+ {
+ /* If video output size has changed, change interface window size */
+ intf_DbgMsg( "resizing output window" );
+ if(p_win->fUsingOverlay)
+ {
+ p_win->Lock();
+ p_win->view->ClearViewOverlay();
+ delete p_win->bitmap[0];
+ delete p_win->bitmap[1];
+ p_vout->p_sys->i_width = p_vout->i_width;
+ p_vout->p_sys->i_height = p_vout->i_height;;
+ p_win->GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
+ p_win->SetSizeLimits((float) p_vout->p_sys->i_width, maxWidth, (float) p_vout->p_sys->i_height, maxHeight);
+ p_win->ResizeTo(p_vout->p_sys->i_width, p_vout->p_sys->i_height);
+ p_win->bitmap[0] = new BBitmap(p_win->Bounds(),
+ B_BITMAP_WILL_OVERLAY|B_BITMAP_RESERVE_OVERLAY_CHANNEL,
+ B_YCbCr422);
+ p_win->bitmap[0] = new BBitmap(p_win->Bounds(),
+ B_BITMAP_WILL_OVERLAY, B_YCbCr422);
+ memset(p_win->bitmap[0]->Bits(), 0, p_win->bitmap[0]->BitsLength());
+ memset(p_win->bitmap[1]->Bits(), 0, p_win->bitmap[1]->BitsLength());
+ p_win->view->SetViewOverlay(p_win->bitmap[0], p_win->bitmap[0]->Bounds(), p_win->Bounds(), &key, B_FOLLOW_ALL,
+ B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL|B_OVERLAY_TRANSFER_CHANNEL);
+ p_win->view->SetViewColor(key);
+ p_win->Unlock();
+ p_vout->pf_setbuffers( p_vout,
+ (byte_t *)p_win->bitmap[0]->Bits(),
+ (byte_t *)p_win->bitmap[0]->Bits());
+ delete p_win->bitmap[0];
+ }
+ }
+return( 0 );
}
/*****************************************************************************
* vout_Display: displays previously rendered output
*****************************************************************************
- * This function send the currently rendered image to dummy image, waits until
+ * This function send the currently rendered image to BeOS image, waits until
* it is displayed and switch the two rendering buffers, preparing next frame.
*****************************************************************************/
void vout_Display( vout_thread_t *p_vout )
{
VideoWindow * p_win = p_vout->p_sys->p_window;
- p_win->locker->Lock();
- p_vout->i_buffer_index = ++p_vout->i_buffer_index & 1;
- p_win->fReady = true;
+ p_win->i_buffer_index = p_vout->i_buffer_index;
+ if(p_win->fUsingOverlay)
+ p_vout->i_buffer_index = p_vout->i_buffer_index & 1;
+ else
+ p_vout->i_buffer_index = ++p_vout->i_buffer_index & 1;
p_win->fDirty = true;
- p_win->locker->Unlock();
}
/* following functions are local */
/*****************************************************************************
- * BeosOpenDisplay: open and initialize dummy device
+ * 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
static int BeosOpenDisplay( vout_thread_t *p_vout )
{
- /* Create the DirectDraw 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)", p_vout );
+ new VideoWindow( BRect( 80, 50, 80+p_vout->i_width-1, 50+p_vout->i_height-1 ), NULL, p_vout );
if( p_vout->p_sys->p_window == 0 )
{
free( p_vout->p_sys );
}
VideoWindow * p_win = p_vout->p_sys->p_window;
- /* Wait until DirectConnected has been called */
- while( !p_win->fConnected )
- snooze( 50000 );
-
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;
p_vout->i_blue_mask = 0x0000ff;
break;
}
-
return( 0 );
}
/*****************************************************************************
- * BeosDisplay: close and reset dummy device
+ * BeosDisplay: close and reset BeOS device
*****************************************************************************
* Returns all resources allocated by BeosOpenDisplay and restore the original
* state of the device.