1 /*****************************************************************************
2 * vout_beos.cpp: beos video output display method
3 *****************************************************************************
4 * Copyright (C) 2000, 2001 VideoLAN
5 * $Id: vout_beos.cpp,v 1.43 2002/02/27 03:47:56 sam Exp $
7 * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
8 * Samuel Hocevar <sam@zoy.org>
9 * Tony Castley <tcastley@mail.powerup.com.au>
10 * Richard Shepherd <richard@rshepherd.demon.co.uk>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
25 *****************************************************************************/
27 /*****************************************************************************
29 *****************************************************************************/
30 #include <errno.h> /* ENOMEM */
31 #include <stdlib.h> /* free() */
33 #include <string.h> /* strerror() */
34 #include <InterfaceKit.h>
35 #include <DirectWindow.h>
36 #include <Application.h>
41 #include <videolan/vlc.h>
44 #include "video_output.h"
46 #include "interface.h"
49 #include "VideoWindow.h"
51 #define BITS_PER_PLANE 16
52 #define BYTES_PER_PIXEL 2
54 /*****************************************************************************
55 * vout_sys_t: BeOS video output method descriptor
56 *****************************************************************************
57 * This structure is part of the video output thread descriptor.
58 * It describes the BeOS specific properties of an output thread.
59 *****************************************************************************/
60 typedef struct vout_sys_s
62 VideoWindow * p_window;
73 /*****************************************************************************
74 * beos_GetAppWindow : retrieve a BWindow pointer from the window name
75 *****************************************************************************/
76 BWindow *beos_GetAppWindow(char *name)
81 for (index = 0 ; ; index++)
83 window = be_app->WindowAt(index);
86 if (window->LockWithTimeout(20000) == B_OK)
88 if (strcmp(window->Name(), name) == 0)
99 /****************************************************************************
100 * DrawingThread : thread that really does the drawing
101 ****************************************************************************/
102 int32 Draw(void *data)
106 display_mode disp_mode;
107 static uint32 refresh, oldrefresh = 0;
109 screen = new BScreen();
110 screen-> GetMode(&disp_mode);
112 (disp_mode.timing.pixel_clock * 1000)/((disp_mode.timing.h_total)*
113 (disp_mode.timing.v_total));
114 if (!(refresh == oldrefresh))
116 intf_WarnMsg( 1, "vout info: new refreshrate is %ld:Hz", refresh );
117 oldrefresh = refresh;
120 intf_WarnMsg( 1, "vout info: enabling retrace sync" );
124 intf_WarnMsg( 1, "vout info: disabling retrace sync" );
129 p_win = (VideoWindow *) data;
130 if ( p_win-> voutWindow-> LockLooper() )
135 screen-> WaitForRetrace(22000);//set timeout for < 45 Hz...
138 p_win-> view-> DrawBitmap( p_win-> bitmap[p_win-> i_buffer],
139 p_win-> bitmap[p_win-> i_buffer]-> Bounds(),
140 p_win-> voutWindow-> Bounds() );
141 p_win-> voutWindow-> UnlockLooper();
146 /*****************************************************************************
147 * bitmapWindow : This is the bitmap window output
148 *****************************************************************************/
149 bitmapWindow::bitmapWindow(BRect frame, VideoWindow *theOwner)
150 : BWindow( frame, NULL, B_TITLED_WINDOW,
151 B_OUTLINE_RESIZE | B_NOT_CLOSABLE | B_NOT_MINIMIZABLE )
156 SetTitle(VOUT_TITLE " (BBitmap output)");
159 bitmapWindow::~bitmapWindow()
163 void bitmapWindow::FrameResized( float width, float height )
172 width_scale = width / origRect.Width();
173 height_scale = height / origRect.Height();
175 /* if the width is proportionally smaller */
176 if (width_scale <= height_scale)
178 ResizeTo(width, origRect.Height() * width_scale);
180 else /* if the height is proportionally smaller */
182 ResizeTo(origRect.Width() * height_scale, height);
186 void bitmapWindow::Zoom(BPoint origin, float width, float height )
190 MoveTo(origRect.left, origRect.top);
191 ResizeTo(origRect.IntegerWidth(), origRect.IntegerHeight());
192 be_app->ShowCursor();
197 screen = new BScreen(this);
198 BRect rect = screen->Frame();
201 ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
202 be_app->HideCursor();
204 is_zoomed = !is_zoomed;
207 /*****************************************************************************
208 * directWindow : This is the bitmap window output
209 *****************************************************************************/
210 directWindow::directWindow(BRect frame, VideoWindow *theOwner)
211 : BDirectWindow( frame, NULL, B_TITLED_WINDOW,
212 B_OUTLINE_RESIZE | B_NOT_CLOSABLE | B_NOT_MINIMIZABLE )
217 SetTitle(VOUT_TITLE " (DirectWindow output)");
220 directWindow::~directWindow()
224 void directWindow::DirectConnected(direct_buffer_info *info)
228 void directWindow::FrameResized( float width, float height )
237 width_scale = width / origRect.Width();
238 height_scale = height / origRect.Height();
240 /* if the width is proportionally smaller */
241 if (width_scale <= height_scale)
243 ResizeTo(width, origRect.Height() * width_scale);
245 else /* if the height is proportionally smaller */
247 ResizeTo(origRect.Width() * height_scale, height);
251 void directWindow::Zoom(BPoint origin, float width, float height )
255 SetFullScreen(false);
256 MoveTo(origRect.left, origRect.top);
257 ResizeTo(origRect.IntegerWidth(), origRect.IntegerHeight());
258 be_app->ShowCursor();
264 screen = new BScreen(this);
265 BRect rect = screen->Frame();
268 ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
269 be_app->HideCursor();
271 is_zoomed = !is_zoomed;
274 /*****************************************************************************
275 * VideoWindow constructor and destructor
276 *****************************************************************************/
277 VideoWindow::VideoWindow( int width, int height,
278 vout_thread_t *p_video_output )
280 if ( BDirectWindow::SupportsWindowMode() )
282 voutWindow = new directWindow( BRect( 80, 50,
283 80 + width, 50 + height ), this );
287 voutWindow = new bitmapWindow( BRect( 80, 50,
288 80 + width, 50 + height ), this );
291 /* set the VideoWindow variables */
292 teardownwindow = false;
294 /* create the view to do the display */
295 view = new VLCView( voutWindow->Bounds() );
296 voutWindow->AddChild(view);
298 /* Bitmap mode overlay not available, set the system to 32bits
299 * and let BeOS do all the work */
300 bitmap[0] = new BBitmap( voutWindow->Bounds(), B_RGB32);
301 bitmap[1] = new BBitmap( voutWindow->Bounds(), B_RGB32);
302 memset(bitmap[0]->Bits(), 0, bitmap[0]->BitsLength());
303 memset(bitmap[1]->Bits(), 0, bitmap[1]->BitsLength());
305 i_width = bitmap[0]->Bounds().IntegerWidth();
306 i_height = bitmap[0]->Bounds().IntegerHeight();
311 VideoWindow::~VideoWindow()
319 teardownwindow = true;
320 wait_for_thread(fDrawThreadID, &result);
325 void VideoWindow::resizeIfRequired( int newWidth, int newHeight )
327 if (( newWidth != i_width + 1) &&
328 ( newHeight != i_height + 1) &&
331 if ( voutWindow->Lock() )
333 view->ClearViewBitmap();
334 i_width = newWidth - 1;
335 i_height = newHeight -1;
336 voutWindow->ResizeTo((float) i_width, (float) i_height);
337 voutWindow->Unlock();
342 void VideoWindow::drawBuffer(int bufferIndex)
346 i_buffer = bufferIndex;
348 fDrawThreadID = spawn_thread(Draw, "drawing_thread",
349 B_DISPLAY_PRIORITY, (void*) this);
350 wait_for_thread(fDrawThreadID, &status);
353 /*****************************************************************************
355 *****************************************************************************/
356 VLCView::VLCView(BRect bounds) : BView(bounds, "", B_FOLLOW_ALL, B_WILL_DRAW)
358 SetViewColor(B_TRANSPARENT_32_BIT);
361 /*****************************************************************************
363 *****************************************************************************/
368 /*****************************************************************************
370 *****************************************************************************/
371 void VLCView::MouseDown(BPoint point)
373 BWindow *win = Window();
380 /*****************************************************************************
382 *****************************************************************************/
383 static int vout_Create ( vout_thread_t * );
384 static int vout_Init ( vout_thread_t * );
385 static void vout_End ( vout_thread_t * );
386 static void vout_Destroy ( vout_thread_t * );
387 static int vout_Manage ( vout_thread_t * );
388 static void vout_Display ( vout_thread_t *, picture_t * );
389 static void vout_Render ( vout_thread_t *, picture_t * );
391 static int BeosOpenDisplay ( vout_thread_t *p_vout );
392 static void BeosCloseDisplay( vout_thread_t *p_vout );
394 /*****************************************************************************
395 * Functions exported as capabilities. They are declared as static so that
396 * we don't pollute the namespace too much.
397 *****************************************************************************/
398 void _M( vout_getfunctions )( function_list_t * p_function_list )
400 p_function_list->functions.vout.pf_create = vout_Create;
401 p_function_list->functions.vout.pf_init = vout_Init;
402 p_function_list->functions.vout.pf_end = vout_End;
403 p_function_list->functions.vout.pf_destroy = vout_Destroy;
404 p_function_list->functions.vout.pf_manage = vout_Manage;
405 p_function_list->functions.vout.pf_display = vout_Display;
406 p_function_list->functions.vout.pf_render = vout_Render;
409 /*****************************************************************************
410 * vout_Create: allocates BeOS video thread output method
411 *****************************************************************************
412 * This function allocates and initializes a BeOS vout method.
413 *****************************************************************************/
414 int vout_Create( vout_thread_t *p_vout )
416 /* Allocate structure */
417 p_vout->p_sys = (vout_sys_t*) malloc( sizeof( vout_sys_t ) );
418 if( p_vout->p_sys == NULL )
420 intf_ErrMsg( "error: %s", strerror(ENOMEM) );
424 if( p_vout->render.i_height * p_vout->render.i_aspect
425 >= p_vout->render.i_width * VOUT_ASPECT_FACTOR )
427 p_vout->p_sys->i_width = p_vout->render.i_height
428 * p_vout->render.i_aspect / VOUT_ASPECT_FACTOR;
429 p_vout->p_sys->i_height = p_vout->render.i_height;
433 p_vout->p_sys->i_width = p_vout->render.i_width;
434 p_vout->p_sys->i_height = p_vout->render.i_width
435 * VOUT_ASPECT_FACTOR / p_vout->render.i_aspect;
441 /*****************************************************************************
442 * vout_Init: initialize BeOS video thread output method
443 *****************************************************************************/
444 int vout_Init( vout_thread_t *p_vout )
449 I_OUTPUTPICTURES = 0;
451 /* Open and initialize device */
452 if( BeosOpenDisplay( p_vout ) )
454 intf_ErrMsg("vout error: can't open display");
458 p_vout->output.i_width = p_vout->p_sys->i_width;
459 p_vout->output.i_height = p_vout->p_sys->i_height;
460 p_vout->output.i_aspect = p_vout->p_sys->i_width
461 * VOUT_ASPECT_FACTOR / p_vout->p_sys->i_height;
462 p_vout->output.i_chroma = FOURCC_RV32;
466 /* Find an empty picture slot */
467 for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
469 if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
471 p_pic = p_vout->p_picture + i_index;
481 p_vout->p_sys->i_index = 0;
482 p_pic->p->p_pixels = p_vout->p_sys->pp_buffer[0];
483 p_pic->p->i_pixel_bytes = 4;
484 p_pic->p->i_lines = p_vout->p_sys->i_height;
485 p_pic->p->b_margin = 0;
486 p_pic->p->i_pitch = 4 * p_vout->p_sys->i_width;
488 p_pic->p->i_red_mask = 0x00ff0000;
489 p_pic->p->i_green_mask = 0x0000ff00;
490 p_pic->p->i_blue_mask = 0x000000ff;
494 p_pic->i_status = DESTROYED_PICTURE;
495 p_pic->i_type = DIRECT_PICTURE;
497 PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
504 /*****************************************************************************
505 * vout_End: terminate BeOS video thread output method
506 *****************************************************************************/
507 void vout_End( vout_thread_t *p_vout )
509 BeosCloseDisplay( p_vout );
512 /*****************************************************************************
513 * vout_Destroy: destroy BeOS video thread output method
514 *****************************************************************************
515 * Terminate an output method created by DummyCreateOutputMethod
516 *****************************************************************************/
517 void vout_Destroy( vout_thread_t *p_vout )
519 free( p_vout->p_sys );
522 /*****************************************************************************
523 * vout_Manage: handle BeOS events
524 *****************************************************************************
525 * This function should be called regularly by video output thread. It manages
526 * console events. It returns a non null value on error.
527 *****************************************************************************/
528 int vout_Manage( vout_thread_t *p_vout )
530 // VideoWindow * p_win = p_vout->p_sys->p_window;
532 // p_win->resizeIfRequired(p_vout->p_sys->pp_buffer[p_vout->p_sys->i_index].i_pic_width,
533 // p_vout->p_sys->pp_buffer[p_vout->p_sys->i_index].i_pic_height);
538 /*****************************************************************************
539 * vout_Render: render previously calculated output
540 *****************************************************************************/
541 void vout_Render( vout_thread_t *p_vout, picture_t *p_pic )
546 /*****************************************************************************
547 * vout_Display: displays previously rendered output
548 *****************************************************************************
549 * This function send the currently rendered image to BeOS image, waits until
550 * it is displayed and switch the two rendering buffers, preparing next frame.
551 *****************************************************************************/
552 void vout_Display( vout_thread_t *p_vout, picture_t *p_pic )
554 VideoWindow * p_win = p_vout->p_sys->p_window;
556 /* draw buffer if required */
557 if (!p_win->teardownwindow)
559 p_win->drawBuffer(p_vout->p_sys->i_index);
562 p_vout->p_sys->i_index = ++p_vout->p_sys->i_index & 1;
563 p_pic->p->p_pixels = p_vout->p_sys->pp_buffer[p_vout->p_sys->i_index];
566 /* following functions are local */
568 /*****************************************************************************
569 * BeosOpenDisplay: open and initialize BeOS device
570 *****************************************************************************/
571 static int BeosOpenDisplay( vout_thread_t *p_vout )
573 p_vout->p_sys->p_window = new VideoWindow( p_vout->p_sys->i_width - 1,
574 p_vout->p_sys->i_height - 1,
577 if( p_vout->p_sys->p_window == NULL )
579 intf_ErrMsg( "error: cannot allocate memory for VideoWindow" );
583 p_vout->p_sys->i_width = p_vout->p_sys->p_window->i_width + 1;
584 p_vout->p_sys->i_height = p_vout->p_sys->p_window->i_height + 1;
586 p_vout->p_sys->pp_buffer[0] = (u8*)p_vout->p_sys->p_window->bitmap[0]->Bits();
587 p_vout->p_sys->pp_buffer[1] = (u8*)p_vout->p_sys->p_window->bitmap[1]->Bits();
592 /*****************************************************************************
593 * BeosDisplay: close and reset BeOS device
594 *****************************************************************************
595 * Returns all resources allocated by BeosOpenDisplay and restore the original
596 * state of the device.
597 *****************************************************************************/
598 static void BeosCloseDisplay( vout_thread_t *p_vout )
600 /* Destroy the video window */
601 delete p_vout->p_sys->p_window;