1 /*****************************************************************************
2 * vout_beos.cpp: beos video output display method
3 *****************************************************************************
4 * Copyright (C) 2000, 2001 VideoLAN
5 * $Id: vout_beos.cpp,v 1.27 2001/05/31 03:57:54 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 #define MODULE_NAME beos
28 #include "modules_inner.h"
30 /*****************************************************************************
32 *****************************************************************************/
35 #include <errno.h> /* ENOMEM */
36 #include <stdlib.h> /* free() */
38 #include <string.h> /* strerror() */
39 #include <kernel/OS.h>
41 #include <Application.h>
57 #include "video_output.h"
59 #include "interface.h"
65 #include "modules_export.h"
68 #include "VideoWindow.h"
73 #define BITS_PER_PLANE 16
74 #define BYTES_PER_PIXEL 2
76 /*****************************************************************************
77 * vout_sys_t: BeOS video output method descriptor
78 *****************************************************************************
79 * This structure is part of the video output thread descriptor.
80 * It describes the BeOS specific properties of an output thread.
81 *****************************************************************************/
83 typedef struct vout_sys_s
85 VideoWindow
* p_window
;
87 byte_t
* pp_buffer
[2];
93 /*****************************************************************************
94 * beos_GetAppWindow : retrieve a BWindow pointer from the window name
95 *****************************************************************************/
97 BWindow
*beos_GetAppWindow(char *name
)
102 for (index
= 0 ; ; index
++)
104 window
= be_app
->WindowAt(index
);
107 if (window
->LockWithTimeout(200000) == B_OK
)
109 if (strcmp(window
->Name(), name
) == 0)
120 /*****************************************************************************
121 * DrawingThread : thread that really does the drawing
122 *****************************************************************************/
124 int32
DrawingThread(void *data
)
127 w
= (VideoWindow
*) data
;
129 while(!w
->teardownwindow
)
138 w
->view
->SetViewOverlay( w
->bitmap
[w
->i_buffer_index
],
139 w
->bitmap
[w
->i_buffer_index
]->Bounds(),
143 B_OVERLAY_FILTER_HORIZONTAL
| B_OVERLAY_FILTER_VERTICAL
144 | B_OVERLAY_TRANSFER_CHANNEL
);
145 w
->view
->SetViewColor(key
);
149 w
->view
->DrawBitmap( w
->bitmap
[w
->i_buffer_index
],
150 w
->bitmap
[w
->i_buffer_index
]->Bounds(),
158 else // we couldn't lock the window, it probably closed.
167 /*****************************************************************************
168 * VideoWindow constructor and destructor
169 *****************************************************************************/
171 VideoWindow::VideoWindow(BRect frame
, const char *name
, vout_thread_t
*p_video_output
)
172 : BWindow(frame
, name
, B_TITLED_WINDOW
, NULL
)
174 float minWidth
, minHeight
, maxWidth
, maxHeight
;
176 teardownwindow
= false;
178 p_vout
= p_video_output
;
179 fDrawThreadID
= NULL
;
184 view
= new VLCView(Bounds());
186 bitmap
[0] = new BBitmap(Bounds(), B_BITMAP_WILL_OVERLAY
|B_BITMAP_RESERVE_OVERLAY_CHANNEL
, B_YCbCr422
);
187 bitmap
[1] = new BBitmap(Bounds(), B_BITMAP_WILL_OVERLAY
, B_YCbCr422
);
188 fUsingOverlay
= true;
190 p_vout
->b_YCbr
= true;
192 if ((bitmap
[0]->InitCheck() != B_OK
) || (bitmap
[1]->InitCheck() != B_OK
))
196 p_vout
->b_YCbr
= false;
197 fUsingOverlay
= false;
199 screen
= new BScreen();
200 color_space space
= screen
->ColorSpace();
205 bitmap
[0] = new BBitmap(Bounds(), B_RGB15
);
206 bitmap
[1] = new BBitmap(Bounds(), B_RGB15
);
209 else if(space
== B_RGB16
)
211 bitmap
[0] = new BBitmap(Bounds(), B_RGB16
);
212 bitmap
[1] = new BBitmap(Bounds(), B_RGB16
);
215 else //default to 32bpp
217 bitmap
[0] = new BBitmap(Bounds(), B_RGB32
);
218 bitmap
[1] = new BBitmap(Bounds(), B_RGB32
);
221 SetTitle(VOUT_TITLE
" (BBitmap output)");
227 view
->SetViewOverlay(bitmap
[0], bitmap
[0]->Bounds(), Bounds(), &key
, B_FOLLOW_ALL
,
228 B_OVERLAY_FILTER_HORIZONTAL
|B_OVERLAY_FILTER_VERTICAL
);
229 view
->SetViewColor(key
);
230 SetTitle(VOUT_TITLE
" (Overlay output)");
231 GetSizeLimits(&minWidth
, &maxWidth
, &minHeight
, &maxHeight
);
232 SetSizeLimits((float) Bounds().IntegerWidth(), maxWidth
, (float) Bounds().IntegerHeight(), maxHeight
);
236 fDrawThreadID
= spawn_thread(DrawingThread
, "drawing_thread",
237 B_DISPLAY_PRIORITY
, (void*) this);
238 resume_thread(fDrawThreadID
);
241 memset(bitmap
[0]->Bits(), 0, bitmap
[0]->BitsLength());
242 memset(bitmap
[1]->Bits(), 0, bitmap
[1]->BitsLength());
243 i_bytes_per_pixel
= bitmap
[0]->BytesPerRow()/bitmap
[0]->Bounds().IntegerWidth();
244 fRowBytes
= bitmap
[0]->BytesPerRow();
249 VideoWindow::~VideoWindow()
255 // if(!fUsingOverlay)
257 teardownwindow
= true;
258 wait_for_thread(fDrawThreadID
, &result
);
265 /*****************************************************************************
266 * VideoWindow::FrameResized
267 *****************************************************************************/
268 void VideoWindow::FrameResized( float width
, float height
)
272 /*****************************************************************************
274 *****************************************************************************/
276 void VideoWindow::Zoom(BPoint origin
, float width
, float height
)
280 MoveTo(rect
.left
, rect
.top
);
281 ResizeTo(rect
.IntegerWidth(), rect
.IntegerHeight());
282 be_app
->ShowCursor();
288 screen
= new BScreen(this);
289 BRect rect
= screen
->Frame();
292 ResizeTo(rect
.IntegerWidth(), rect
.IntegerHeight());
293 be_app
->HideCursor();
295 is_zoomed
= !is_zoomed
;
298 /*****************************************************************************
299 * VideoWindow::MessageReceived
300 *****************************************************************************/
302 void VideoWindow::MessageReceived( BMessage
* p_message
)
306 switch( p_message
->what
)
310 // post the message to the interface window which will handle it
311 p_win
= beos_GetAppWindow( "interface" );
314 p_win
->PostMessage( p_message
);
319 BWindow::MessageReceived( p_message
);
324 /*****************************************************************************
325 * VideoWindow::QuitRequested
326 *****************************************************************************/
328 bool VideoWindow::QuitRequested()
330 /* FIXME: send a message ! */
331 p_main
->p_intf
->b_die
= 1;
332 teardownwindow
= true;
336 /*****************************************************************************
338 *****************************************************************************/
339 VLCView::VLCView(BRect bounds
) : BView(bounds
, "", B_FOLLOW_ALL
, B_WILL_DRAW
)
341 SetViewColor(B_TRANSPARENT_32_BIT
);
344 /*****************************************************************************
346 *****************************************************************************/
352 /*****************************************************************************
354 *****************************************************************************/
355 void VLCView::MouseDown(BPoint point
)
357 VideoWindow
*w
= (VideoWindow
*) Window();
360 BWindow
*win
= Window();
368 /*****************************************************************************
370 *****************************************************************************/
371 static int vout_Probe ( probedata_t
*p_data
);
372 static int vout_Create ( struct vout_thread_s
* );
373 static int vout_Init ( struct vout_thread_s
* );
374 static void vout_End ( struct vout_thread_s
* );
375 static void vout_Destroy ( struct vout_thread_s
* );
376 static int vout_Manage ( struct vout_thread_s
* );
377 static void vout_Display ( struct vout_thread_s
* );
379 static int BeosOpenDisplay ( vout_thread_t
*p_vout
);
380 static void BeosCloseDisplay( vout_thread_t
*p_vout
);
382 /*****************************************************************************
383 * Functions exported as capabilities. They are declared as static so that
384 * we don't pollute the namespace too much.
385 *****************************************************************************/
386 void _M( vout_getfunctions
)( function_list_t
* p_function_list
)
388 p_function_list
->pf_probe
= vout_Probe
;
389 p_function_list
->functions
.vout
.pf_create
= vout_Create
;
390 p_function_list
->functions
.vout
.pf_init
= vout_Init
;
391 p_function_list
->functions
.vout
.pf_end
= vout_End
;
392 p_function_list
->functions
.vout
.pf_destroy
= vout_Destroy
;
393 p_function_list
->functions
.vout
.pf_manage
= vout_Manage
;
394 p_function_list
->functions
.vout
.pf_display
= vout_Display
;
395 p_function_list
->functions
.vout
.pf_setpalette
= NULL
;
398 /*****************************************************************************
399 * vout_Probe: probe the video driver and return a score
400 *****************************************************************************
401 * This function tries to initialize SDL and returns a score to the
402 * plugin manager so that it can select the best plugin.
403 *****************************************************************************/
404 static int vout_Probe( probedata_t
*p_data
)
406 if( TestMethod( VOUT_METHOD_VAR
, "beos" ) )
414 /*****************************************************************************
415 * vout_Create: allocates BeOS video thread output method
416 *****************************************************************************
417 * This function allocates and initializes a BeOS vout method.
418 *****************************************************************************/
419 int vout_Create( vout_thread_t
*p_vout
)
421 /* Allocate structure */
422 p_vout
->p_sys
= (vout_sys_t
*) malloc( sizeof( vout_sys_t
) );
423 if( p_vout
->p_sys
== NULL
)
425 intf_ErrMsg( "error: %s", strerror(ENOMEM
) );
429 /* Set video window's size */
430 p_vout
->i_width
= main_GetIntVariable( VOUT_WIDTH_VAR
,
431 VOUT_WIDTH_DEFAULT
);
432 p_vout
->i_height
= main_GetIntVariable( VOUT_HEIGHT_VAR
,
433 VOUT_HEIGHT_DEFAULT
);
435 /* Open and initialize device */
436 if( BeosOpenDisplay( p_vout
) )
438 intf_ErrMsg("vout error: can't open display");
439 free( p_vout
->p_sys
);
446 /*****************************************************************************
447 * vout_Init: initialize BeOS video thread output method
448 *****************************************************************************/
449 int vout_Init( vout_thread_t
*p_vout
)
451 VideoWindow
* p_win
= p_vout
->p_sys
->p_window
;
455 i_page_size
= p_vout
->i_width
* p_vout
->i_height
* p_vout
->i_bytes_per_pixel
;
457 p_vout
->p_sys
->i_width
= p_vout
->i_width
;
458 p_vout
->p_sys
->i_height
= p_vout
->i_height
;
460 /* if(p_win->fUsingOverlay)
462 if(p_win->bitmap[0] != NULL)
464 p_vout->pf_setbuffers( p_vout,
465 (byte_t *)p_win->bitmap[0]->Bits(),
466 (byte_t *)p_win->bitmap[0]->Bits());
467 delete p_win->bitmap[0];
468 p_win->bitmap[0] = NULL;
473 if((p_win->bitmap[0] != NULL) && (p_win->bitmap[1] != NULL))
475 p_vout->pf_setbuffers( p_vout,
476 (byte_t *)p_win->bitmap[0]->Bits(),
477 (byte_t *)p_win->bitmap[1]->Bits());
480 if((p_win
->bitmap
[0] != NULL
) && (p_win
->bitmap
[1] != NULL
))
482 p_vout
->pf_setbuffers( p_vout
,
483 (byte_t
*)p_win
->bitmap
[0]->Bits(),
484 (byte_t
*)p_win
->bitmap
[1]->Bits());
490 /*****************************************************************************
491 * vout_End: terminate BeOS video thread output method
492 *****************************************************************************/
493 void vout_End( vout_thread_t
*p_vout
)
497 /*****************************************************************************
498 * vout_Destroy: destroy BeOS video thread output method
499 *****************************************************************************
500 * Terminate an output method created by DummyCreateOutputMethod
501 *****************************************************************************/
502 void vout_Destroy( vout_thread_t
*p_vout
)
504 BeosCloseDisplay( p_vout
);
506 free( p_vout
->p_sys
);
509 /*****************************************************************************
510 * vout_Manage: handle BeOS events
511 *****************************************************************************
512 * This function should be called regularly by video output thread. It manages
513 * console events. It returns a non null value on error.
514 *****************************************************************************/
515 int vout_Manage( vout_thread_t
*p_vout
)
517 VideoWindow
* p_win
= p_vout
->p_sys
->p_window
;
519 float minWidth
, minHeight
, maxWidth
, maxHeight
;
521 if( (p_vout
->i_width
!= p_vout
->p_sys
->i_width
) ||
522 (p_vout
->i_height
!= p_vout
->p_sys
->i_height
) )
524 /* If video output size has changed, change interface window size */
525 intf_DbgMsg( "resizing output window" );
526 if(p_win
->fUsingOverlay
)
529 p_win
->view
->ClearViewOverlay();
530 delete p_win
->bitmap
[0];
531 delete p_win
->bitmap
[1];
532 p_vout
->p_sys
->i_width
= p_vout
->i_width
;
533 p_vout
->p_sys
->i_height
= p_vout
->i_height
;;
534 p_win
->GetSizeLimits(&minWidth
, &maxWidth
, &minHeight
, &maxHeight
);
535 p_win
->SetSizeLimits((float) p_vout
->p_sys
->i_width
, maxWidth
, (float) p_vout
->p_sys
->i_height
, maxHeight
);
536 p_win
->ResizeTo(p_vout
->p_sys
->i_width
, p_vout
->p_sys
->i_height
);
537 p_win
->bitmap
[0] = new BBitmap(p_win
->Bounds(),
538 B_BITMAP_WILL_OVERLAY
|B_BITMAP_RESERVE_OVERLAY_CHANNEL
,
540 p_win
->bitmap
[0] = new BBitmap(p_win
->Bounds(),
541 B_BITMAP_WILL_OVERLAY
, B_YCbCr422
);
542 memset(p_win
->bitmap
[0]->Bits(), 0, p_win
->bitmap
[0]->BitsLength());
543 memset(p_win
->bitmap
[1]->Bits(), 0, p_win
->bitmap
[1]->BitsLength());
544 p_win
->view
->SetViewOverlay(p_win
->bitmap
[0], p_win
->bitmap
[0]->Bounds(), p_win
->Bounds(), &key
, B_FOLLOW_ALL
,
545 B_OVERLAY_FILTER_HORIZONTAL
|B_OVERLAY_FILTER_VERTICAL
|B_OVERLAY_TRANSFER_CHANNEL
);
546 p_win
->view
->SetViewColor(key
);
548 p_vout
->pf_setbuffers( p_vout
,
549 (byte_t
*)p_win
->bitmap
[0]->Bits(),
550 (byte_t
*)p_win
->bitmap
[0]->Bits());
551 delete p_win
->bitmap
[0];
557 /*****************************************************************************
558 * vout_Display: displays previously rendered output
559 *****************************************************************************
560 * This function send the currently rendered image to BeOS image, waits until
561 * it is displayed and switch the two rendering buffers, preparing next frame.
562 *****************************************************************************/
563 void vout_Display( vout_thread_t
*p_vout
)
565 VideoWindow
* p_win
= p_vout
->p_sys
->p_window
;
567 p_win
->i_buffer_index
= p_vout
->i_buffer_index
;
568 if(p_win
->fUsingOverlay
)
569 p_vout
->i_buffer_index
= p_vout
->i_buffer_index
& 1;
571 p_vout
->i_buffer_index
= ++p_vout
->i_buffer_index
& 1;
572 p_win
->fDirty
= true;
575 /* following functions are local */
577 /*****************************************************************************
578 * BeosOpenDisplay: open and initialize BeOS device
579 *****************************************************************************
580 * XXX?? The framebuffer mode is only provided as a fast and efficient way to
581 * display video, providing the card is configured and the mode ok. It is
582 * not portable, and is not supposed to work with many cards. Use at your
584 *****************************************************************************/
586 static int BeosOpenDisplay( vout_thread_t
*p_vout
)
588 p_vout
->p_sys
->p_window
=
589 new VideoWindow( BRect( 80, 50, 80+p_vout
->i_width
-1, 50+p_vout
->i_height
-1 ), NULL
, p_vout
);
590 if( p_vout
->p_sys
->p_window
== 0 )
592 free( p_vout
->p_sys
);
593 intf_ErrMsg( "error: cannot allocate memory for VideoWindow" );
596 VideoWindow
* p_win
= p_vout
->p_sys
->p_window
;
598 p_vout
->i_screen_depth
= p_win
->i_screen_depth
;
599 p_vout
->i_bytes_per_pixel
= p_win
->i_bytes_per_pixel
;
600 p_vout
->i_bytes_per_line
= p_vout
->i_width
*p_win
->i_bytes_per_pixel
;
602 switch( p_vout
->i_screen_depth
)
605 intf_ErrMsg( "vout error: 8 bit mode not fully supported" );
608 p_vout
->i_red_mask
= 0x7c00;
609 p_vout
->i_green_mask
= 0x03e0;
610 p_vout
->i_blue_mask
= 0x001f;
613 p_vout
->i_red_mask
= 0xf800;
614 p_vout
->i_green_mask
= 0x07e0;
615 p_vout
->i_blue_mask
= 0x001f;
620 p_vout
->i_red_mask
= 0xff0000;
621 p_vout
->i_green_mask
= 0x00ff00;
622 p_vout
->i_blue_mask
= 0x0000ff;
628 /*****************************************************************************
629 * BeosDisplay: close and reset BeOS device
630 *****************************************************************************
631 * Returns all resources allocated by BeosOpenDisplay and restore the original
632 * state of the device.
633 *****************************************************************************/
634 static void BeosCloseDisplay( vout_thread_t
*p_vout
)
636 /* Destroy the video window */
637 p_vout
->p_sys
->p_window
->Lock();
638 p_vout
->p_sys
->p_window
->Quit();