.*
+*.ts
core
dep
gmon.out
misc/rsc_files.o \
misc/netutils.o
-ifeq ($(VIDEO),X11)
-misc_obj+= misc/xutils.o
-endif
-
ifeq ($(ARCH),MMX)
ASM_OBJ = video_decoder_ref/idctmmx.o \
video_output/yuv_mmx.o
* + variable names should end with '_VAR'
* + environment variable default value should end with '_DEFAULT'
* + values having a special meaning with '_VAL'
- * + complete environment strings with '_ENV'
*
*/
* Program information
*******************************************************************************/
-/* Program options */
+/* Program options - this part will produce a copyright message with compilation
+ * options informations, based on some definines set in the Makefile - do not
+ * edit */
#if defined(VIDEO_X11)
-#define VIDEO_OPTIONS "X11"
+#define VIDEO_OPTIONS "X11"
#elif defined(VIDEO_FB)
-#define VIDEO_OPTIONS "Framebuffer"
+#define VIDEO_OPTIONS "Framebuffer"
#elif defined(VIDEO_GGI)
-#define VIDEO_OPTIONS "GGI"
+#define VIDEO_OPTIONS "GGI"
#else
-#define VIDEO_OPTIONS ""
+#define VIDEO_OPTIONS ""
#endif
#if defined(HAVE_MMX)
-#define ARCH_OPTIONS "MMX"
+#define ARCH_OPTIONS "MMX"
#else
-#define ARCH_OPTIONS ""
+#define ARCH_OPTIONS ""
#endif
-#define PROGRAM_OPTIONS VIDEO_OPTIONS " " ARCH_OPTIONS
+#define PROGRAM_OPTIONS VIDEO_OPTIONS " " ARCH_OPTIONS
/* Program version and copyright message */
-#define PROGRAM_VERSION "1.0-dev"
-#define COPYRIGHT_MESSAGE "VideoLAN Client v" PROGRAM_VERSION " (" __DATE__ ") - " PROGRAM_OPTIONS " - (c)1999-2000 VideoLAN\n"
+#define PROGRAM_VERSION "DR 2.1"
+#define COPYRIGHT_MESSAGE "VideoLAN Client v" PROGRAM_VERSION " (" __DATE__ ") - " \
+ PROGRAM_OPTIONS " - (c)1999 VideoLAN"
/*******************************************************************************
* General compilation options
* and might cause problems with some very weird streams. */
//#define MPEG2_COMPLIANT
-/* Define for profiling support */
+/* Define for profiling and statistics support - such informations, like FPS
+ * or pictures count won't be available if it not set */
#define STATS
/* Define for unthreaded version of the program - ?? not yet implemented */
/* General debugging support */
#define DEBUG
-/* Extended debugging support - in this mode, debugging messages will have their
- * date and context printed */
-#define DEBUG_CONTEXT
-
-/* Modules specific debugging */
+/* Modules specific debugging - this will produce a lot of output, but can be
+ * usefull to track a bug */
#define DEBUG_INTF
#define DEBUG_INPUT
#define DEBUG_AUDIO
/* Debugging log file - if defined, a file can be used to store all messages. If
* DEBUG_LOG_ONLY is defined, debug messages will only be printed to the log and
* will not appear on the screen */
-#define DEBUG_LOG "vlc-debug.log"
-#define DEBUG_LOG_ONLY
-
+#define DEBUG_LOG "vlc-debug.log"
+#define DEBUG_LOG_ONLY
/*******************************************************************************
- * Common settings
+ * General configuration
*******************************************************************************/
/* Automagically spawn input, audio and video threads ? */
+// ?? used ?
#define AUTO_SPAWN
-/* Startup script */
-#define INTF_INIT_SCRIPT_VAR "vlc_init"
-#define INTF_INIT_SCRIPT_DEFAULT "vlc.init"
-
-/* ?? */
-#define THREAD_SLEEP 100000
+/* When creating or destroying threads in blocking mode, delay to poll thread
+ * status */
+#define THREAD_SLEEP 10000
/*
- * X11/XLib settings
+ * Decoders FIFO configuration
*/
-/* Default font used when a wished font could not be loaded - note that this
- * font should be universal, else the program will exit when it can't find
- * a font */
-#define X11_DEFAULT_FONT "fixed"
+/* Size of the FIFO. FIFO_SIZE+1 must be a multiple of 2 */
+#define FIFO_SIZE 1023
+
+
+/*******************************************************************************
+ * Interface configuration
+ *******************************************************************************/
+
+/* Environment variable used to store startup script name and default value */
+#define INTF_INIT_SCRIPT_VAR "vlc_init"
+#define INTF_INIT_SCRIPT_DEFAULT "vlc.init"
+
+/* Base delay in micro second for interface sleeps */
+#define INTF_IDLE_SLEEP 100000
/*
- * Decoders FIFO configuration
+ * X11 settings
*/
-/* Size of the FIFO. FIFO_SIZE+1 must be a multiple of 2 */
-#define FIFO_SIZE 1023
+/* Title of the X11 window */
+#define VOUT_TITLE "VideoLAN Client"
+
+/* Environment variable used in place of DISPLAY if available */
+#define ENV_VLC_DISPLAY "vlc_DISPLAY"
/*******************************************************************************
* Input thread configuration
* Default settings for video output threads
*/
-/* Title of the window */
-#define VOUT_TITLE "VideoLAN Client"
-
/* Default dimensions for display window - these dimensions are the standard
* width and height for broadcasted MPEG-2 */
#define VOUT_WIDTH 544
#define VOUT_GRAYSCALE_VAR "vlc_grayscale"
#define VOUT_GRAYSCALE_DEFAULT 0
-/* Number of pictures required to computes the FPS rate */
-#define VOUT_FPS_SAMPLES 5
-
/*
* Time settings
*/
/* ?? this constant will probably evolve to a calculated value */
#define VOUT_DISPLAY_DELAY 100000
+/* Delay (in microseconds) between increments in idle levels */
+#define VOUT_IDLE_DELAY 5000000
+
+/* Number of pictures required to computes the FPS rate */
+#define VOUT_FPS_SAMPLES 5
+
/*
* Framebuffer settings
*/
/* Font maximum and minimum characters - characters outside this range are not
* printed - maximum range is 1-256 */
-#define VOUT_MIN_CHAR 1
-#define VOUT_MAX_CHAR 128
+#define VOUT_MIN_CHAR 1
+#define VOUT_MAX_CHAR 128
/*******************************************************************************
* Video parser configuration
#define GDEC_IDLE_SLEEP 100000
/*******************************************************************************
- * Interface (main) thread configuration
- *******************************************************************************/
-
-/*
- * Interface configuration
- */
-
-/* Base delay in micro second for interface sleeps ?? */
-#define INTF_IDLE_SLEEP 100000
-
-/* Maximal number of arguments on a command line, including the function name */
-#define INTF_MAX_ARGS 20
-
-/* Maximal size of a command line in a script */
-#define INTF_MAX_CMD_SIZE 240
-/*
- * X11 interface properties
- */
-#define INTF_APP_CLASS "vlc"
-#define INTF_APP_NAME "vlc"
-
-/*
- * X11 console properties
- */
-
-/* Title of the X11 console interface window */
-#define INTF_XCONSOLE_TITLE "VideoLAN Client: console"
-
-/* Welcome message: this message is always displayed when a new console is
- * openned */
-#define INTF_XCONSOLE_WELCOME_MSG COPYRIGHT_MESSAGE "try `help' to have a list of available commands"
-
-/* Background pixmap - if not defined, no pixmap is used */
-#define INTF_XCONSOLE_BACKGROUND_PIXMAP "Resources/background.xpm"
-
-/* Default X11 console interface window geometry. It should at least give a
- * default size */
-#define INTF_XCONSOLE_GEOMETRY "400x100"
-
-/* Font used in console. If first font is not found, the fallback font is
- * used. Therefore, the fallback font should be a universal one. */
-#define INTF_XCONSOLE_FONT "-*-helvetica-medium-r-normal-*-18-*-*-*-*-*-iso8859-1"
-
-/* Number of memorized lines in X11 console window text zone */
-#define INTF_CONSOLE_MAX_TEXT 100
-
-/* Maximal number of commands which can be saved in history list */
-#define INTF_CONSOLE_MAX_HISTORY 20
-
-/* Maximum width of a line in an X11 console window. If a larger line is
- * printed, it will be wrapped. */
-#define INTF_XCONSOLE_MAX_LINE_WIDTH 120
-
-#define ENV_VLC_DISPLAY "vlc_DISPLAY"
-
-#define INTF_MAIN_WIDTH 600
-#define INTF_MAIN_HEIGHT 600
-
-/*******************************************************************************
- * Interface messages functions
+ * Messages and console interfaces configuration
*******************************************************************************/
/* Maximal size of the message queue - in case of overflow, all messages in the
/* Format of the header for debug messages. The arguments following this header
* are the file (char *), the function (char *) and the line (int) in which the
* message function was called */
-#define INTF_MSG_DBG_FORMAT "## %s:%s(),%i: "
+#define INTF_MSG_DBG_FORMAT "## %s:%s(),%i: "
+
+/* Maximal number of arguments on a command line, including the function name */
+#define INTF_MAX_ARGS 20
+
+/* Maximal size of a command line in a script */
+#define INTF_MAX_CMD_SIZE 240
+
+/* Number of memorized lines in console window text zone */
+#define INTF_CONSOLE_MAX_TEXT 100
+
+/* Maximal number of commands which can be saved in history list */
+#define INTF_CONSOLE_MAX_HISTORY 20
/*******************************************************************************
* Network and VLAN management
float f_x_ratio; /* horizontal display ratio */
float f_y_ratio; /* vertical display ratio */
+ /* New size for resizeable windows - they may be ignored or handled by
+ * vout_SysManage */
+ int i_new_width; /* new width */
+ int i_new_height; /* new height */
+
#ifdef STATS
- /* Statistics */
+ /* Statistics - these numbers are not supposed to be accurate */
count_t c_loops; /* number of loops */
count_t c_idle_loops; /* number of idle loops */
- count_t c_pictures; /* number of pictures added to heap */
-
- /* FPS */
- mtime_t fps_sample[ VOUT_FPS_SAMPLES ]; /* samples dates */
- int i_fps_index; /* index in samples */
+ count_t c_fps_samples; /* picture counts */
+ mtime_t fps_sample[ VOUT_FPS_SAMPLES ]; /* FPS samples dates */
#endif
#ifdef DEBUG_VIDEO
p_vout_sys_t p_sys; /* system output method */
/* Video heap */
- int i_pictures; /* current heap size */
picture_t p_picture[VOUT_MAX_PICTURES]; /* pictures */
/* YUV translation tables, for 15,16 and 24/32 bpp displays. 16 bits and 32
#include "vlc_thread.h"
#include "netutils.h"
#include "debug.h"
-#include "xutils.h"
#include "intf_msg.h"
/* Input */
+++ /dev/null
-/*******************************************************************************
- * xutils.h: X11 utilities
- * (c)1999 VideoLAN
- *******************************************************************************
- * This library includes many usefull functions to perform simple operations
- * using Xlib.
- *******************************************************************************
- * Required headers:
- * <X11/Xlib.h>
- *******************************************************************************/
-
-/*******************************************************************************
- * Prototypes
- *******************************************************************************/
-int XTryLoadFont( Display *p_display, char *psz_font, XFontStruct **p_font );
-void XEnableScreenSaver( Display *p_display );
-void XDisableScreenSaver( Display *p_display );
intf_MsgDestroy();
return(errno);
}
- intf_MsgImm( COPYRIGHT_MESSAGE ); /* print welcome message */
+ intf_MsgImm( COPYRIGHT_MESSAGE "\n" ); /* print welcome message */
/*
* Initialize shared resources and libraries
******************************************************************************
* Uses the gettimeofday() function when possible (1 MHz resolution) or the
* ftime() function (1 kHz resolution).
- ******************************************************************************
- * to-do list: ??
- * implement the function when gettimeofday is not available
- * this function should be decalred as inline
******************************************************************************/
mtime_t mdate( void )
{
* This function uses select() and an system date function to wake up at a
* precise date. It should be used for process synchronization. If current date
* is posterior to wished date, the function returns immediately.
- ******************************************************************************
- * to-do list:
- * implement the function when gettimeofday is not available
- * optimize delay calculation
- * ?? declare as inline
******************************************************************************/
void mwait( mtime_t date )
{
+++ /dev/null
-/*******************************************************************************
- * xutils.c: X11 utilities
- * (c)1998 VideoLAN
- *******************************************************************************
- * This library includes many usefull functions to perform simple operations
- * using Xlib.
- *******************************************************************************/
-
-/*******************************************************************************
- * Preamble
- *******************************************************************************/
-
-#include <stdio.h>
-#include <X11/Xlib.h>
-#include <X11/extensions/XShm.h>
-
-#include "config.h"
-#include "common.h"
-#include "mtime.h"
-#include "intf_msg.h"
-#include "xutils.h"
-
-
-/*******************************************************************************
- * XTryLoadFont: try to load a font and a fallback font
- *******************************************************************************
- * This function try to load a font, and, on failure, a default fallback font
- * (usually 'fixed'). This function returns 0 on success, >0 if it failed but
- * the default font
- *******************************************************************************/
-int XTryLoadFont( Display *p_display, char *psz_font, XFontStruct **p_font )
-{
- *p_font = XLoadQueryFont( p_display, psz_font );
- if( *p_font ) /* success */
- {
- return( 0 );
- }
-
- intf_DbgMsg("X11 error: can't load font `%s', using `%s' instead\n", p_font, X11_DEFAULT_FONT );
- *p_font = XLoadQueryFont( p_display, X11_DEFAULT_FONT );
- if( *p_font ) /* success */
- {
- return( 1 );
- }
-
- /* Fatal error */
- intf_ErrMsg("X11 error: can't load fallback font `%s'\n", X11_DEFAULT_FONT );
- return( -1 );
-}
-
-/*******************************************************************************
- * XEnableScreenSaver: enable screen saver
- *******************************************************************************
- * This function enable the screen saver on a display after it had been
- * disabled by XDisableScreenSaver. Both functions use a counter mechanism to
- * know wether the screen saver can be activated or not: if n successive calls
- * are made to XDisableScreenSaver, n successive calls to XEnableScreenSaver
- * will be required before the screen saver could effectively be activated.
- *******************************************************************************/
-void XEnableScreenSaver( Display *p_display )
-{
- /* ?? */
-}
-
-/*******************************************************************************
- * XDisableScreenSaver: disable screen saver
- *******************************************************************************
- * See XEnableScreenSaver
- *******************************************************************************/
-void XDisableScreenSaver( Display *p_display )
-{
- /* ?? */
-}
/* Buffers informations */
int i_buffer_index; /* buffer index */
- ggi_directbuffer * pp_buffer[2]; /* buffers */
+ ggi_directbuffer * p_buffer[2]; /* buffers */
boolean_t b_must_acquire; /* must be acquired before writing */
/* Characters size */
p_vout->p_sys->i_buffer_index = 0;
if( p_vout->p_sys->b_must_acquire )
{
- ggiResourceAcquire( p_vout->p_sys->pp_buffer[ 0 ]->resource, GGI_ACTYPE_WRITE );
+ ggiResourceAcquire( p_vout->p_sys->p_buffer[ 0 ]->resource, GGI_ACTYPE_WRITE );
}
return( 0 );
/* Release buffer */
if( p_vout->p_sys->b_must_acquire )
{
- ggiResourceRelease( p_vout->p_sys->pp_buffer[ p_vout->p_sys->i_buffer_index ]->resource );
+ ggiResourceRelease( p_vout->p_sys->p_buffer[ p_vout->p_sys->i_buffer_index ]->resource );
}
}
/* Change display frame */
if( p_vout->p_sys->b_must_acquire )
{
- ggiResourceRelease( p_vout->p_sys->pp_buffer[ p_vout->p_sys->i_buffer_index ]->resource );
+ ggiResourceRelease( p_vout->p_sys->p_buffer[ p_vout->p_sys->i_buffer_index ]->resource );
}
ggiFlush( p_vout->p_sys->p_display ); // ??
ggiSetDisplayFrame( p_vout->p_sys->p_display,
- p_vout->p_sys->pp_buffer[ p_vout->p_sys->i_buffer_index ]->frame );
+ p_vout->p_sys->p_buffer[ p_vout->p_sys->i_buffer_index ]->frame );
/* Swap buffers and change write frame */
p_vout->p_sys->i_buffer_index = ++p_vout->p_sys->i_buffer_index & 1;
if( p_vout->p_sys->b_must_acquire )
{
- ggiResourceAcquire( p_vout->p_sys->pp_buffer[ p_vout->p_sys->i_buffer_index ]->resource,
+ ggiResourceAcquire( p_vout->p_sys->p_buffer[ p_vout->p_sys->i_buffer_index ]->resource,
GGI_ACTYPE_WRITE );
}
ggiSetWriteFrame( p_vout->p_sys->p_display,
- p_vout->p_sys->pp_buffer[ p_vout->p_sys->i_buffer_index ]->frame );
+ p_vout->p_sys->p_buffer[ p_vout->p_sys->i_buffer_index ]->frame );
}
/*******************************************************************************
*******************************************************************************/
byte_t * vout_SysGetPicture( vout_thread_t *p_vout )
{
- return( p_vout->p_sys->pp_buffer[ p_vout->p_sys->i_buffer_index ]->write );
+ return( p_vout->p_sys->p_buffer[ p_vout->p_sys->i_buffer_index ]->write );
}
/*******************************************************************************
for( i_index = 0; i_index < 2; i_index++ )
{
/* Get buffer address */
- p_vout->p_sys->pp_buffer[ i_index ] =
+ p_vout->p_sys->p_buffer[ i_index ] =
ggiDBGetBuffer( p_vout->p_sys->p_display, i_index );
- if( p_vout->p_sys->pp_buffer[ i_index ] == NULL )
+ if( p_vout->p_sys->p_buffer[ i_index ] == NULL )
{
intf_ErrMsg("error: double buffering is not possible\n");
ggiClose( p_vout->p_sys->p_display );
}
/* Check buffer properties */
- if( ! (p_vout->p_sys->pp_buffer[ i_index ]->type & GGI_DB_SIMPLE_PLB) ||
- (p_vout->p_sys->pp_buffer[ i_index ]->page_size != 0) ||
- (p_vout->p_sys->pp_buffer[ i_index ]->write == NULL ) ||
- (p_vout->p_sys->pp_buffer[ i_index ]->noaccess != 0) ||
- (p_vout->p_sys->pp_buffer[ i_index ]->align != 0) )
+ if( ! (p_vout->p_sys->p_buffer[ i_index ]->type & GGI_DB_SIMPLE_PLB) ||
+ (p_vout->p_sys->p_buffer[ i_index ]->page_size != 0) ||
+ (p_vout->p_sys->p_buffer[ i_index ]->write == NULL ) ||
+ (p_vout->p_sys->p_buffer[ i_index ]->noaccess != 0) ||
+ (p_vout->p_sys->p_buffer[ i_index ]->align != 0) )
{
intf_ErrMsg("error: incorrect video memory type\n");
ggiClose( p_vout->p_sys->p_display );
}
/* Check if buffer needs to be acquired before write */
- if( ggiResourceMustAcquire( p_vout->p_sys->pp_buffer[ i_index ]->resource ) )
+ if( ggiResourceMustAcquire( p_vout->p_sys->p_buffer[ i_index ]->resource ) )
{
p_vout->p_sys->b_must_acquire = 1;
}
/* Set thread information */
p_vout->i_width = mode.visible.x;
p_vout->i_height = mode.visible.y;
- p_vout->i_bytes_per_line = p_vout->p_sys->pp_buffer[ 0 ]->buffer.plb.stride;
+ p_vout->i_bytes_per_line = p_vout->p_sys->p_buffer[ 0 ]->buffer.plb.stride;
switch( mode.graphtype )
{
case GT_15BIT:
#include <string.h>
#ifdef VIDEO_X11
-#include <X11/Xlib.h>
+#include <X11/Xlib.h> /* for video_sys.h in X11 mode */
#endif
#include "common.h"
*******************************************************************************/
/* CLIP_BYTE: return value if between 0 and 255, else return nearest boundary
- * (0 or 255) */
+ * (0 or 255), used to build translations tables */
#define CLIP_BYTE( i_val ) ( (i_val < 0) ? 0 : ((i_val > 255) ? 255 : i_val) )
/* YUV_GRAYSCALE: parametric macro for YUV grayscale transformation.
static void RenderYUV16Picture ( vout_thread_t *p_vout, picture_t *p_pic );
static void RenderYUV32Picture ( vout_thread_t *p_vout, picture_t *p_pic );
static void RenderInfo ( vout_thread_t *p_vout );
+static int RenderIdle ( vout_thread_t *p_vout, int i_level );
/*******************************************************************************
* vout_CreateThread: creates a new video output thread
#ifdef STATS
p_vout->c_loops = 0;
p_vout->c_idle_loops = 0;
- p_vout->c_pictures = 0;
+ p_vout->c_fps_samples = 0;
#endif
/* Create thread and set locks */
char psz_date[MSTRTIME_MAX_SIZE]; /* buffer for date string */
#endif
-#ifdef DEBUG_VIDEO
+#ifdef DEBUG
/* Check if picture status is valid */
if( p_pic->i_status != RESERVED_PICTURE )
{
- intf_DbgMsg("error: picture %d has invalid status %d\n",
- p_pic, p_pic->i_status );
+ intf_DbgMsg("error: picture %d has invalid status %d\n", p_pic, p_pic->i_status );
}
#endif
/* Remove reservation flag */
p_pic->i_status = READY_PICTURE;
-#ifdef STATS
- /* Update stats */
- p_vout->c_pictures++;
-#endif
-
#ifdef DEBUG_VIDEO
/* Send picture informations */
intf_DbgMsg("picture %p: type=%d, %dx%d, date=%s\n", p_pic, p_pic->i_type,
*******************************************************************************/
void vout_DestroyPicture( vout_thread_t *p_vout, picture_t *p_pic )
{
-#ifdef DEBUG_VIDEO
+#ifdef DEBUG
/* Check if picture status is valid */
if( p_pic->i_status != RESERVED_PICTURE )
{
- intf_DbgMsg("error: picture %d has invalid status %d\n",
- p_pic, p_pic->i_status );
+ intf_DbgMsg("error: picture %d has invalid status %d\n", p_pic, p_pic->i_status );
}
#endif
{
vlc_mutex_lock( &p_vout->lock );
p_pic->i_refcount++;
+ vlc_mutex_unlock( &p_vout->lock );
#ifdef DEBUG_VIDEO
intf_DbgMsg("picture %p\n", p_pic);
#endif
-
- vlc_mutex_unlock( &p_vout->lock );
}
/*******************************************************************************
{
p_pic->i_status = DESTROYED_PICTURE;
}
+ vlc_mutex_unlock( &p_vout->lock );
#ifdef DEBUG_VIDEO
intf_DbgMsg("picture %p\n", p_pic);
#endif
-
- vlc_mutex_unlock( &p_vout->lock );
}
/* following functions are local */
*p_vout->pi_status = THREAD_START;
/* Initialize pictures */
- p_vout->i_pictures = 0;
for( i_index = 0; i_index < VOUT_MAX_PICTURES; i_index++)
{
p_vout->p_picture[i_index].i_type = EMPTY_PICTURE;
p_vout->p_picture[i_index].i_status= FREE_PICTURE;
}
-#ifdef STATS
- /* Initialize FPS index - since samples won't be used until a minimum of
- * pictures, they don't need to be initialized */
- p_vout->i_fps_index = 0;
-#endif
-
/* Initialize output method - this function issues its own error messages */
if( vout_SysInit( p_vout ) )
{
p_vout->b_active = 1;
*p_vout->pi_status = THREAD_READY;
intf_DbgMsg("thread ready\n");
- return(0);
+ return( 0 );
}
/*******************************************************************************
{
int i_picture; /* picture index */
int i_err; /* error code */
+ int i_idle_level = 0; /* idle level */
mtime_t current_date; /* current date */
- picture_t * p_pic; /* picture pointer */
mtime_t pic_date = 0; /* picture date */
-
+ mtime_t last_date = 0; /* last picture date */
+ boolean_t b_display; /* display flag */
+ picture_t * p_pic; /* picture pointer */
+
/*
* Initialize thread and free configuration
*/
pic_date = p_pic->date;
}
}
+ current_date = mdate();
/*
* Render picture if any
{
#ifdef STATS
/* Computes FPS rate */
- p_vout->fps_sample[ p_vout->i_fps_index++ ] = pic_date;
- if( p_vout->i_fps_index == VOUT_FPS_SAMPLES )
- {
- p_vout->i_fps_index = 0;
- }
-#endif
- current_date = mdate();
+ p_vout->fps_sample[ p_vout->c_fps_samples++ % VOUT_FPS_SAMPLES ] = pic_date;
+#endif
if( pic_date < current_date )
{
- /* Picture is late: it will be destroyed and the thread will go
- * immediately to next picture */
- if( p_pic->i_refcount )
- {
- p_pic->i_status = DISPLAYED_PICTURE;
- }
- else
- {
- p_pic->i_status = DESTROYED_PICTURE;
- }
-
+ /* Picture is late: it will be destroyed and the thread will sleep and
+ * go to next picture */
+ vlc_mutex_lock( &p_vout->lock );
+ p_pic->i_status = p_pic->i_refcount ? DISPLAYED_PICTURE : DESTROYED_PICTURE;
+ vlc_mutex_unlock( &p_vout->lock );
#ifdef DEBUG_VIDEO
intf_DbgMsg( "warning: late picture %p skipped\n", p_pic );
#endif
- p_pic = NULL;
+ p_pic = NULL;
}
else if( pic_date > current_date + VOUT_DISPLAY_DELAY )
{
/* A picture is ready to be rendered, but its rendering date is
* far from the current one so the thread will perform an empty loop
* as if no picture were found. The picture state is unchanged */
- p_pic = NULL;
+ p_pic = NULL;
}
else
{
/* Picture has not yet been displayed, and has a valid display
- * date : render it, then forget it */
- RenderPicture( p_vout, p_pic );
- if( p_pic->i_refcount )
- {
- p_pic->i_status = DISPLAYED_PICTURE;
- }
- else
- {
- p_pic->i_status = DESTROYED_PICTURE;
- }
-
- /* Print additional informations */
- if( p_vout->b_info )
+ * date : render it, then mark it as displayed */
+ if( p_vout->b_active )
{
- RenderInfo( p_vout );
+ RenderPicture( p_vout, p_pic );
}
+ vlc_mutex_lock( &p_vout->lock );
+ p_pic->i_status = p_pic->i_refcount ? DISPLAYED_PICTURE : DESTROYED_PICTURE;
+ vlc_mutex_unlock( &p_vout->lock );
}
}
p_vout->b_error = 1;
}
else
- {
+ {
if( p_pic )
{
- /* A picture is ready to be displayed : sleep until its display date */
+ /* A picture is ready to be displayed : remove blank screen flag */
+ last_date = pic_date;
+ i_idle_level = 0;
+ b_display = 1;
+
+ /* Render additionnal informations */
+ if( p_vout->b_active && p_vout->b_info )
+ {
+ RenderInfo( p_vout );
+ }
+
+ /* Sleep until its display date */
mwait( pic_date );
-
- if( !i_err )
- {
- vout_SysDisplay( p_vout );
- }
}
else
{
- /* Sleep to wait for new pictures */
- msleep( VOUT_IDLE_SLEEP );
+ /* If last picture was a long time ago, increase idle level, reset
+ * date and render idle screen */
+ if( !i_err && (current_date - last_date > VOUT_IDLE_DELAY) )
+ {
+ last_date = current_date;
+ b_display = p_vout->b_active && RenderIdle( p_vout, i_idle_level++ );
+ }
+ else
+ {
+ b_display = 0;
+ }
+
#ifdef STATS
/* Update counters */
p_vout->c_idle_loops++;
#endif
+
+ /* Sleep to wait for new pictures */
+ msleep( VOUT_IDLE_SLEEP );
}
+
+ /* On awakening, send immediately picture to display */
+ if( b_display && p_vout->b_active )
+ {
+ vout_SysDisplay( p_vout );
+ }
}
#ifdef STATS
static void RenderInfo( vout_thread_t *p_vout )
{
char psz_buffer[256]; /* string buffer */
+#ifdef DEBUG
+ int i_ready_pic = 0; /* ready pictures */
+ int i_reserved_pic = 0; /* reserved pictures */
+ int i_picture; /* picture index */
+#endif
#ifdef STATS
- /* Print FPS rate */
- if( p_vout->c_pictures > VOUT_FPS_SAMPLES )
+ /* Print FPS rate in upper right corner */
+ if( p_vout->c_fps_samples > VOUT_FPS_SAMPLES )
{
sprintf( psz_buffer, "%.2f fps", (double) VOUT_FPS_SAMPLES * 1000000 /
- ( p_vout->fps_sample[ (p_vout->i_fps_index + (VOUT_FPS_SAMPLES - 1)) %
- VOUT_FPS_SAMPLES ] -
- p_vout->fps_sample[ p_vout->i_fps_index ] ) );
+ ( p_vout->fps_sample[ (p_vout->c_fps_samples - 1) % VOUT_FPS_SAMPLES ] -
+ p_vout->fps_sample[ p_vout->c_fps_samples % VOUT_FPS_SAMPLES ] ) );
vout_SysPrint( p_vout, p_vout->i_width, 0, 1, -1, psz_buffer );
}
- /* Print statistics */
- sprintf( psz_buffer, "%ld pictures, %.1f %% idle loops", p_vout->c_pictures,
- (double) p_vout->c_idle_loops * 100 / p_vout->c_loops );
+ /* Print statistics in upper left corner */
+ sprintf( psz_buffer, "%ld frames (%.1f %% idle)", p_vout->c_fps_samples,
+ p_vout->c_loops ?
+ (double ) p_vout->c_idle_loops * 100 / p_vout->c_loops : 100. );
vout_SysPrint( p_vout, 0, 0, -1, -1, psz_buffer );
#endif
#ifdef DEBUG
- /* Print heap size */
- sprintf( psz_buffer, "video heap size: %d (%.1f %%)", p_vout->i_pictures,
- (double) p_vout->i_pictures * 100 / VOUT_MAX_PICTURES );
+ /* Print heap state in lower left corner */
+ for( i_picture = 0; i_picture < VOUT_MAX_PICTURES; i_picture++ )
+ {
+ switch( p_vout->p_picture[i_picture].i_status )
+ {
+ case RESERVED_PICTURE:
+ i_reserved_pic++;
+ break;
+ case READY_PICTURE:
+ i_ready_pic++;
+ break;
+ }
+ }
+ sprintf( psz_buffer, "video heap: %d/%d/%d", i_reserved_pic, i_ready_pic,
+ VOUT_MAX_PICTURES );
vout_SysPrint( p_vout, 0, p_vout->i_height, -1, 1, psz_buffer );
#endif
#ifdef DEBUG_VIDEO
- /* Print rendering statistics */
+ /* Print rendering statistics in lower right corner */
sprintf( psz_buffer, "picture rendering time: %lu us",
(unsigned long) p_vout->picture_render_time );
vout_SysPrint( p_vout, p_vout->i_width, p_vout->i_height, 1, 1, psz_buffer );
#endif
}
+/*******************************************************************************
+ * RenderIdle: render idle picture
+ *******************************************************************************
+ * This function will clear the display or print a logo. Level will vary from 0
+ * to a very high value that noone should never reach. It returns non 0 if
+ * something needs to be displayed and 0 if the previous picture can be kept.
+ *******************************************************************************/
+static int RenderIdle( vout_thread_t *p_vout, int i_level )
+{
+ byte_t *pi_pic; /* pointer to picture data */
+
+ /* Get frame pointer and clear display */
+ pi_pic = vout_SysGetPicture( p_vout );
+
+
+ switch( i_level )
+ {
+ case 0: /* level 0: clear screen */
+ memset( pi_pic, 0, p_vout->i_bytes_per_line * p_vout->i_height );
+ break;
+ case 1: /* level 1: "no stream" */
+ memset( pi_pic, 0, p_vout->i_bytes_per_line * p_vout->i_height );
+ vout_SysPrint( p_vout, p_vout->i_width / 2, p_vout->i_height / 2,
+ 0, 0, "no stream" );
+ break;
+ case 50: /* level 50: copyright message */
+ memset( pi_pic, 0, p_vout->i_bytes_per_line * p_vout->i_height );
+ vout_SysPrint( p_vout, p_vout->i_width / 2, p_vout->i_height / 2,
+ 0, 0, COPYRIGHT_MESSAGE );
+ break;
+ default: /* other levels: keep previous picture */
+ return( 0 );
+ break;
+ }
+
+ return( 1 );
+}
/*******************************************************************************
* vout_SysInit: initialize X11 video thread output method
*******************************************************************************
- * This function create the XImages needed by the output thread.
+ * This function create the XImages needed by the output thread. It is called
+ * at the beginning of the thread, but also each time the window is resized.
*******************************************************************************/
int vout_SysInit( vout_thread_t *p_vout )
{
}
}
+ /* Set bytes per line */
+ p_vout->i_bytes_per_line = p_vout->p_sys->p_ximage[0]->bytes_per_line;
+
/* Set buffer index to 0 */
p_vout->p_sys->i_buffer_index = 0;
return( 0 );
/*******************************************************************************
* vout_SysEnd: terminate X11 video thread output method
*******************************************************************************
- * Destroy the X11 XImages created by vout_SysInit.
+ * Destroy the X11 XImages created by vout_SysInit. It is called at the end of
+ * the thread, but also each time the window is resized.
*******************************************************************************/
void vout_SysEnd( vout_thread_t *p_vout )
{
*******************************************************************************/
int vout_SysManage( vout_thread_t *p_vout )
{
- //??
+ if( (p_vout->i_width != p_vout->i_new_width) ||
+ (p_vout->i_height != p_vout->i_new_height) )
+ {
+ /* Resize window */
+ XResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->window,
+ p_vout->i_new_width, p_vout->i_new_height );
+
+ /* Destroy then recreate XImages to change their size */
+ vout_SysEnd( p_vout );
+ p_vout->i_width = p_vout->i_new_width;
+ p_vout->i_height = p_vout->i_new_height;
+ // ?? bpl
+ vout_SysInit( p_vout );
+
+ /* Cancel current display */
+ return( 1 );
+ }
+
return 0;
-
- // ?? if resized: end/init again, return >0
}
/*******************************************************************************
break;
}
- /* Create a window and set line length */
+ /* Create a window */
if( X11CreateWindow( p_vout ) )
{
intf_ErrMsg("error: can't open a window\n");
XCloseDisplay( p_vout->p_sys->p_display );
return( 1 );
}
- p_vout->i_bytes_per_line = p_vout->i_width * p_vout->i_bytes_per_pixel;
+
+ /* Store additionnal vout informations */
+ p_vout->i_new_width = p_vout->i_width;
+ p_vout->i_new_height = p_vout->i_height;
/* Get font information */
if( X11GetFont( p_vout ) )
/*******************************************************************************
* X11CreateImage: create an XImage
+ *******************************************************************************
+ * Create a simple XImage used as a buffer.
*******************************************************************************/
static int X11CreateImage( vout_thread_t *p_vout, XImage **pp_ximage )
{
int i_quantum; /* XImage quantum (see below) */
/* Allocate memory for image */
+ p_vout->i_bytes_per_line = p_vout->i_width * p_vout->i_bytes_per_pixel;
pb_data = (byte_t *) malloc( p_vout->i_bytes_per_line * p_vout->i_height );
if( !pb_data ) /* error */
{