* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
-#define MODULE_NAME qnx
-#include "modules_inner.h"
-
/*****************************************************************************
* Preamble
*****************************************************************************/
-#include "defs.h"
-
#include <errno.h> /* ENOMEM */
#include <stdlib.h> /* free() */
#include <string.h> /* strerror() */
#include <photon/PtLabel.h>
#include <photon/PdDirect.h>
-#include "config.h"
-#include "common.h"
-#include "threads.h"
-#include "mtime.h"
-#include "tests.h"
+#include <videolan/vlc.h>
#include "video.h"
#include "video_output.h"
#include "interface.h"
-#include "intf_msg.h"
-#include "main.h"
-
-#include "modules.h"
-#include "modules_export.h"
/*****************************************************************************
* vout_sys_t: video output QNX method descriptor
/* position & dimensions */
PhPoint_t pos;
PhDim_t dim;
+ PhPoint_t old_pos;
PhDim_t old_dim;
PhDim_t screen_dim;
+ PhRect_t frame;
} vout_sys_t;
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static int vout_Probe ( probedata_t *p_data );
static int vout_Create ( struct vout_thread_s * );
static int vout_Init ( struct vout_thread_s * );
static void vout_End ( struct vout_thread_s * );
static int vout_Manage ( struct vout_thread_s * );
static void vout_Display ( struct vout_thread_s * );
+static int QNXInitDisplay ( struct vout_thread_s * );
static int QNXCreateWnd ( struct vout_thread_s * );
static int QNXDestroyWnd ( struct vout_thread_s * );
-static int QNXInitDisplay ( struct vout_thread_s * );
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
*****************************************************************************/
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;
p_function_list->functions.vout.pf_init = vout_Init;
p_function_list->functions.vout.pf_end = vout_End;
p_function_list->functions.vout.pf_setpalette = NULL;
}
-/*****************************************************************************
- * vout_Probe: probe the video driver and return a score
- *****************************************************************************
- * This function tries to initialize SDL and returns a score to the
- * plugin manager so that it can select the best plugin.
- *****************************************************************************/
-static int vout_Probe( probedata_t *p_data )
-{
- if( TestMethod( VOUT_METHOD_VAR, "qnx" ) )
- {
- return( 999 );
- }
-
- return( 100 );
-}
-
/*****************************************************************************
* vout_Create: allocate QNX video thread output method
*****************************************************************************
memset( p_vout->p_sys, 0, sizeof( vout_sys_t ) );
p_vout->b_fullscreen =
- main_GetIntVariable( VOUT_FULLSCREEN_VAR, VOUT_FULLSCREEN_DEFAULT );
+ config_GetIntVariable( "fullscreen" );
p_vout->p_sys->i_mode =
- main_GetIntVariable( VOUT_OVERLAY_VAR, VOUT_OVERLAY_DEFAULT ) ?
- MODE_VIDEO_OVERLAY : MODE_NORMAL_MEM;
- p_vout->p_sys->dim.w =
- main_GetIntVariable( VOUT_WIDTH_VAR, VOUT_WIDTH_DEFAULT );
- p_vout->p_sys->dim.h =
- main_GetIntVariable( VOUT_HEIGHT_VAR, VOUT_HEIGHT_DEFAULT );
-
+ config_GetIntVariable( "nooverlay" ) ?
+ MODE_NORMAL_MEM : MODE_VIDEO_OVERLAY;
+ p_vout->p_sys->dim.w = p_vout->i_window_width;
+ p_vout->p_sys->dim.h = p_vout->i_window_height;
+
/* init display and create window */
if( QNXInitDisplay( p_vout ) || QNXCreateWnd( p_vout ) )
{
*****************************************************************************/
static int vout_Init( vout_thread_t *p_vout )
{
- if( p_vout->p_sys->i_mode == MODE_NORMAL_MEM ||
- p_vout->p_sys->i_mode == MODE_SHARED_MEM )
+ /* These variables are only used if we are in overlay mode */
+ int i_ret;
+ PgScalerProps_t props;
+
+ switch( p_vout->p_sys->i_mode )
{
+ case MODE_NORMAL_MEM:
+ case MODE_SHARED_MEM:
/* create images for [shared] memory blit */
-
if( !( p_vout->p_sys->p_image[0] = PhCreateImage( NULL,
p_vout->p_sys->dim.w, p_vout->p_sys->dim.h,
p_vout->p_sys->i_img_type, NULL, 0,
/* set bytes per line, set buffers */
p_vout->i_bytes_per_line = p_vout->p_sys->p_image[0]->bpl;
p_vout->pf_setbuffers( p_vout, p_vout->p_sys->p_image[0]->image,
- p_vout->p_sys->p_image[1]->image );
- }
- else if( p_vout->p_sys->i_mode == MODE_VIDEO_MEM )
- {
- /* create offscreen contexts for video memory blit */
+ p_vout->p_sys->p_image[1]->image );
+ break;
+ case MODE_VIDEO_MEM:
+ /* create offscreen contexts for video memory blit */
if( ( p_vout->p_sys->p_ctx[0] = PdCreateOffscreenContext( 0,
p_vout->p_sys->dim.w, p_vout->p_sys->dim.h,
Pg_OSC_MEM_PAGE_ALIGN ) ) == NULL )
}
/* set bytes per line, clear buffers, set buffers */
- p_vout->i_bytes_per_line =
- p_vout->i_bytes_per_pixel * p_vout->p_sys->dim.w;
+ p_vout->i_bytes_per_line = p_vout->p_sys->p_ctx[0]->pitch;
memset( p_vout->p_sys->p_buf[0], 0,
p_vout->i_bytes_per_line * p_vout->p_sys->dim.h );
memset( p_vout->p_sys->p_buf[1], 0,
p_vout->i_bytes_per_line * p_vout->p_sys->dim.h );
p_vout->pf_setbuffers( p_vout, p_vout->p_sys->p_buf[0],
- p_vout->p_sys->p_buf[1] );
- }
- else if( p_vout->p_sys->i_mode == MODE_VIDEO_OVERLAY )
- {
- PgScalerProps_t props;
+ p_vout->p_sys->p_buf[1] );
- props.size = sizeof( props );
+ case MODE_VIDEO_OVERLAY:
+ props.size = sizeof( props );
props.format = p_vout->p_sys->i_vc_format;
- props.viewport.ul.x = p_vout->p_sys->pos.x + 4;
- props.viewport.ul.y = p_vout->p_sys->pos.y + 20;
+ props.flags = Pg_SCALER_PROP_SCALER_ENABLE |
+ Pg_SCALER_PROP_DOUBLE_BUFFER;
+
+ /* enable chroma keying if available */
+ if( p_vout->p_sys->i_vc_flags & Pg_SCALER_CAP_DST_CHROMA_KEY )
+ {
+ props.flags |= Pg_SCALER_PROP_CHROMA_ENABLE;
+ }
+
+ /* set viewport position */
+ props.viewport.ul.x = p_vout->p_sys->pos.x;
+ props.viewport.ul.y = p_vout->p_sys->pos.y;
+ if( !p_vout->b_fullscreen )
+ {
+ props.viewport.ul.x += p_vout->p_sys->frame.ul.x;
+ props.viewport.ul.y += p_vout->p_sys->frame.ul.y;
+ }
+
+ /* set viewport dimension */
props.viewport.lr.x = p_vout->p_sys->dim.w + props.viewport.ul.x;
props.viewport.lr.y = p_vout->p_sys->dim.h + props.viewport.ul.y;
- props.src_dim.w = p_vout->p_sys->dim.w;
- props.src_dim.h = p_vout->p_sys->dim.h;
- props.flags = Pg_SCALER_PROP_SCALER_ENABLE |
- Pg_SCALER_PROP_DOUBLE_BUFFER;
- if( PgConfigScalerChannel( p_vout->p_sys->p_channel, &props ) == -1 )
+ /* set source dimension */
+ props.src_dim.w = p_vout->i_width;
+ props.src_dim.h = p_vout->i_height;
+
+ /* configure scaler channel */
+ i_ret = PgConfigScalerChannel( p_vout->p_sys->p_channel, &props );
+
+ if( i_ret == -1 )
{
intf_ErrMsg( "vout error: unable to configure video channel" );
return( 1 );
}
-
- p_vout->p_sys->p_vc_y[0] =
- PdGetOffscreenContextPtr( p_vout->p_sys->p_channel->yplane1 );
- p_vout->p_sys->p_vc_y[1] =
- PdGetOffscreenContextPtr( p_vout->p_sys->p_channel->yplane2 );
-
- if( p_vout->p_sys->p_vc_y[0] == NULL ||
- p_vout->p_sys->p_vc_y[1] == NULL )
+ else if( i_ret == 1 )
{
- intf_ErrMsg( "vout error: unable to get video channel ctx ptr" );
- return( 1 );
+ p_vout->p_sys->p_vc_y[0] =
+ PdGetOffscreenContextPtr( p_vout->p_sys->p_channel->yplane1 );
+ p_vout->p_sys->p_vc_y[1] =
+ PdGetOffscreenContextPtr( p_vout->p_sys->p_channel->yplane2 );
+
+ if( p_vout->p_sys->p_vc_y[0] == NULL ||
+ p_vout->p_sys->p_vc_y[1] == NULL )
+ {
+ intf_ErrMsg( "vout error: unable to get video channel ctx ptr" );
+ return( 1 );
+ }
}
- if( p_vout->p_sys->i_vc_format == Pg_VIDEO_FORMAT_YV12 )
+ if( p_vout->p_sys->i_vc_format == Pg_VIDEO_FORMAT_YV12 && i_ret == 1 )
{
p_vout->b_need_render = 0;
{
/* set bytes per line, clear buffers, set buffers */
p_vout->i_bytes_per_line =
- p_vout->i_bytes_per_pixel * p_vout->p_sys->dim.w;
+ p_vout->p_sys->p_channel->yplane1->pitch;
memset( p_vout->p_sys->p_vc_y[0], 0,
- p_vout->i_bytes_per_line * p_vout->p_sys->dim.h );
+ p_vout->i_bytes_per_line * p_vout->i_height );
memset( p_vout->p_sys->p_vc_y[1], 0,
- p_vout->i_bytes_per_line * p_vout->p_sys->dim.h );
+ p_vout->i_bytes_per_line * p_vout->i_height );
p_vout->pf_setbuffers( p_vout,
p_vout->p_sys->p_vc_y[0], p_vout->p_sys->p_vc_y[1] );
}
+ break;
+
+ default:
+ /* This shouldn't happen ! */
+ break;
}
return( 0 );
break;
case Ph_WM_MOVE:
- b_repos = 1;
p_vout->p_sys->pos.x = p_ev->pos.x;
p_vout->p_sys->pos.y = p_ev->pos.y;
+ b_repos = 1;
break;
case Ph_WM_RESIZE:
p_vout->p_sys->old_dim.w = p_vout->p_sys->dim.w;
p_vout->p_sys->old_dim.h = p_vout->p_sys->dim.h;
- p_vout->p_sys->dim.w = p_vout->i_width = p_ev->size.w;
- p_vout->p_sys->dim.h = p_vout->i_height = p_ev->size.h;
+ p_vout->p_sys->dim.w = p_ev->size.w;
+ p_vout->p_sys->dim.h = p_ev->size.h;
p_vout->i_changes |= VOUT_SIZE_CHANGE;
break;
}
{
network_ChannelJoin( i_key );
}
- else if( intf_ProcessKey( p_main->p_intf,
- (char) i_key ) )
- {
- intf_DbgMsg( "vout: unhandled key '%c' (%i)",
- (char) i_key, i_key );
- }
break;
}
}
if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE )
{
PhDim_t dim;
- PhPoint_t pos;
-
- intf_DbgMsg( "vout: changing full-screen status" );
p_vout->b_fullscreen = !p_vout->b_fullscreen;
p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
if( p_vout->b_fullscreen )
{
- pos.x = pos.y = 0;
+ p_vout->p_sys->old_pos.x = p_vout->p_sys->pos.x;
+ p_vout->p_sys->old_pos.y = p_vout->p_sys->pos.y;
+ p_vout->p_sys->pos.x = p_vout->p_sys->pos.y = 0;
dim.w = p_vout->p_sys->screen_dim.w + 1;
dim.h = p_vout->p_sys->screen_dim.h + 1;
}
else
{
- pos.x = p_vout->p_sys->pos.x;
- pos.y = p_vout->p_sys->pos.y;
+ p_vout->p_sys->pos.x = p_vout->p_sys->old_pos.x;
+ p_vout->p_sys->pos.y = p_vout->p_sys->old_pos.y;
dim.w = p_vout->p_sys->old_dim.w + 1;
dim.h = p_vout->p_sys->old_dim.h + 1;
}
+ /* modify render flags, border */
PtSetResource( p_vout->p_sys->p_window,
Pt_ARG_WINDOW_RENDER_FLAGS,
p_vout->b_fullscreen ? Pt_FALSE : Pt_TRUE,
Ph_WM_RENDER_BORDER | Ph_WM_RENDER_TITLE );
+
+ /* set position and dimension */
PtSetResource( p_vout->p_sys->p_window,
- Pt_ARG_POS, &pos, 0 );
+ Pt_ARG_POS, &p_vout->p_sys->pos, 0 );
PtSetResource( p_vout->p_sys->p_window,
- Pt_ARG_DIM, &dim, 0 );
- }
-
- /*
- * vout window resizing
- */
- if( ( p_vout->i_width != p_vout->p_sys->dim.w ) ||
- ( p_vout->i_height != p_vout->p_sys->dim.h ) )
- {
- intf_DbgMsg( "vout: resizing output window" );
-
- p_vout->p_sys->dim.w = p_vout->i_width;
- p_vout->p_sys->dim.h = p_vout->i_height;
+ Pt_ARG_DIM, &dim, 0 );
- /* set new dimension */
- PtSetResource( p_vout->p_sys->p_window,
- Pt_ARG_DIM, &p_vout->p_sys->dim, 0 );
+ /* mark as damaged to force redraw */
+ PtDamageWidget( p_vout->p_sys->p_window );
}
/*
*/
if( p_vout->i_changes & VOUT_SIZE_CHANGE )
{
- intf_DbgMsg( "vout: resizing window" );
p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
+ if( p_vout->p_sys->i_mode != MODE_VIDEO_OVERLAY )
+ {
+ p_vout->i_width = p_vout->p_sys->dim.w;
+ p_vout->i_height = p_vout->p_sys->dim.h;
+ p_vout->i_changes |= VOUT_YUV_CHANGE;
+ }
+
vout_End( p_vout );
if( vout_Init( p_vout ) )
{
return( 1 );
}
- p_vout->i_changes |= VOUT_YUV_CHANGE;
intf_Msg( "vout: video display resized (%dx%d)",
- p_vout->i_width, p_vout->i_height );
+ p_vout->p_sys->dim.w, p_vout->p_sys->dim.h );
}
/*
*/
if( b_repos && p_vout->p_sys->i_mode == MODE_VIDEO_OVERLAY )
{
- intf_DbgMsg( "vout: moving video channel" );
-
vout_End( p_vout );
if( vout_Init( p_vout ) )
{
return( 1 );
}
+ /* switch to normal mode if no overlay support */
+ if( p_vout->p_sys->i_mode == MODE_VIDEO_OVERLAY &&
+ !( minfo.mode_capabilities1 & PgVM_MODE_CAP1_VIDEO_OVERLAY ) )
+ {
+ intf_ErrMsg( "vout error: no overlay support detected" );
+ p_vout->p_sys->i_mode = MODE_NORMAL_MEM;
+ }
+
/* use video ram if we have enough available */
if( p_vout->p_sys->i_mode == MODE_NORMAL_MEM &&
hwcaps.currently_available_video_ram >=
( ( minfo.width * minfo.height * minfo.bits_per_pixel ) / 8 ) )
{
- intf_DbgMsg( "vout: using video ram" );
p_vout->p_sys->i_mode = MODE_VIDEO_MEM;
}
switch( p_vout->i_screen_depth )
{
case 15:
- p_vout->i_red_mask = 0x7c00;
- p_vout->i_green_mask = 0x03e0;
- p_vout->i_blue_mask = 0x001f;
+ p_vout->output.i_rmask = 0x7c00;
+ p_vout->output.i_gmask = 0x03e0;
+ p_vout->output.i_bmask = 0x001f;
break;
case 16:
- p_vout->i_red_mask = 0xf800;
- p_vout->i_green_mask = 0x07e0;
- p_vout->i_blue_mask = 0x001f;
+ p_vout->output.i_rmask = 0xf800;
+ p_vout->output.i_gmask = 0x07e0;
+ p_vout->output.i_bmask = 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;
+ p_vout->output.i_rmask = 0xff0000;
+ p_vout->output.i_gmask = 0x00ff00;
+ p_vout->output.i_bmask = 0x0000ff;
break;
}
PhPoint_t pos = { 0, 0 };
PgColor_t color = Pg_BLACK;
- /* correct way to check for overlay support:
-
- 1. call PgGetGraphicsHWCaps and check
- the results for Pg_VIDEO_OVERLAY
- 2. check if the current graphics mode
- has PgVM_MODE_CAP1_VIDEO_OVERLAY set
- 3. call PgGetScalerCapabilities for info
-
- problems:
-
- 1. Pg_VIDEO_OVERLAY is not defined in any
- header files :)
- 2. PgVM_MODE_CAP1_VIDEO_OVERLAY is not set
- even if the current mode supports overlay
- 3. the flags (chroma, etc) do not reflect
- the actual capabilities
- */
-
if( p_vout->p_sys->i_mode == MODE_VIDEO_OVERLAY )
{
+ int i = 0;
+ PgScalerCaps_t vcaps;
+
if( ( p_vout->p_sys->p_channel =
PgCreateVideoChannel( Pg_VIDEO_CHANNEL_SCALER, 0 ) ) == NULL )
{
intf_ErrMsg( "vout error: unable to create video channel" );
return( 1 );
}
- else
- {
- int i = 0;
- PgScalerCaps_t vcaps;
- vcaps.size = sizeof( vcaps );
- while( PgGetScalerCapabilities( p_vout->p_sys->p_channel,
- i++, &vcaps ) == 0 )
- {
- if( vcaps.format == Pg_VIDEO_FORMAT_YV12 ||
- vcaps.format == Pg_VIDEO_FORMAT_RGB8888 )
- {
- p_vout->p_sys->i_vc_flags = vcaps.flags;
- p_vout->p_sys->i_vc_format = vcaps.format;
- }
-
- vcaps.size = sizeof( vcaps );
- }
-
- if( p_vout->p_sys->i_vc_format == 0 )
+ vcaps.size = sizeof( vcaps );
+ while( PgGetScalerCapabilities( p_vout->p_sys->p_channel,
+ i++, &vcaps ) == 0 )
+ {
+ if( vcaps.format == Pg_VIDEO_FORMAT_YV12 ||
+ vcaps.format == Pg_VIDEO_FORMAT_RGB8888 )
{
- intf_ErrMsg( "vout error: need YV12 or RGB8888 overlay" );
- return( 1 );
- }
- else if( vcaps.flags & Pg_SCALER_CAP_DST_CHROMA_KEY )
- {
- color = PgGetOverlayChromaColor();
+ p_vout->p_sys->i_vc_flags = vcaps.flags;
+ p_vout->p_sys->i_vc_format = vcaps.format;
}
+
+ vcaps.size = sizeof( vcaps );
+ }
+
+ if( p_vout->p_sys->i_vc_format == 0 )
+ {
+ intf_ErrMsg( "vout error: need YV12 or RGB8888 overlay" );
+
+ return( 1 );
+ }
+
+ if( p_vout->p_sys->i_vc_flags & Pg_SCALER_CAP_DST_CHROMA_KEY )
+ {
+ color = PgGetOverlayChromaColor();
}
}
PtSetArg( &args[3], Pt_ARG_WINDOW_TITLE, "VideoLan Client", 0 );
PtSetArg( &args[4], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_CLOSE );
PtSetArg( &args[5], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE,
- Ph_WM_MOVE | Ph_WM_RESIZE | Ph_WM_CLOSE );
+ Ph_WM_MOVE | Ph_WM_RESIZE | Ph_WM_CLOSE );
PtSetArg( &args[6], Pt_ARG_WINDOW_RENDER_FLAGS,
- p_vout->b_fullscreen ? Pt_FALSE : Pt_TRUE,
- Ph_WM_RENDER_BORDER | Ph_WM_RENDER_TITLE );
+ p_vout->b_fullscreen ? Pt_FALSE : Pt_TRUE,
+ Ph_WM_RENDER_BORDER | Ph_WM_RENDER_TITLE );
/* create window */
p_vout->p_sys->p_window = PtCreateWidget( PtWindow, Pt_NO_PARENT, 7, args);
return( 1 );
}
+ /* get window frame size */
+ if( PtWindowFrameSize( NULL, p_vout->p_sys->p_window,
+ &p_vout->p_sys->frame ) != 0 )
+ {
+ intf_ErrMsg( "vout error: unable to get window frame size" );
+ PtDestroyWidget( p_vout->p_sys->p_window );
+ return( 1 );
+ }
+
return( 0 );
}