]> git.sesse.net Git - vlc/blobdiff - plugins/beos/vout_beos.cpp
* Fixed the BeOS compile typo.
[vlc] / plugins / beos / vout_beos.cpp
index 495a44b960c4e82b62bda360267ee9414e8b2ae1..44fe4b304f9972ea7c2d6395baf6d87a2da577c7 100644 (file)
@@ -2,9 +2,12 @@
  * 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
 #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 +57,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 +82,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 +115,182 @@ 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)
+  {
+    if (w->Lock())
+    {
+      if( w->fDirty )
+      {
+        if(w->fUsingOverlay)
+        {
+          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 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)
 {
-    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);
+       float minWidth, minHeight, maxWidth, maxHeight; 
 
+    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);
+       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);
+       }
+
+       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();
 }
 
 VideoWindow::~VideoWindow()
 {
-}
+    int32 result;
+
+    Hide();
+    Sync();
+//    if(!fUsingOverlay)
+//     {
+           teardownwindow = true;
+           wait_for_thread(fDrawThreadID, &result);
+       delete bitmap[0];
+       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 +327,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 +447,41 @@ 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();
-    
-    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 );
+
+    i_page_size =   p_vout->i_width * p_vout->i_height * p_vout->i_bytes_per_pixel;
     
-    if( p_bmp[0]->InitCheck() == B_OK && p_bmp[1]->InitCheck() == B_OK )
-    {
-        p_vout->p_sys->b_overlay_enabled = true;
-    }
+    p_vout->p_sys->i_width =         p_vout->i_width;
+    p_vout->p_sys->i_height =        p_vout->i_height;    
+
+/*    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
-    {
-        delete p_bmp[0];
-        delete p_bmp[1];
-    }
+               {
+           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());
+               }
     
-    /* 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 );
-        }
-    }
-
-    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 +490,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,40 +512,44 @@ 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;
-    }
+VideoWindow * p_win = p_vout->p_sys->p_window;
+rgb_color key;
+float minWidth, minHeight, maxWidth, maxHeight; 
 
-    /* XXX: I doubt that this code is working correctly (Polux) */
-    if( p_vout->i_changes & VOUT_SIZE_CHANGE )
+if( (p_vout->i_width  != p_vout->p_sys->i_width) ||
+             (p_vout->i_height != p_vout->p_sys->i_height) )
     {
-       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 );
+        /* 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 );
 }
 
 /*****************************************************************************
@@ -407,58 +561,47 @@ 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_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->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;
 }
 
 /* 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( 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 );
         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 +620,6 @@ static int BeosOpenDisplay( vout_thread_t *p_vout )
         p_vout->i_blue_mask =       0x0000ff;
         break;
     }
-
     return( 0 );
 }