/*****************************************************************************
* vout_beos.cpp: beos video output display method
*****************************************************************************
- * Copyright (C) 2000 VideoLAN
+ * Copyright (C) 2000, 2001 VideoLAN
+ * $Id: vout_beos.cpp,v 1.65 2002/07/31 20:56:50 sam Exp $
*
- * Authors:
- * Jean-Marc Dressler
+ * 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
/*****************************************************************************
* Preamble
*****************************************************************************/
-#include "defs.h"
-
#include <errno.h> /* ENOMEM */
#include <stdlib.h> /* free() */
#include <stdio.h>
#include <string.h> /* strerror() */
-#include <kernel/OS.h>
-#include <View.h>
-#include <Application.h>
+#include <InterfaceKit.h>
#include <DirectWindow.h>
-#include <Locker.h>
-#include <malloc.h>
-#include <string.h>
-
-extern "C"
-{
-#include "config.h"
-#include "common.h"
-#include "threads.h"
-#include "mtime.h"
-#include "plugins.h"
-
-#include "video.h"
-#include "video_output.h"
-
-#include "intf_msg.h"
-#include "interface.h" /* XXX maybe to remove if beos_window.h is splitted */
+#include <Application.h>
+#include <Bitmap.h>
-#include "main.h"
-}
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+#include <vlc/vout.h>
-#include "beos_window.h"
+#include "VideoWindow.h"
+#include "DrawingTidbits.h"
+#include "MsgVals.h"
-#define WIDTH 128
-#define HEIGHT 64
-#define BITS_PER_PLANE 16
-#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
+struct vout_sys_t
{
- VideoWindow * p_window;
-
- byte_t * pp_buffer[2];
- s32 i_width;
- s32 i_height;
-} vout_sys_t;
+ VideoWindow * p_window;
+
+ s32 i_width;
+ s32 i_height;
+ u32 source_chroma;
+ int i_index;
+};
/*****************************************************************************
* beos_GetAppWindow : retrieve a BWindow pointer from the window name
*****************************************************************************/
-
BWindow *beos_GetAppWindow(char *name)
{
int32 index;
window = be_app->WindowAt(index);
if (window == NULL)
break;
- if (window->LockWithTimeout(200000) == B_OK)
+ if (window->LockWithTimeout(20000) == B_OK)
{
if (strcmp(window->Name(), name) == 0)
{
}
/*****************************************************************************
- * DrawingThread : thread that really does the drawing
+ * VideoWindow constructor and destructor
*****************************************************************************/
-
-int32 DrawingThread(void *data)
+VideoWindow::VideoWindow( int v_width, int v_height,
+ BRect frame )
+ : BWindow( frame, NULL, B_TITLED_WINDOW,
+ B_NOT_CLOSABLE | B_NOT_MINIMIZABLE )
{
- 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;
+ BView *mainView = new BView( Bounds(), "mainView",
+ B_FOLLOW_ALL, B_FULL_UPDATE_ON_RESIZE);
+ AddChild(mainView);
+ mainView->SetViewColor(kBlack);
+
+ /* create the view to do the display */
+ view = new VLCView( Bounds() );
+ mainView->AddChild(view);
+
+ /* set the VideoWindow variables */
+ teardownwindow = false;
+ is_zoomed = false;
+ vsync = false;
+ i_buffer = 0;
+
+ /* call ScreenChanged to set vsync correctly */
+ BScreen *screen;
+ display_mode disp_mode;
+ float refresh;
+
+ screen = new BScreen(this);
- while(!w->fConnectionDisabled)
+ 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;
+ }
+ delete screen;
+
+ mode = SelectDrawingMode(v_width, v_height);
+
+ // remember current settings
+ i_width = v_width;
+ i_height = v_height;
+ FrameResized(v_width, v_height);
+
+ if (mode == OVERLAY)
+ {
+ overlay_restrictions r;
+
+ bitmap[1]->GetOverlayRestrictions(&r);
+ SetSizeLimits((i_width * r.min_width_scale) + 1, i_width * r.max_width_scale,
+ (i_height * r.min_height_scale) + 1, i_height * r.max_height_scale);
+ }
+ Show();
+}
+
+VideoWindow::~VideoWindow()
+{
+ teardownwindow = true;
+ delete bitmap[0];
+ delete bitmap[1];
+ delete bitmap[2];
+}
+
+void VideoWindow::MessageReceived( BMessage *p_message )
+{
+ switch( p_message->what )
{
- w->locker->Lock();
- if( w->fConnected )
+ case TOGGLE_FULL_SCREEN:
+ ((BWindow *)this)->Zoom();
+ break;
+ case RESIZE_100:
+ if (is_zoomed)
{
- 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 )
+ ((BWindow *)this)->Zoom();
+ }
+ ResizeTo(i_width, i_height);
+ break;
+ case RESIZE_200:
+ if (is_zoomed)
+ {
+ ((BWindow *)this)->Zoom();
+ }
+ ResizeTo(i_width * 2, i_height * 2);
+ break;
+ case VERT_SYNC:
+ vsync = !vsync;
+ break;
+ case WINDOW_FEEL:
+ {
+ int16 winFeel;
+ if (p_message->FindInt16("WinFeel", &winFeel) == B_OK)
{
- 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;
- }
- }
+ SetFeel((window_feel)winFeel);
}
- w->fDirty = false;
}
- w->locker->Unlock();
- snooze( 20000 );
+ break;
+ default:
+ BWindow::MessageReceived( p_message );
+ break;
}
- return B_OK;
}
-/*****************************************************************************
- * VideoWindow constructor and destructor
- *****************************************************************************/
-
-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)
+void VideoWindow::drawBuffer(int bufferIndex)
{
- BView * view;
-
- fReady = false;
- fConnected = false;
- fConnectionDisabled = false;
- locker = new BLocker();
- fClipList = NULL;
- fNumClipRects = 0;
- p_vout = p_video_output;
-
- view = new BView(Bounds(), "", B_FOLLOW_ALL, B_WILL_DRAW);
- view->SetViewColor(B_TRANSPARENT_32_BIT);
- AddChild(view);
-/*
- if(!SupportsWindowMode())
+ i_buffer = bufferIndex;
+
+ // sync to the screen if required
+ if (vsync)
{
- SetFullScreen(true);
+ BScreen *screen;
+ screen = new BScreen(this);
+ screen-> WaitForRetrace(22000);
+ delete screen;
+ }
+ if (LockLooper())
+ {
+ // switch the overlay bitmap
+ if (mode == OVERLAY)
+ {
+ rgb_color key;
+ view->SetViewOverlay(bitmap[i_buffer],
+ bitmap[i_buffer]->Bounds() ,
+ view->Bounds(),
+ &key, B_FOLLOW_ALL,
+ B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL|
+ B_OVERLAY_TRANSFER_CHANNEL);
+ view->SetViewColor(key);
+ }
+ else
+ {
+ // switch the bitmap
+ view-> DrawBitmap(bitmap[i_buffer], view->Bounds() );
+ }
+ UnlockLooper();
}
-*/
- fDirty = false;
- fDrawThreadID = spawn_thread(DrawingThread, "drawing_thread",
- B_DISPLAY_PRIORITY, (void*) this);
- resume_thread(fDrawThreadID);
- Show();
}
-VideoWindow::~VideoWindow()
+void VideoWindow::Zoom(BPoint origin, float width, float height )
{
- int32 result;
-
- fConnectionDisabled = true;
- Hide();
- Sync();
- wait_for_thread(fDrawThreadID, &result);
- free(fClipList);
- delete locker;
+ if(is_zoomed)
+ {
+ is_zoomed = !is_zoomed;
+ MoveTo(winSize.left, winSize.top);
+ ResizeTo(winSize.IntegerWidth(), winSize.IntegerHeight());
+ be_app->ShowCursor();
+ }
+ else
+ {
+ is_zoomed = !is_zoomed;
+ BScreen *screen;
+ screen = new BScreen(this);
+ BRect rect = screen->Frame();
+ delete screen;
+ MoveTo(0,0);
+ ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
+ be_app->ObscureCursor();
+ }
}
-/*****************************************************************************
- * VideoWindow::DirectConnected
- *****************************************************************************/
+void VideoWindow::FrameMoved(BPoint origin)
+{
+ if (is_zoomed) return ;
+ winSize = Frame();
+}
-void VideoWindow::DirectConnected(direct_buffer_info *info)
+void VideoWindow::FrameResized( float width, float height )
{
- unsigned int i;
+ float out_width, out_height;
+ float out_left, out_top;
+ float width_scale = width / i_width;
+ float height_scale = height / i_height;
- if(!fConnected && fConnectionDisabled)
+ if (width_scale <= height_scale)
{
- return;
+ out_width = (i_width * width_scale);
+ out_height = (i_height * width_scale);
+ out_left = 0;
+ out_top = (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 = (width - out_width) /2;
+ }
+ view->MoveTo(out_left,out_top);
+ view->ResizeTo(out_width, out_height);
+ if (!is_zoomed)
+ {
+ winSize = Frame();
}
- locker->Lock();
+}
+
+void VideoWindow::ScreenChanged(BRect frame, color_space mode)
+{
+ BScreen *screen;
+ float refresh;
+
+ screen = new BScreen(this);
+ display_mode disp_mode;
+
+ 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;
+ }
+}
+
+void VideoWindow::WindowActivated(bool active)
+{
+}
+
+int VideoWindow::SelectDrawingMode(int width, int height)
+{
+ int drawingMode = BITMAP;
+ int noOverlay = 0;
- switch(info->buffer_state & B_DIRECT_MODE_MASK)
+// int noOverlay = !config_GetIntVariable( "overlay" );
+ for (int i = 0; i < COLOR_COUNT; i++)
{
- 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)
+ if (noOverlay) break;
+ bitmap[0] = new BBitmap ( BRect( 0, 0, width, height ),
+ B_BITMAP_WILL_OVERLAY,
+ colspace[i].colspace);
+
+ if(bitmap[0] && bitmap[0]->InitCheck() == B_OK)
{
- free(fClipList);
- fClipList = NULL;
+ colspace_index = i;
+
+ bitmap[1] = new BBitmap( BRect( 0, 0, width, height ), B_BITMAP_WILL_OVERLAY,
+ colspace[colspace_index].colspace);
+ bitmap[2] = new BBitmap( BRect( 0, 0, width, height ), B_BITMAP_WILL_OVERLAY,
+ colspace[colspace_index].colspace);
+ if ( (bitmap[2] && bitmap[2]->InitCheck() == B_OK) )
+ {
+ drawingMode = OVERLAY;
+ rgb_color key;
+ view->SetViewOverlay(bitmap[0],
+ bitmap[0]->Bounds() ,
+ view->Bounds(),
+ &key, B_FOLLOW_ALL,
+ B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL);
+ view->SetViewColor(key);
+ SetTitle(VOUT_TITLE " (Overlay)");
+ break;
+ }
+ else
+ {
+ delete bitmap[0];
+ delete bitmap[1];
+ delete bitmap[2];
+ }
}
- fNumClipRects = info->clip_list_count;
- fClipList = (clipping_rect*) malloc(fNumClipRects*sizeof(clipping_rect));
- for( i=0 ; i<info->clip_list_count ; i++ )
+ else
{
- 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;
+ delete bitmap[0];
+ }
+ }
+
+ if (drawingMode == BITMAP)
+ {
+ // fallback to RGB16
+ colspace_index = DEFAULT_COL;
+ SetTitle(VOUT_TITLE " (Bitmap)");
+ bitmap[0] = new BBitmap( BRect( 0, 0, width, height ), colspace[colspace_index].colspace);
+ bitmap[1] = new BBitmap( BRect( 0, 0, width, height ), colspace[colspace_index].colspace);
+ bitmap[2] = new BBitmap( BRect( 0, 0, width, height ), colspace[colspace_index].colspace);
}
- locker->Unlock();
+ return drawingMode;
}
/*****************************************************************************
- * VideoWindow::MessageReceived
+ * VLCView::VLCView
*****************************************************************************/
+VLCView::VLCView(BRect bounds) : BView(bounds, "", B_FOLLOW_NONE,
+ B_WILL_DRAW)
-void VideoWindow::MessageReceived( BMessage * p_message )
{
- BWindow * p_win;
-
- switch( p_message->what )
- {
- case B_KEY_DOWN:
- // post the message to the interface window which will handle it
- p_win = beos_GetAppWindow( "interface" );
- if( p_win != NULL )
- {
- p_win->PostMessage( p_message );
- }
- break;
-
- default:
- BWindow::MessageReceived( p_message );
- break;
- }
+ SetViewColor(B_TRANSPARENT_32_BIT);
}
/*****************************************************************************
- * VideoWindow::QuitRequested
+ * VLCView::~VLCView
*****************************************************************************/
+VLCView::~VLCView()
+{
+}
-bool VideoWindow::QuitRequested()
+/*****************************************************************************
+ * VLCVIew::MouseDown
+ *****************************************************************************/
+void VLCView::MouseDown(BPoint point)
{
- return( true );
+ BMessage* msg = Window()->CurrentMessage();
+ int32 clicks = msg->FindInt32("clicks");
+
+ VideoWindow *vWindow = (VideoWindow *)Window();
+ uint32 mouseButtons;
+ BPoint where;
+ GetMouse(&where, &mouseButtons, true);
+
+ if ((mouseButtons & B_PRIMARY_MOUSE_BUTTON) && (clicks == 2))
+ {
+ Window()->Zoom();
+ return;
+ }
+ else
+ {
+ if (mouseButtons & B_SECONDARY_MOUSE_BUTTON)
+ {
+ BPopUpMenu *menu = new BPopUpMenu("context menu");
+ menu->SetRadioMode(false);
+ // Toggle FullScreen
+ BMenuItem *zoomItem = new BMenuItem("Fullscreen", new BMessage(TOGGLE_FULL_SCREEN));
+ zoomItem->SetMarked(vWindow->is_zoomed);
+ menu->AddItem(zoomItem);
+ // Resize to 100%
+ BMenuItem *origItem = new BMenuItem("100%", new BMessage(RESIZE_100));
+ menu->AddItem(origItem);
+ // Resize to 200%
+ BMenuItem *doubleItem = new BMenuItem("200%", new BMessage(RESIZE_200));
+ menu->AddItem(doubleItem);
+ menu->AddSeparatorItem();
+ // Toggle vSync
+ BMenuItem *vsyncItem = new BMenuItem("Vertical Sync", new BMessage(VERT_SYNC));
+ vsyncItem->SetMarked(vWindow->vsync);
+ menu->AddItem(vsyncItem);
+ menu->AddSeparatorItem();
+
+ // Windwo Feel Items
+ BMessage *winNormFeel = new BMessage(WINDOW_FEEL);
+ winNormFeel->AddInt16("WinFeel", (int16)B_NORMAL_WINDOW_FEEL);
+ BMenuItem *normWindItem = new BMenuItem("Normal Window", winNormFeel);
+ normWindItem->SetMarked(vWindow->Feel() == B_NORMAL_WINDOW_FEEL);
+ menu->AddItem(normWindItem);
+
+ BMessage *winFloatFeel = new BMessage(WINDOW_FEEL);
+ winFloatFeel->AddInt16("WinFeel", (int16)B_MODAL_ALL_WINDOW_FEEL);
+ BMenuItem *onTopWindItem = new BMenuItem("App Top", winFloatFeel);
+ onTopWindItem->SetMarked(vWindow->Feel() == B_MODAL_ALL_WINDOW_FEEL);
+ menu->AddItem(onTopWindItem);
+
+ BMessage *winAllFeel = new BMessage(WINDOW_FEEL);
+ winAllFeel->AddInt16("WinFeel", (int16)B_FLOATING_ALL_WINDOW_FEEL);
+ BMenuItem *allSpacesWindItem = new BMenuItem("On Top All Workspaces", winAllFeel);
+ allSpacesWindItem->SetMarked(vWindow->Feel() == B_FLOATING_ALL_WINDOW_FEEL);
+ menu->AddItem(allSpacesWindItem);
+
+ menu->SetTargetForItems(this);
+ ConvertToScreen(&where);
+ menu->Go(where, true, false, true);
+ }
+ }
}
-extern "C"
+/*****************************************************************************
+ * VLCVIew::Draw
+ *****************************************************************************/
+void VLCView::Draw(BRect updateRect)
{
+ VideoWindow *win = (VideoWindow *) Window();
+ if (win->mode == BITMAP)
+ FillRect(updateRect);
+}
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static int BeosOpenDisplay ( vout_thread_t *p_vout );
-static void BeosCloseDisplay ( vout_thread_t *p_vout );
+static int Init ( vout_thread_t * );
+static void End ( vout_thread_t * );
+static int Manage ( vout_thread_t * );
+static void Display ( vout_thread_t *, picture_t * );
+
+static int BeosOpenDisplay ( vout_thread_t *p_vout );
+static void BeosCloseDisplay( vout_thread_t *p_vout );
/*****************************************************************************
- * vout_BeCreate: allocates dummy video thread output method
+ * OpenVideo: 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_BeCreate( vout_thread_t *p_vout, char *psz_display,
- int i_root_window, void *p_data )
+int E_(OpenVideo) ( vlc_object_t *p_this )
{
+ vout_thread_t * p_vout = (vout_thread_t *)p_this;
+
/* Allocate structure */
p_vout->p_sys = (vout_sys_t*) malloc( sizeof( vout_sys_t ) );
if( p_vout->p_sys == NULL )
{
- intf_ErrMsg( "error: %s", strerror(ENOMEM) );
+ msg_Err( p_vout, "out of memory" );
return( 1 );
}
-
- /* Set video window's size */
- p_vout->i_width = main_GetIntVariable( VOUT_WIDTH_VAR, VOUT_WIDTH_DEFAULT );
- p_vout->i_height = main_GetIntVariable( VOUT_HEIGHT_VAR, VOUT_HEIGHT_DEFAULT );
+ p_vout->p_sys->i_width = p_vout->render.i_width;
+ p_vout->p_sys->i_height = p_vout->render.i_height;
+ p_vout->p_sys->source_chroma = p_vout->render.i_chroma;
- /* Open and initialize device */
- if( BeosOpenDisplay( p_vout ) )
- {
- intf_ErrMsg("vout error: can't open display");
- free( p_vout->p_sys );
- return( 1 );
- }
+ p_vout->pf_init = Init;
+ p_vout->pf_end = End;
+ p_vout->pf_manage = NULL;
+ p_vout->pf_render = NULL;
+ p_vout->pf_display = Display;
return( 0 );
}
/*****************************************************************************
- * vout_BeInit: initialize dummy video thread output method
+ * Init: initialize BeOS video thread output method
*****************************************************************************/
-int vout_BeInit( vout_thread_t *p_vout )
+int Init( vout_thread_t *p_vout )
{
- VideoWindow * p_win = p_vout->p_sys->p_window;
- u32 i_page_size;
+ int i_index;
+ picture_t *p_pic;
- p_win->locker->Lock();
+ I_OUTPUTPICTURES = 0;
- 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 )
+ /* Open and initialize device */
+ if( BeosOpenDisplay( p_vout ) )
{
- 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 );
+ msg_Err(p_vout, "vout error: can't open display");
+ return 0;
}
+ p_vout->output.i_width = p_vout->render.i_width;
+ p_vout->output.i_height = p_vout->render.i_height;
- /* Set and initialize buffers */
- vout_SetBuffers( p_vout, p_vout->p_sys->pp_buffer[0],
- p_vout->p_sys->pp_buffer[1] );
+ /* Assume we have square pixels */
+ p_vout->output.i_aspect = p_vout->p_sys->i_width
+ * VOUT_ASPECT_FACTOR / p_vout->p_sys->i_height;
+ p_vout->output.i_chroma = colspace[p_vout->p_sys->p_window->colspace_index].chroma;
+ p_vout->p_sys->i_index = 0;
- p_win->locker->Unlock();
- return( 0 );
-}
+ p_vout->b_direct = 1;
-/*****************************************************************************
- * vout_BeEnd: terminate dummy video thread output method
- *****************************************************************************/
-void vout_BeEnd( 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();
+ p_vout->output.i_rmask = 0x00ff0000;
+ p_vout->output.i_gmask = 0x0000ff00;
+ p_vout->output.i_bmask = 0x000000ff;
+
+ for (int buffer_index = 0 ; buffer_index < 3; buffer_index++)
+ {
+ p_pic = NULL;
+ /* Find an empty picture slot */
+ for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
+ {
+ p_pic = NULL;
+ if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
+ {
+ p_pic = p_vout->p_picture + i_index;
+ break;
+ }
+ }
+
+ if( p_pic == NULL )
+ {
+ return 0;
+ }
+ p_pic->p->p_pixels = (u8*)p_vout->p_sys->p_window->bitmap[buffer_index]->Bits();
+ p_pic->p->i_lines = p_vout->p_sys->i_height;
+
+ p_pic->p->i_pixel_pitch = colspace[p_vout->p_sys->p_window->colspace_index].pixel_bytes;
+ p_pic->i_planes = colspace[p_vout->p_sys->p_window->colspace_index].planes;
+ p_pic->p->i_pitch = p_vout->p_sys->p_window->bitmap[buffer_index]->BytesPerRow();
+ p_pic->p->i_visible_pitch = p_pic->p->i_pixel_pitch * ( p_vout->p_sys->p_window->bitmap[buffer_index]->Bounds().IntegerWidth() + 1 );
+
+ p_pic->i_status = DESTROYED_PICTURE;
+ p_pic->i_type = DIRECT_PICTURE;
+
+ PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
+
+ I_OUTPUTPICTURES++;
+ }
+
+ return( 0 );
}
/*****************************************************************************
- * vout_BeDestroy: destroy dummy video thread output method
- *****************************************************************************
- * Terminate an output method created by DummyCreateOutputMethod
+ * End: terminate BeOS video thread output method
*****************************************************************************/
-void vout_BeDestroy( vout_thread_t *p_vout )
+void End( vout_thread_t *p_vout )
{
BeosCloseDisplay( p_vout );
-
- free( p_vout->p_sys );
}
/*****************************************************************************
- * vout_BeManage: handle dummy events
+ * CloseVideo: destroy BeOS video thread output method
*****************************************************************************
- * This function should be called regularly by video output thread. It manages
- * console events. It returns a non null value on error.
+ * Terminate an output method created by DummyCreateOutputMethod
*****************************************************************************/
-int vout_BeManage( vout_thread_t *p_vout )
+void E_(CloseVideo) ( vlc_object_t *p_this )
{
- 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_BeEnd( p_vout );
-
- /* Recreate XImages. If SysInit failed, the thread can't go on. */
- if( vout_BeInit( p_vout ) )
- {
- intf_ErrMsg("error: can't resize display");
- return( 1 );
- }
+ vout_thread_t * p_vout = (vout_thread_t *)p_this;
- /* 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("Video display resized (%dx%d)", p_vout->i_width, p_vout->i_height);
- }
- return( 0 );
+ free( p_vout->p_sys );
}
/*****************************************************************************
- * vout_BeDisplay: displays previously rendered output
+ * 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_BeDisplay( vout_thread_t *p_vout )
+void Display( vout_thread_t *p_vout, picture_t *p_pic )
{
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->fDirty = true;
- p_win->locker->Unlock();
+
+ /* draw buffer if required */
+ if (!p_win->teardownwindow)
+ {
+ p_win->drawBuffer(p_vout->p_sys->i_index);
+ }
+ /* change buffer */
+ p_vout->p_sys->i_index = ++p_vout->p_sys->i_index % 3;
+ p_pic->p->p_pixels = (u8*)p_vout->p_sys->p_window->bitmap[p_vout->p_sys->i_index]->Bits();
}
/* following functions are local */
/*****************************************************************************
- * BeosOpenDisplay: open and initialize dummy 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 !
+ * BeosOpenDisplay: open and initialize BeOS device
*****************************************************************************/
-
static int BeosOpenDisplay( vout_thread_t *p_vout )
{
- /* Create the DirectDraw video window */
- p_vout->p_sys->p_window =
- new VideoWindow( BRect( 100, 100, 100+p_vout->i_width-1, 100+p_vout->i_height-1 ), "VideoLAN", p_vout );
- if( p_vout->p_sys->p_window == 0 )
+
+ p_vout->p_sys->p_window = new VideoWindow( p_vout->p_sys->i_width - 1,
+ p_vout->p_sys->i_height - 1,
+ BRect( 20, 50,
+ 20 + p_vout->i_window_width - 1,
+ 50 + p_vout->i_window_height - 1 ));
+
+ if( p_vout->p_sys->p_window == NULL )
{
- free( p_vout->p_sys );
- intf_ErrMsg( "error: cannot allocate memory for VideoWindow" );
+ msg_Err( p_vout, "cannot allocate VideoWindow" );
return( 1 );
}
- 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;
-
- switch( p_vout->i_screen_depth )
- {
- case 8:
- intf_ErrMsg( "vout error: 8 bit mode not fully supported" );
- break;
- case 15:
- p_vout->i_red_mask = 0x7c00;
- p_vout->i_green_mask = 0x03e0;
- p_vout->i_blue_mask = 0x001f;
- break;
- case 16:
- p_vout->i_red_mask = 0xf800;
- p_vout->i_green_mask = 0x07e0;
- p_vout->i_blue_mask = 0x001f;
- break;
- case 24:
- case 32:
- default:
- p_vout->i_red_mask = 0xff0000;
- p_vout->i_green_mask = 0x00ff00;
- 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.
*****************************************************************************/
static void BeosCloseDisplay( vout_thread_t *p_vout )
{
+ VideoWindow * p_win = p_vout->p_sys->p_window;
/* Destroy the video window */
- p_vout->p_sys->p_window->Lock();
- p_vout->p_sys->p_window->Quit();
+ if( p_win != NULL && !p_win->teardownwindow)
+ {
+ p_win->Lock();
+ p_win->teardownwindow = true;
+ p_win->Hide();
+ p_win->Quit();
+ }
+ p_win = NULL;
}
-} /* extern "C" */