# Configuration
################################################################################
+# Environment
#CC = gcc
#SHELL = /bin/sh
+# Video output settings
+VIDEO=X11
+#VIDEO=DGA
+#VIDEO=FB
+#VIDEO=BEOS
+
+# Target architecture and optimization
+#ARCH=
+ARCH=MMX
+#ARCH=PPC
+
+#----------------- do not change anything below this line ----------------------
+
+################################################################################
+# Configuration pre-processing
+################################################################################
+
+# DEFINE will contain all the constants definitions decided in Makefile
+DEFINE = -DVIDEO_$(VIDEO)
+
+# video is a lowercase version of VIDEO used for filenames
+video = $(shell echo $(VIDEO) | tr 'A-Z' 'a-z')
+
################################################################################
-# Settings and other variables
+# Tunning and other variables
################################################################################
+#
+# Transformation for video decompression (Fourier or cosine)
+#
+TRANSFORM=vdec_idct
+#TRANSFORM=vdec_idft
+
#
# C headers directories
#
INCLUDE += -Iinclude
+
+ifeq ($(VIDEO),X11)
INCLUDE += -I/usr/X11R6/include/X11
+endif
#
# Libraries
#
+LIB += -lpthread
+
+ifeq ($(VIDEO),X11)
LIB += -L/usr/X11R6/lib
LIB += -lX11
LIB += -lXext
-LIB += -lpthread
LIB += -lXpm
+endif
+
+# System dependant libraries
+#??LIB += -lXxf86dga
#
# C compiler flags: compilation
#
-CCFLAGS += $(INCLUDE)
+CCFLAGS += $(DEFINE) $(INCLUDE)
CCFLAGS += -Wall
CCFLAGS += -D_REENTRANT
CCFLAGS += -D_GNU_SOURCE
CCFLAGS += -ffast-math -funroll-loops -fargument-noalias-global
CCFLAGS += -fomit-frame-pointer
#CCFLAGS += -fomit-frame-pointer -s
-#LCFLAGS += -s
-# Platform-specific optimizations
-# Optimizations for x86 familiy :
+# Optimizations for x86 familiy, without MMX
+ifeq ($(ARCH),)
CCFLAGS += -malign-double
CCFLAGS += -march=pentiumpro
#CCFLAGS += -march=pentium
+endif
-# MMX support :
-CFLAGS += -DHAVE_MMX
-ASM_OBJ = video_decoder_ref/idctmmx.o \
- video_decoder_ref/yuv12-rgb16.o
+# Optimization for x86 with MMX support
+ifeq ($(ARCH),MMX)
+CCFLAGS += -malign-double
+CCFLAGS += -march=pentiumpro
+endif
-#Optimizations for PowerPC :
-#CCFLAGS += -mcpu=604e -mmultiple -mhard-float -mstring
+# Optimizations for PowerPC
+ifeq ($(ARCH),PPC)
+CCFLAGS += -mcpu=604e -mmultiple -mhard-float -mstring
+endif
#
# C compiler flags: dependancies
#
LCFLAGS += $(LIB)
LCFLAGS += -Wall
-
-#
-# C compiler flags: functions flow
-#
-FCFLAGS += $(INCLUDE)
-FCFLAGS += -A
-FCFLAGS += -P
-FCFLAGS += -v
-FCFLAGS += -a
-FCFLAGS += -X errno.h
-FCFLAGS += -X fcntl.h
-FCFLAGS += -X signal.h
-FCFLAGS += -X stdio.h
-FCFLAGS += -X stdlib.h
-FCFLAGS += -X string.h
-FCFLAGS += -X unistd.h
-FCFLAGS += -X sys/ioctl.h
-FCFLAGS += -X sys/stat.h
-FCFLAGS += -X X11/Xlib.h
-FFILTER = grep -v "intf_.*Msg.*\.\.\."
+#LCFLAGS += -s
#
# C compiler flags: common flags
#
-# CFLAGS
+
+# Optimizations for x86 with MMX support
+ifeq ($(ARCH),MMX)
+CFLAGS += -DHAVE_MMX
+endif
#
# Additionnal debugging flags
# Note that electric fence and accurate profiling are quite uncompatible.
#CCFLAGS += -g
#CCFLAGS += -pg
-#LCFLAGS += -g
+#LCFLAGS += -g
#LCFLAGS += -pg
#LIB += -ldmalloc
#LIB += -lefence
interface/intf_cmd.o \
interface/intf_ctrl.o \
interface/control.o \
- interface/xconsole.o
+ interface/intf_console.o \
+ interface/intf_$(video).o
input_obj = input/input_vlan.o \
input/input_file.o \
audio_output_obj = audio_output/audio_output.o \
audio_output/audio_dsp.o
-#video_output_obj = video_output/video_output.o \
-# video_output/video_x11.o \
-# video_output/video_graphics.o
+video_output_obj = video_output/video_output.o \
+ video_output/video_$(video).o
audio_decoder_obj = audio_decoder/audio_decoder.o \
audio_decoder/audio_math.o
-#generic_decoder_obj = generic_decoder/generic_decoder.o
+#??generic_decoder_obj = generic_decoder/generic_decoder.o
+# remeber to add it to OBJ
video_decoder_obj = video_decoder_ref/video_decoder.o \
video_decoder_ref/display.o \
video_decoder_ref/motion.o \
video_decoder_ref/mpeg2dec.o \
video_decoder_ref/recon.o \
- video_decoder_ref/spatscal.o
+ video_decoder_ref/spatscal.o
+# video_decoder_ref/$(TRANSFORM).o
#video_parser_obj = video_parser/video_parser.o \
# video_parser/vpar_headers.o \
misc/rsc_files.o \
misc/netutils.o
+
+ifeq ($(ARCH),MMX)
+ASM_OBJ = video_decoder_ref/idctmmx.o \
+ video_decoder_ref/yuv12-rgb16.o
+endif
+
C_OBJ = $(interface_obj) \
$(input_obj) \
$(audio_output_obj) \
$(video_parser_obj) \
$(video_decoder_obj) \
$(vlan_obj) \
- $(misc_obj) \
+ $(misc_obj)
#
# Other lists of files
distclean: clean
rm -f **/*.o **/*~ *.log
- rm -f vlc gmon.out core Documentation/cflow
+ rm -f vlc gmon.out core
rm -rf dep
FORCE:
vlc: $(C_OBJ) $(ASM_OBJ)
$(CC) $(LCFLAGS) $(CFLAGS) -o $@ $(C_OBJ) $(ASM_OBJ)
-Documentation/cflow: $(sources)
- cflow $(FCFLAGS) $(CFLAGS) $(sources) | $(FFILTER) > $@
-
#
# Generic rules (see below)
#
$(C_OBJ): %.o: %.c
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
$(ASM_OBJ): %.o: %.S
- $(CC) -c -o $@ $<
+ $(CC) $(CFLAGS) -c -o $@ $<
################################################################################
# Note on generic rules and dependancies
/******************************************************************************
* Prototypes
******************************************************************************/
-int aout_Open ( aout_thread_t *p_aout );
-int aout_SpawnThread ( aout_thread_t *p_aout );
-void aout_CancelThread ( aout_thread_t *p_aout );
-void aout_Close ( aout_thread_t *p_aout );
+aout_thread_t * aout_CreateThread ( int *pi_status );
+void aout_DestroyThread ( aout_thread_t *p_aout, int *pi_status );
+
aout_fifo_t * aout_CreateFifo ( aout_thread_t *p_aout, aout_fifo_t *p_fifo );
void aout_DestroyFifo ( aout_fifo_t *p_fifo );
*******************************************************************************/
/*******************************************************************************
- * Types definitions
+ * Basic types definitions
*******************************************************************************/
/* Basic types definitions */
/* Counter for statistics and profiling */
typedef unsigned long count_t;
+/*******************************************************************************
+ * Classes declaration
+ *******************************************************************************/
+
+/* Interface */
+struct intf_thread_s;
+struct intf_sys_s;
+struct intf_console_s;
+struct intf_msg_s;
+
+typedef struct intf_thread_s * p_intf_thread_t;
+typedef struct intf_sys_s * p_intf_sys_t;
+typedef struct intf_console_s * p_intf_console_t;
+typedef struct intf_msg_s * p_intf_msg_t;
+
+/* Input */
+struct input_thread_s;
+struct input_vlan_method_s;
+struct input_cfg_s;
+
+typedef struct input_thread_s * p_input_thread_t;
+typedef struct input_vlan_method_s * p_input_vlan_method_t;
+typedef struct input_cfg_s * p_input_cfg_t;
+
+/* Audio */
+struct aout_thread_s;
+
+typedef struct aout_thread_s * p_aout_thread_t;
+
+/* Video */
+struct vout_thread_s;
+struct vout_sys_s;
+struct vdec_thread_s;
+struct vpar_thread_s;
+struct video_parser_s;
+
+typedef struct vout_thread_s * p_vout_thread_t;
+typedef struct vout_sys_s * p_vout_sys_t;
+typedef struct vdec_thread_s * p_vdec_thread_t;
+typedef struct vpar_thread_s * p_vpar_thread_t;
+typedef struct video_parser_s * p_video_parser_t;
+
/*******************************************************************************
* Macros and inline functions
*******************************************************************************/
* (c)1999 VideoLAN
*******************************************************************************
* Defines all compilation-time configuration constants and size limits
- *******************************************************************************
- * required headers:
- * none
*******************************************************************************/
+/* Conventions regarding names of symbols and variables
+ * ----------------------------------------------------
+ *
+ * - Symbols should begin with a prefix indicating in which module they are
+ * used, such as INTF_, VOUT_ or ADEC_.
+ *
+ * - Regarding environment variables, which are used as initialization parameters
+ * for threads :
+ * + 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 version and copyright message */
-#define PROGRAM_VERSION "0.0.x"
+#define PROGRAM_VERSION "DR 2.1"
#define COPYRIGHT_MESSAGE "VideoLAN Client v" PROGRAM_VERSION " (" __DATE__ ") - (c)1999 VideoLAN\n"
/*******************************************************************************
/* 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 */
#define DEBUG_INTF
#define DEBUG_INPUT
/* 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
-/* ?? VOUT_DEBUG and co have changed ! */
/*******************************************************************************
* Common settings
#define AUTO_SPAWN
/* Startup script */
-#define INIT_SCRIPT "vlc.init"
+#define INTF_INIT_SCRIPT_VAR "vlc_init"
+#define INTF_INIT_SCRIPT_DEFAULT "vlc.init"
/* ?? */
#define THREAD_SLEEP 100000
#define VLAN_DEFAULT_SERVER_PORT 6010
/*******************************************************************************
- * Audio output thread configuration
+ * Audio configuration
*******************************************************************************/
+/* Environment variable used to store dsp device name, and default value */
+#define AOUT_DSP_VAR "vlc_dsp"
+#define AOUT_DSP_DEFAULT "/dev/dsp"
+
+/* Environment variable for stereo, and default value */
+#define AOUT_STEREO_VAR "vlc_stereo"
+#define AOUT_STEREO_DEFAULT 1
+
+/* Environment variable for output rate, and default value */
+#define AOUT_RATE_VAR "vlc_audio_rate"
+#define AOUT_RATE_DEFAULT 44100
+
/*******************************************************************************
- * Video output thread configuration
+ * Video configuration
*******************************************************************************/
/*
*/
/* Title of the window */
-#define VOUT_TITLE "VideoLAN Client: output"
+#define VOUT_TITLE "VideoLAN Client"
-/* Default use of XShm extension */
-#define VOUT_SHM_EXT 1
-
-/* Dimensions for display window */
+/* Default dimensions for display window - these dimensions are the standard
+ * width and height for broadcasted MPEG-2 */
#define VOUT_WIDTH 544
#define VOUT_HEIGHT 576
-/* Default heap size */
-#define VOUT_HEAP_SIZE 100
-
-/*
- * Limitations
- */
-
-/* Maximum number of video output threads - this value is used exclusively by
- * interface, and is in fact an interface limitation */
-#define VOUT_MAX_THREADS 10
-
-/* Maximum number of video streams per video output thread */
-#define VOUT_MAX_STREAMS 10
-
-/* Maximum number of pictures which can be rendered in one loop, plus one */
+/* Default video heap size - remember that a decompressed picture is big
+ * (~1 Mbyte) before using huge values */
#define VOUT_MAX_PICTURES 10
/*
- * Other settings
+ * Time settings
*/
/* Time during which the thread will sleep if it has nothing to
/* ?? this constant will probably evolve to a calculated value */
#define VOUT_DISPLAY_DELAY 150000
-/* Maximum lap of time during which images are rendered in the same
- * time. It should be greater than the maximum time between two succesive
- * images to avoid useless renderings and calls to the display driver,
- * but not to high to avoid desynchronization */
-/* ?? this constant will probably evolve to a calculated value */
-#define VOUT_DISPLAY_TOLERANCE 150000
+/*
+ * Environment settings
+ */
+
+/* Allow use of X11 XShm (shared memory) extension if possible */
+#define VOUT_XSHM 1
/*******************************************************************************
* Video parser configuration
/* Maximal size of a command line in a script */
#define INTF_MAX_CMD_SIZE 240
-
/*
- * Messages functions
+ * X11 interface properties
*/
-
-/* Maximal size of the message queue - in case of overflow, all messages in the
- * queue are printed by the calling thread */
-#define INTF_MSG_QSIZE 32
-
-/* Define to enable messages queues - disabling messages queue can be usefull
- * when debugging, since it allows messages which would not otherwise be printed,
- * due to a crash, to be printed anyway */
-/*#define INTF_MSG_QUEUE*/
-
-/* 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: "
-
-/* Filename to log message
- * Note that messages are only logged when debugging */
-//#define INTF_MSG_LOGFILE "vlc.log"
+#define INTF_APP_CLASS "vlc"
+#define INTF_APP_NAME "vlc"
+//??#define
/*
* X11 console properties
#define INTF_XCONSOLE_FONT "-*-helvetica-medium-r-normal-*-18-*-*-*-*-*-iso8859-1"
/* Number of memorized lines in X11 console window text zone */
-#define INTF_XCONSOLE_MAX_LINES 100
+#define INTF_CONSOLE_MAX_TEXT 100
/* Maximal number of commands which can be saved in history list */
-#define INTF_XCONSOLE_HISTORY_SIZE 20
+#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
+ *******************************************************************************/
+
+/* Maximal size of the message queue - in case of overflow, all messages in the
+ * queue are printed by the calling thread */
+#define INTF_MSG_QSIZE 32
+
+/* Define to enable messages queues - disabling messages queue can be usefull
+ * when debugging, since it allows messages which would not otherwise be printed,
+ * due to a crash, to be printed anyway */
+//#define INTF_MSG_QUEUE
+
+/* 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: "
/*******************************************************************************
* Network and VLAN management
/*******************************************************************************
* Prototypes
*******************************************************************************/
-int intf_CreateVoutThread ( intf_thread_t *p_intf, char *psz_title,
- int i_width, int i_height );
-void intf_DestroyVoutThread ( intf_thread_t *p_intf, int i_thread );
-int intf_CreateInputThread ( intf_thread_t *p_intf, input_cfg_t* p_cfg );
-void intf_DestroyInputThread ( intf_thread_t *p_intf, int i_thread );
-
int intf_SelectAudioStream ( intf_thread_t *p_intf, int i_input, int i_id );
void intf_DeselectAudioStream( intf_thread_t *p_intf, int i_input, int i_id );
int intf_SelectVideoStream ( intf_thread_t *p_intf, int i_input,
size_t );
typedef void (*f_clean_t)( struct input_thread_struct * );
-typedef struct input_thread_struct
+typedef struct input_thread_s
{
/* Thread properties and locks */
boolean_t b_die; /* 'die' flag */
* properties, asking the called function to use default settings for
* the other ones.
******************************************************************************/
-typedef struct input_cfg_struct
+typedef struct input_cfg_s
{
u64 i_properties;
#define VLAN_ID_VLAN( vlan_id ) ( (vlan_id) & 0xff )
#define VLAN_ID( iface, vlan ) ( ((iface) << 8) | (vlan) )
-/*******************************************************************************
- * input_vlan_server_t: vlan server
- *******************************************************************************
- * This structure describes a vlan server.
- *******************************************************************************/
-typedef struct
-{
- struct sockaddr_in sa_in; /* server address */
- int i_socket; /* socket descriptor */
-
- /* Login informations */
- char * psz_login; /* server login */
- char * psz_passwd; /* server password */
-} input_vlan_server_t;
-
-/*******************************************************************************
- * input_vlan_iface_t: vlan-capable network interface
- *******************************************************************************
- * This structure describes the abilities of a network interface capable of
- * vlan management. Note that an interface could have several IP adresses, but
- * since only the MAC address is used to change vlan, only one needs to be
- * retrieved.
- * ?? it could be interesting to send a port id on vlan request, to know if two
- * interfaces are dependant regarding vlan changes.
- *******************************************************************************/
-typedef struct
-{
- char * psz_name; /* interface name */
- struct sockaddr_in sa_in; /* interface IP */
- char psz_mac[20]; /* interface MAC */
-
- /* Hardware properties */
- int i_master; /* master interface index */
- int i_switch; /* switch number */
- int i_port; /* port number */
- int i_sharers; /* number of MACs on this port */
-
- /* Vlan properties - these are only used if i_master is negative */
- int i_refcount; /* locks counter */
- int i_vlan; /* current vlan */
- int i_default_vlan; /* default vlan */
-} input_vlan_iface_t;
-
-/*******************************************************************************
- * vlan_method_data_t
- *******************************************************************************
- * Store global vlan library data.
- *******************************************************************************/
-typedef struct
-{
- vlc_mutex_t lock; /* library lock */
-
- /* Server */
- input_vlan_server_t server; /* vlan server */
-
- /* Network interfaces */
- int i_ifaces; /* number of vlan-compliant interfaces */
- input_vlan_iface_t * p_iface; /* interfaces */
-} input_vlan_method_t;
-
/*******************************************************************************
* Prototypes
*******************************************************************************/
-int input_VlanMethodInit ( input_vlan_method_t *p_method,
- char *psz_server, int i_port);
-void input_VlanMethodFree ( input_vlan_method_t *p_method );
+int input_VlanCreate ( void );
+void input_VlanDestroy ( void );
int input_VlanId ( char *psz_iface, int i_vlan );
int input_VlanJoin ( int i_vlan_id );
* This structe describes all interface-specific data of the main (interface)
* thread.
******************************************************************************/
-typedef struct
+typedef struct intf_thread_s
{
boolean_t b_die; /* `die' flag */
- /* Threads control */
- input_thread_t * pp_input[INPUT_MAX_THREADS]; /* input threads */
- vout_thread_t * pp_vout[VOUT_MAX_THREADS]; /* vout threads */
- aout_thread_t * p_aout; /* aout thread */
-
- int i_input; /* default input thread */
- int i_vout; /* default output thread */
-
/* Specific interfaces */
- xconsole_t xconsole; /* X11 console */
+ p_intf_console_t p_console; /* console */
+ p_intf_sys_t p_sys; /* system interface */
+
+ /* Main threads - NULL if not active */
+ p_vout_thread_t p_vout;
+ p_input_thread_t p_input;
} intf_thread_t;
/******************************************************************************
* Prototypes
******************************************************************************/
-int intf_Run( intf_thread_t * p_intf );
+intf_thread_t * intf_Create ( void );
+void intf_Run ( intf_thread_t * p_intf );
+void intf_Destroy ( intf_thread_t * p_intf );
+
+int intf_SelectInput ( intf_thread_t * p_intf, p_input_cfg_t p_cfg );
+
--- /dev/null
+/*******************************************************************************
+ * intf_console.h: generic console methods for interface
+ * (c)1998 VideoLAN
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ *******************************************************************************/
+p_intf_console_t intf_ConsoleCreate ( void );
+void intf_ConsoleDestroy ( p_intf_console_t p_console );
+
+void intf_ConsoleClear ( p_intf_console_t p_console );
+void intf_ConsolePrint ( p_intf_console_t p_console, char *psz_str );
+void intf_ConsoleExec ( p_intf_console_t p_console, char *psz_str );
+
+
* (c)1999 VideoLAN
*******************************************************************************
* This library provides basic functions for threads to interact with user
- * interface, such as message output. If INTF_MSG_QUEUE is defined (which is the
- * defaul), messages are not printed directly by threads, to bypass console
- * limitations and slow printf() calls, but sent to a queue and printed later by
- * interface thread.
- * If INTF_MSG_QUEUE is not defined, output is directly performed on stderr.
- *******************************************************************************
- * required headers:
- * "config.h"
- * "mtime.h"
- * "vlc_thread.h"
- *******************************************************************************/
-
-/*******************************************************************************
- * interface_message_t
- *******************************************************************************
- * Store a single message. Messages have a maximal size of INTF_MSG_MSGSIZE.
- * If DEBUG is defined, messages have a date field and debug messages are
- * printed with a date to allow more precise profiling.
- *******************************************************************************/
-typedef struct
-{
- int i_type; /* message type, see below */
- char * psz_msg; /* the message itself */
-
-#ifdef DEBUG
- /* Debugging informations - in DEBUG mode, all messages are dated and debug
- * messages have calling location informations printed */
- mtime_t date; /* date of the message (all messages) */
- char * psz_file; /* file in which the function was called */
- char * psz_function; /* function from which the function was called */
- int i_line; /* line at which the function was called */
-#endif
-} interface_msg_message_t;
-
-/* Message types */
-#define INTF_MSG_STD 0 /* standard message */
-#define INTF_MSG_ERR 1 /* error message */
-#define INTF_MSG_INTF 2 /* interface message */
-#define INTF_MSG_DBG 3 /* debug message */
-
-/*******************************************************************************
- * interface_msg_t
- *******************************************************************************
- * Store all data requiered by messages interfaces. It has a singe instance in
- * program_data.
+ * interface, such as message output. See config.h for output configuration.
*******************************************************************************/
-typedef struct
-{
-#ifdef INTF_MSG_QUEUE
- /* Message queue */
- vlc_mutex_t lock; /* message queue lock */
- int i_count; /* number of messages stored */
- interface_msg_message_t msg[INTF_MSG_QSIZE]; /* message queue */
-#endif
-
-#ifdef DEBUG_LOG
- /* Log file */
- FILE * p_log_file; /* log file */
-#endif
-
-#ifndef INTF_MSG_QUEUE
-#ifndef DEBUG_LOG
- /* If neither messages queue, neither log file is used, then the structure
- * is empty. However, empty structures are not allowed in C. Therefore, a
- * dummy integer is used to fill it. */
- int i_dummy; /* unused filler */
-#endif
-#endif
-} interface_msg_t;
/*******************************************************************************
* intf_DbgMsg macros and functions
/*******************************************************************************
* Prototypes
*******************************************************************************/
-int intf_InitMsg ( interface_msg_t *p_intf_msg );
-void intf_TerminateMsg ( interface_msg_t *p_intf_msg );
-
-void intf_Msg ( char *psz_format, ... );
-void intf_ErrMsg ( char *psz_format, ... );
-void intf_IntfMsg ( char *psz_format, ... );
-
-void intf_MsgImm ( char *psz_format, ... );
-void intf_ErrMsgImm ( char *psz_format, ... );
+p_intf_msg_t intf_MsgCreate ( void );
+void intf_MsgDestroy ( void );
+void intf_Msg ( char *psz_format, ... );
+void intf_ErrMsg ( char *psz_format, ... );
+void intf_IntfMsg ( char *psz_format, ... );
+void intf_MsgImm ( char *psz_format, ... );
+void intf_ErrMsgImm ( char *psz_format, ... );
--- /dev/null
+/*******************************************************************************
+ * intf_sys.h: system dependant interface API
+ * (c)1999 VideoLAN
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ *******************************************************************************/
+int intf_SysCreate ( p_intf_thread_t p_intf );
+void intf_SysDestroy( p_intf_thread_t p_intf );
+void intf_SysManage ( p_intf_thread_t p_intf );
--- /dev/null
+/*******************************************************************************
+ * main.h: access to all program variables
+ * (c)1999 VideoLAN
+ *******************************************************************************
+ * Declaration and extern access to global program object.
+ *******************************************************************************/
+
+/*******************************************************************************
+ * main_t, p_main (global variable)
+ *******************************************************************************
+ * This structure has an unique instance, declared in main and pointed by the
+ * only global variable of the program. It should allow access to any variable
+ * of the program, for user-interface purposes or more easier call of interface
+ * and common functions (example: the intf_*Msg functions). Please avoid using
+ * it when you can access the members you need in an other way. In fact, it
+ * should only be used by interface thread.
+ *******************************************************************************/
+typedef struct
+{
+ /* Global properties */
+ int i_argc; /* command line arguments count */
+ char ** ppsz_argv; /* command line arguments */
+ char ** ppsz_env; /* environment variables */
+
+ /* Generic settings */
+ boolean_t b_audio; /* is audio output allowed ? */
+ boolean_t b_video; /* is video output allowed ? */
+ boolean_t b_vlans; /* are vlans supported ? */
+
+ /* Unique threads */
+ p_aout_thread_t p_aout; /* audio output thread */
+ p_intf_thread_t p_intf; /* main interface thread */
+
+ /* Shared data - these structures are accessed directly from p_main by
+ * several modules */
+ p_intf_msg_t p_msg; /* messages interface data */
+ p_input_vlan_method_t p_input_vlan; /* vlan input method */
+} main_t;
+
+extern main_t *p_main;
+
+/*******************************************************************************
+ * Prototypes - these methods are used to get default values for some threads
+ * and modules.
+ *******************************************************************************/
+int main_GetIntVariable( char *psz_name, int i_default );
+char * main_GetPszVariable( char *psz_name, char *psz_default );
+
+++ /dev/null
-/*******************************************************************************
- * pgm_data.h: access to all program variables
- * (c)1999 VideoLAN
- *******************************************************************************
- * This header provides structures to access to all program variables. It should
- * only be used by interface.
- *******************************************************************************
- * Required headers:
- * <netinet/in.h>
- * <sys/soundcard.h>
- * <sys/uio.h>
- * <X11/Xlib.h>
- * <X11/extensions/XShm.h>
- * "config.h"
- * "common.h"
- * "mtime.h"
- * "vlc_thread.h"
- * "input.h"
- * "input_vlan.h"
- * "audio_output.h"
- * "video.h"
- * "video_output.h"
- * "xconsole.h"
- * "interface.h"
- * "intf_msg.h"
- *******************************************************************************/
-
-/*******************************************************************************
- * main_config_t
- *******************************************************************************
- * Store the main configuration (non thread-dependant configuration), such as
- * parameters read from command line and name of configuration file
- *******************************************************************************/
-typedef struct
-{
- boolean_t b_audio; /* is audio output allowed ? */
- boolean_t b_video; /* is video output allowed ? */
- boolean_t b_vlans; /* are vlans supported ? */
-
- /* Vlan input method configuration */
- char * psz_input_vlan_server; /* vlan server */
- int i_input_vlan_server_port; /* vlan server port */
-} main_config_t;
-
-/*******************************************************************************
- * program_data_t, p_program_data (global variable)
- *******************************************************************************
- * This structure has an unique instance, declared in main and pointed by the
- * only global variable of the program. It should allow access to any variable
- * of the program, for user-interface purposes or more easier call of interface
- * and common functions (example: the intf_*Msg functions). Please avoid using
- * it when you can access the members you need in an other way. In fact, it
- * should only be used by interface thread.
- *******************************************************************************/
-typedef struct
-{
- /* Global properties */
- int i_argc; /* command line arguments count */
- char ** ppsz_argv; /* command line arguments */
- char ** ppsz_env; /* environment variables */
-
- /* Configurations */
- main_config_t cfg; /* general configuration */
- video_cfg_t vout_cfg; /* video output configuration */
-
- /* Threads */
- aout_thread_t aout_thread; /* audio output thread */
- intf_thread_t intf_thread; /* interface thread */
-
- /* Shared data - these structures are accessed directly from p_program_data
- * by several libraries */
- interface_msg_t intf_msg; /* messages interface data */
- input_vlan_method_t input_vlan_method; /* vlan input method */
-} program_data_t;
-
-extern program_data_t *p_program_data;
-
+++ /dev/null
-/*******************************************************************************
- * thread.h: threads status constants
- * (c)1999 VideoLAN
- *******************************************************************************
- * These constants are used by all threads in *_CreateThread() and
- * *_DestroyThreads() functions. Since those calls are non-blocking, an integer
- * value is used as a shared flag to represent the status of the thread.
- *******************************************************************************
- * Requires:
- * none
- *******************************************************************************/
-
-/* Void status - this value can be used to be sure, in an array of recorded
- * threads, that no operation is currently in progress on the concerned thread */
-#define THREAD_NOP 0 /* nothing happened */
-
-/* Creation status */
-#define THREAD_CREATE 10 /* thread is initializing */
-#define THREAD_START 11 /* thread has forked */
-#define THREAD_READY 19 /* thread is ready */
-
-/* Destructions status */
-#define THREAD_DESTROY 20 /* destruction order has been sent */
-#define THREAD_END 21 /* destruction order has been received */
-#define THREAD_OVER 29 /* thread does not exist any more */
-
-/* Error status */
-#define THREAD_ERROR 30 /* an error occured */
-#define THREAD_FATAL 31 /* an fatal error occured - program must end */
-
-
-
-
* "mtime.h"
*******************************************************************************/
-/*******************************************************************************
- * pixel_t: universal pixel value descriptor
- *******************************************************************************
- * This type and associated macros and functions are provided as an universal
- * way of storing colors/pixels parameters. For pixels, it represents the
- * actual value of the pixel. For RGB values, it is a 24 bits RGB encoded
- * value. For masks, it is 0 or 1...
- *******************************************************************************/
-typedef u32 pixel_t;
-
-#define RGBVALUE2RED( value ) ( (value) & 0x0000ff )
-#define RGBVALUE2GREEN( value ) ( ((value) >> 8) & 0x0000ff )
-#define RGBVALUE2BLUE( value ) ( ((value) >> 16) & 0x0000ff )
-
/*******************************************************************************
* picture_t: video picture
*******************************************************************************
* Any picture destined to be displayed by a video output thread should be
* stored in this structure from it's creation to it's effective display.
- * Two forms of pictures exists: independant pictures, which can be manipulated
- * freely, although usage of graphic library is recommanded, and heap pictures.
- * Extreme care should be taken when manipulating heap pictures, since any error
- * could cause a segmentation fault in the video output thread. The rule is:
- * once a picture is in the video heap, only it's data can be written. All other
- * fields should only be read or modified using interface functions.
- * Note that for all pictures, some properties should never be modified, except
- * by the video output thread itself, once the picture has been created !
+ * Picture type and flags should only be modified by the output thread. Note
+ * that an empty picture MUST have its flags set to 0.
*******************************************************************************/
typedef struct
{
/* Type and flags - should NOT be modified except by the vout thread */
int i_type; /* picture type */
- int i_flags; /* picture flags */
+ int i_status; /* picture flags */
/* Picture properties - those properties are fixed at initialization and
- * should NOT be modified */
+ * should NOT be modified. Note that for YUV pictures, i_bytes_per_line is
+ * the number of bytes for ONE of the Y, U or V pictures, and therefore the
+ * number of bytes in the picture is 3 * i_height * i_bytes_per_line */
int i_width; /* picture width */
int i_height; /* picture height */
- int i_bpp; /* padded bits per pixel */
int i_bytes_per_line; /* total number of bytes per line */
- /* Picture properties - those properties can be modified is the picture is
- * independant, or in a heap but permanent or reserved */
- int i_x; /* x position offset in output window */
- int i_y; /* y position offset in output window */
- int i_h_align; /* horizontal alignment */
- int i_v_align; /* vertical alignment */
- int i_h_ratio; /* horizontal display ratio */
- int i_v_ratio; /* vertical display ratio */
- int i_level; /* overlay hierarchical level */
-
/* Link reference counter - it can be modified using vout_Link and
* vout_Unlink functions, or directly if the picture is independant */
int i_refcount; /* link reference counter */
/* Video properties - those properties should not be modified once
* the picture is in a heap, but can be freely modified if it is
* independant */
- int i_stream; /* video stream id */
mtime_t date; /* display date */
- mtime_t duration; /* duration for overlay pictures */
- /* Picture data - data can always be freely modified, although special care
- * should be taken for permanent pictures to avoid flickering - p_data
- * itself (the pointer) should NEVER be modified */
- pixel_t pixel; /* pixel value, for mask pictures */
+ /* Picture data - data can always be freely modified. p_data itself
+ * (the pointer) should NEVER be modified. In YUV format, the p_y, p_u and
+ * p_v data pointers refers to different areas of p_data, and should not
+ * be freed */
byte_t * p_data; /* picture data */
+ byte_t * p_y; /* pointer to beginning of Y image in p_data */
+ byte_t * p_u; /* pointer to beginning of U image in p_data */
+ byte_t * p_v; /* pointer to beginning of V image in p_data */
} picture_t;
-/* Pictures types */
-#define EMPTY_PICTURE 0 /* picture is waiting to be used */
-#define RGB_BLANK_PICTURE 10 /* blank picture (rgb color, no data) */
-#define PIXEL_BLANK_PICTURE 11 /* blank picture (pixel color, no data) */
-#define RGB_PICTURE 20 /* picture is 24 bits rgb encoded */
-#define PIXEL_PICTURE 30 /* picture is pixel encoded */
-#define RGB_MASK_PICTURE 40 /* picture is a 1 bpp rgb mask */
-#define PIXEL_MASK_PICTURE 41 /* picture is a 1 bpp pixel mask */
-/* ?? */
-#define YUV_444_PICTURE 100 /* chroma 444 YUV picture */
-#define YUV_422_PICTURE 101 /* chroma 422 YUV picture */
-#define YUV_420_PICTURE 102 /* chroma 420 YUV picture */
-
-/* Pictures properties (flags) */
-#define RESERVED_PICTURE (1 << 0) /* picture is not ready but reserved */
-#define PERMANENT_PICTURE (1 << 1) /* picture is permanent */
-#define DISPLAYED_PICTURE (1 << 2) /* picture has been displayed */
-#define OWNER_PICTURE (1 << 3) /* picture owns its data */
-#define DISPLAY_PICTURE (1 << 4) /* picture will be displayed */
-#define DESTROY_PICTURE (1 << 5) /* picture will be destroyed */
-#define TRANSPARENT_PICTURE (1 << 8) /* picture is transparent */
-#define OVERLAY_PICTURE (1 << 9) /* picture overlays another one */
+/* Pictures types */
+#define EMPTY_PICTURE 0 /* picture slot is empty and available */
+#define YUV_422_PICTURE 100 /* 4:2:2 YUV picture */
+#define YUV_442_PICTURE 101 /* 4:4:2 YUV picture */
+#define YUV_444_PICTURE 102 /* 4:4:4 YUV picture */
-/* Alignments - this field describe how the position of the picture will
- * be calculated */
-#define ALIGN_LEFT -1 /* left-aligned */
-#define ALIGN_TOP -1 /* up-aligned */
-#define ALIGN_ENTER 0 /* centered */
-#define ALIGN_RIGHT 1 /* right-aligned */
-#define ALIGN_BOTTOM 1 /* bottom-aligned */
-#define ALIGN_H_DEFAULT ALIGN_LEFT /* default horizontal alignment */
-#define ALIGN_V_DEFAULT ALIGN_TOP /* default vertical alignment */
+/* Pictures status */
+#define FREE_PICTURE 0 /* picture is free and not allocated */
+#define RESERVED_PICTURE 1 /* picture is allocated and reserved */
+#define READY_PICTURE 2 /* picture is ready for display */
+#define DISPLAYED_PICTURE 3 /* picture has been displayed but is linked */
+#define DESTROYED_PICTURE 4 /* picture is allocated but no more used */
-/* Display ratios - this field describe how the image will be resized before
- * being displayed */
-#define DISPLAY_RATIO_HALF -1 /* 1:2 half size */
-#define DISPLAY_RATIO_NORMAL 0 /* 1:1 normal size */
-#define DISPLAY_RATIO_DOUBLE 1 /* 2:1 double size */
-/* ?? add other ratios (TRIPLE, THIRD), TV, automatic, ... */
-/*******************************************************************************
- * video_cfg_t: video object configuration structure
- *******************************************************************************
- * This structure is passed as a parameter to many initialization function of
- * the vout and vdec modules. It includes many fields describing potential
- * properties of a new object. The 'i_properties' field allow to set only a
- * subset of the required properties, asking the called function to use default
- * settings for the other ones.
- *******************************************************************************/
-typedef struct video_cfg_s
-{
- u64 i_properties; /* used properties */
- /* Size properties */
- int i_width; /* image or window width */
- int i_height; /* image or window height */
- int i_size; /* heap size */
- /* X11 properties */
- char * psz_display; /* display name */
- char * psz_title; /* window title */
- boolean_t b_shm_ext; /* try to use XShm extension */
- /* Pictures properties */
- int i_type; /* picture type */
- int i_flags; /* picture flags */
- int i_bpp; /* padded bits per pixel */
- int i_x; /* x position offset in output window */
- int i_y; /* y position offset in output window */
- int i_h_align; /* horizontal alignment */
- int i_v_align; /* vertical alignment */
- int i_h_ratio; /* horizontal display ratio */
- int i_v_ratio; /* vertical display ratio */
- int i_level; /* overlay hierarchical level */
- int i_refcount; /* link reference counter */
- int i_stream; /* video stream id */
- mtime_t date; /* picture display date */
- mtime_t duration; /* duration for overlay pictures */
- pixel_t pixel; /* pixel value, for mask pictures */
- byte_t * p_data; /* picture data */
-} video_cfg_t;
-/* Properties flags (see picture_t and other video structures for
- * explanations) */
-#define VIDEO_CFG_WIDTH (1 << 0)
-#define VIDEO_CFG_HEIGHT (1 << 1)
-#define VIDEO_CFG_SIZE (1 << 2)
-#define VIDEO_CFG_DISPLAY (1 << 4)
-#define VIDEO_CFG_TITLE (1 << 5)
-#define VIDEO_CFG_SHM_EXT (1 << 6)
-#define VIDEO_CFG_TYPE (1 << 8)
-#define VIDEO_CFG_FLAGS (1 << 9)
-#define VIDEO_CFG_BPP (1 << 10)
-#define VIDEO_CFG_POSITION (1 << 11) /* both i_x and i_y */
-#define VIDEO_CFG_ALIGN (1 << 12) /* both i_h_align and i_v_align */
-#define VIDEO_CFG_RATIO (1 << 13) /* both i_h_ratio and i_y_ratio */
-#define VIDEO_CFG_LEVEL (1 << 14)
-#define VIDEO_CFG_REFCOUNT (1 << 15)
-#define VIDEO_CFG_STREAM (1 << 16)
-#define VIDEO_CFG_DATE (1 << 17)
-#define VIDEO_CFG_DURATION (1 << 18)
-#define VIDEO_CFG_PIXEL (1 << 19)
-#define VIDEO_CFG_DATA (1 << 20)
*******************************************************************************/
/* Thread management functions */
-vdec_thread_t * vdec_CreateThread ( /* video_cfg_t *p_cfg, */ input_thread_t *p_input /*,
+p_vdec_thread_t vdec_CreateThread ( /* video_cfg_t *p_cfg, */ input_thread_t *p_input /*,
vout_thread_t *p_vout, int *pi_status */ );
void vdec_DestroyThread ( vdec_thread_t *p_vdec /*, int *pi_status */ );
* Prototypes
*******************************************************************************/
-/* Pictures management functions */
-picture_t * video_CreatePicture ( video_cfg_t *p_cfg );
-picture_t * video_CopyPicture ( picture_t *p_pic );
-picture_t * video_ReplicatePicture ( picture_t *p_pic );
-void video_DestroyPicture ( picture_t *p_pic );
-/* Files functions */
-picture_t * video_ReadPicture ( int i_file );
-
-/* Drawing functions */
-void video_ClearPicture ( picture_t *p_pic );
-void video_DrawPixel ( picture_t *p_pic, int i_x, int i_y, pixel_t value );
-void video_DrawHLine ( picture_t *p_pic, int i_x, int i_y, int i_width, pixel_t value );
-void video_DrawVLine ( picture_t *p_pic, int i_x, int i_y, int i_height, pixel_t value );
-void video_DrawLine ( picture_t *p_pic, int i_x1, int i_y1,
- int i_x2, int i_y2, pixel_t value );
-void video_DrawBar ( picture_t *p_pic, int i_x, int i_y, int i_width,
- int i_height, pixel_t value );
-void video_DrawRectangle ( picture_t *p_pic, int i_x, int i_y,
- int i_width, int i_height, pixel_t color );
-void video_DrawPicture ( picture_t *p_pic, picture_t *p_insert, int i_x, int i_y );
-void video_DrawText ( picture_t *p_pic, int i_x, int i_y, char *psz_text,
- int i_size, pixel_t color );
-
-/* Convertion functions */
-/* ?? rgb->pixel, pixel->rgb */
-
-/* Low-level shared functions */
-void video_CopyPictureDescriptor ( picture_t *p_dest, picture_t *p_src );
-int video_CreatePictureBody ( picture_t *p_pic, video_cfg_t *p_cfg );
-
-#ifdef DEBUG
-/* Debugging functions */
-void video_PrintPicture ( picture_t *p_pic, char *psz_str );
-#endif
* "video.h"
*******************************************************************************/
-/* ?? this over-complicated API and code should be re-designed, with a simple
- * video-stream associated to a window (each window designed to be openned in
- * a parent one and probably without border), and have an api looking like
- * vout_CreateWindow
- * vout_DestroyWindow
- * vout_AddPicture
- * vout_RemovePicture
- * vout_ReservePicture
- * vout_AddReservedPicture
- * vout_Clear
- * vout_Refresh
- *
- * the overlay/transparent, permanent and such stuff should disapear.
- */
-
-/*******************************************************************************
- * vout_stream_t: video stream descriptor
- *******************************************************************************
- * Each video stream has a set of properties, stored in this structure. It is
- * part of vout_thread_t and is not supposed to be used anywhere else.
- *******************************************************************************/
-typedef struct
-{
- int i_status; /* is stream active ? */
- picture_t * p_next_picture; /* next picture to be displayed */
-
-#ifdef STATS
- /* Statistics */
- count_t c_pictures; /* total number of pictures added */
- count_t c_rendered_pictures; /* number of rendered pictures */
-#endif
-} vout_stream_t;
-
-/* Video stream status */
-#define VOUT_INACTIVE_STREAM 0 /* stream is inactive (empty) */
-#define VOUT_ACTIVE_STREAM 1 /* stream is active */
-#define VOUT_ENDING_STREAM 2 /* stream will be destroyed when empty */
-#define VOUT_DESTROYED_STREAM 3 /* stream must be destroyed */
-
/*******************************************************************************
* vout_thread_t: video output thread descriptor
*******************************************************************************
boolean_t b_die; /* `die' flag */
boolean_t b_error; /* `error' flag */
boolean_t b_active; /* `active' flag */
- vlc_thread_t thread_id; /* id for thread functions */
- vlc_mutex_t streams_lock; /* streams modification lock */
- vlc_mutex_t pictures_lock; /* pictures modification lock */
+ pthread_t thread_id; /* id for pthread functions */
+ pthread_mutex_t lock; /* thread lock */
int * pi_status; /* temporary status flag */
/* Common display properties */
int i_height; /* current output method height */
int i_screen_depth; /* bits per pixel */
int i_bytes_per_pixel; /* real screen depth */
+ float f_x_ratio; /* horizontal display ratio */
+ float f_y_ratio; /* vertical display ratio */
/* Output method */
- struct vout_x11_s * p_x11; /* X11 output method */
+ p_vout_sys_t p_sys; /* system output method */
/* Video heap */
- int i_max_pictures; /* heap maximal size */
int i_pictures; /* current heap size */
- picture_t * p_picture; /* pictures */
-
- /* Streams data */
- vout_stream_t p_stream[VOUT_MAX_STREAMS]; /* streams data */
+ picture_t p_picture[VOUT_MAX_PICTURES]; /* pictures */
#ifdef STATS
/* Statistics */
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 */
- count_t c_rendered_pictures; /* number of pictures rendered */
#endif
/* Rendering functions - these functions are of vout_render_blank_t and
* vout_render_line_t, but are not declared here using these types since
* they require vout_thread_t to be defined */
- void (* RenderRGBBlank) ( struct vout_thread_s *p_vout, pixel_t pixel,
+/* void (* RenderRGBBlank) ( struct vout_thread_s *p_vout, pixel_t pixel,
int i_x, int i_y, int i_width, int i_height );
void (* RenderPixelBlank) ( struct vout_thread_s *p_vout, pixel_t pixel,
int i_x, int i_y, int i_width, int i_height );
void (* RenderPixelMaskLine) ( struct vout_thread_s *p_vout, picture_t *p_pic,
int i_x, int i_y, int i_pic_x, int i_pic_y,
int i_width, int i_line_width, int i_ratio );
- /* ?? add YUV types */
+ */ /* ?? add YUV types */
} vout_thread_t;
-/*******************************************************************************
- * vout_render_blank_t: blank rendering function
- * vout_render_line_t: rectangle rendering functions
- *******************************************************************************
- * All rendering functions should be of these types - for blank pictures
- * (pictures with uniform color), blank rendering functions are called once. For
- * other pictures, each function is called once for each picture line. Note that
- * the part of the picture sent to the rendering functions is in the output
- * window, since the clipping is done before.
- * p_vout is the calling thread
- * pixel is the color or pixel value of the rectange to be drawn
- * p_pic is the picture to be rendered
- * i_x, i_y is the absolute position in output window
- * i_pic_x is the first pixel to be drawn in the picture
- * i_pic_y is the line of the picture to be drawn
- * i_width is the width of the area to be rendered in the picture (not in the
- * output window), except for blank pictures, where it is the absolute size
- * of the area to be rendered
- * i_height is the height og the area to be rendered
- * i_line_width is the number of time the line must be copied
- * i_ratio is the horizontal display ratio
- *******************************************************************************/
-typedef void (vout_render_blank_t)( vout_thread_t *p_vout, pixel_t pixel,
- int i_x, int i_y, int i_width, int i_height );
-typedef void (vout_render_line_t) ( vout_thread_t *p_vout, picture_t *p_pic,
- int i_x, int i_y, int i_pic_x, int i_pic_y,
- int i_width, int i_line_width, int i_ratio );
-
/*******************************************************************************
* Prototypes
*******************************************************************************/
-vout_thread_t * vout_CreateThread ( video_cfg_t *p_cfg, int *pi_status );
-void vout_DestroyThread ( vout_thread_t *p_vout, int *pi_status );
-
-picture_t * vout_DisplayPicture ( vout_thread_t *p_vout, picture_t *p_pic );
-picture_t * vout_DisplayPictureCopy ( vout_thread_t *p_vout, picture_t *p_pic );
-picture_t * vout_DisplayPictureReplicate ( vout_thread_t *p_vout, picture_t *p_pic );
-picture_t * vout_DisplayReservedPicture ( vout_thread_t *p_vout, picture_t *p_pic );
-
-picture_t * vout_CreateReservedPicture ( vout_thread_t *p_vout, video_cfg_t *p_cfg );
-picture_t * vout_ReservePicture ( vout_thread_t *p_vout, picture_t *p_pic );
-picture_t * vout_ReservePictureCopy ( vout_thread_t *p_vout, picture_t *p_pic );
-picture_t * vout_ReservePictureReplicate ( vout_thread_t *p_vout, picture_t *p_pic );
-void vout_RemovePicture ( vout_thread_t *p_vout, picture_t *p_pic );
+vout_thread_t * vout_CreateThread (
+#if defined(VIDEO_X11)
+ Display *p_display, Window root_window,
+#elif defined(VIDEO_FB)
+ //??void
+#endif
+ int i_width, int i_height, int *pi_status
+ );
-void vout_RefreshPermanentPicture ( vout_thread_t *p_vout, picture_t *p_pic,
- mtime_t displa_date );
+void vout_DestroyThread ( vout_thread_t *p_vout, int *pi_status );
+picture_t * vout_CreatePicture ( vout_thread_t *p_vout, int i_type,
+ int i_width, int i_height, int i_bytes_per_line );
+void vout_DestroyPicture ( vout_thread_t *p_vout, picture_t *p_pic );
+void vout_DisplayPicture ( vout_thread_t *p_vout, picture_t *p_pic );
void vout_LinkPicture ( vout_thread_t *p_vout, picture_t *p_pic );
void vout_UnlinkPicture ( vout_thread_t *p_vout, picture_t *p_pic );
-int vout_CreateStream ( vout_thread_t *p_vout );
-void vout_EndStream ( vout_thread_t *p_vout, int i_stream );
-void vout_DestroyStream ( vout_thread_t *p_vout, int i_stream );
-
#ifdef DEBUG
void vout_PrintHeap ( vout_thread_t *p_vout, char *psz_str );
#endif
+
+
+
+
+
+
+
+
+
--- /dev/null
+/*******************************************************************************
+ * video_sys.h: system dependant video output display method API
+ * (c)1999 VideoLAN
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ *******************************************************************************/
+#if defined(VIDEO_X11)
+int vout_SysCreate ( p_vout_thread_t p_vout, Display *p_display, Window root_window );
+#elif defined(VIDEO_FB)
+int vout_SysCreate ( p_vout_thread_t p_vout );
+#endif
+int vout_SysInit ( p_vout_thread_t p_vout );
+void vout_SysEnd ( p_vout_thread_t p_vout );
+void vout_SysDestroy ( p_vout_thread_t p_vout );
+int vout_SysManage ( p_vout_thread_t p_vout );
+void vout_SysDisplay ( p_vout_thread_t p_vout );
+
+
/*******************************************************************************
- * all.h: all headers
+ * vlc.h: all headers
* (c)1998 VideoLAN
*******************************************************************************
* This header includes all vlc .h headers and depending headers. A source file
*******************************************************************************/
/* System headers */
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+
+#include <net/if.h>
+
#include <netinet/in.h>
+
+#include <sys/ioctl.h>
+#include <sys/shm.h>
#include <sys/soundcard.h>
#include <sys/uio.h>
+
#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
#include <X11/extensions/XShm.h>
+#include <X11/extensions/xf86dga.h>
+
+
/* Common headers */
#include "config.h"
#include "common.h"
#include "mtime.h"
#include "vlc_thread.h"
+#include "netutils.h"
+#include "debug.h"
+#include "xutils.h"
+#include "intf_msg.h"
/* Input */
#include "input.h"
+#include "input_psi.h"
+#include "input_pcr.h"
+#include "input_netlist.h"
#include "input_vlan.h"
#include "decoder_fifo.h"
+#include "input_file.h"
+#include "input_network.h"
/* Audio */
#include "audio_output.h"
/* Video */
#include "video.h"
+#include "video_sys.h"
#include "video_output.h"
#include "video_decoder.h"
/* Interface */
-#include "xconsole.h"
+#include "intf_cmd.h"
+#include "intf_ctrl.h"
+#include "intf_sys.h"
+#include "intf_console.h"
#include "interface.h"
-#include "intf_msg.h"
-
-/* Shared resources */
-#include "pgm_data.h"
+#include "main.h"
/*******************************************************************************
* vlc_thread.h : thread implementation for vieolan client
* (c)1999 VideoLAN
- ******************************************************************************/
-
+ *******************************************************************************
+ * This header is supposed to provide a portable threads implementation.
+ * Currently, it is a wrapper to the POSIX pthreads library.
+ *******************************************************************************/
#include <pthread.h>
-/*******************************************************************************
- * types definition
- ******************************************************************************/
+/******************************************************************************
+ * Constants
+ ******************************************************************************
+ * These constants are used by all threads in *_CreateThread() and
+ * *_DestroyThreads() functions. Since those calls are non-blocking, an integer
+ * value is used as a shared flag to represent the status of the thread.
+ *******************************************************************************/
+
+/* Void status - this value can be used to be sure, in an array of recorded
+ * threads, that no operation is currently in progress on the concerned thread */
+#define THREAD_NOP 0 /* nothing happened */
+
+/* Creation status */
+#define THREAD_CREATE 10 /* thread is initializing */
+#define THREAD_START 11 /* thread has forked */
+#define THREAD_READY 19 /* thread is ready */
+/* Destructions status */
+#define THREAD_DESTROY 20 /* destruction order has been sent */
+#define THREAD_END 21 /* destruction order has been received */
+#define THREAD_OVER 29 /* thread does not exist any more */
+
+/* Error status */
+#define THREAD_ERROR 30 /* an error occured */
+#define THREAD_FATAL 31 /* an fatal error occured - program must end */
+
+/******************************************************************************
+ * Types definition
+ ******************************************************************************/
typedef pthread_t vlc_thread_t;
typedef pthread_mutex_t vlc_mutex_t;
typedef pthread_cond_t vlc_cond_t;
-typedef void *(*vlc_thread_func)(void *data);
+typedef void *(*vlc_thread_func_t)(void *p_data);
/******************************************************************************
* Prototypes
******************************************************************************/
-static __inline__ int vlc_thread_create ( vlc_thread_t * thread, char * name,
- vlc_thread_func func, void * data );
-static __inline__ void vlc_thread_exit ( );
-static __inline__ void vlc_thread_join ( vlc_thread_t thread );
+static __inline__ int vlc_thread_create( vlc_thread_t *p_thread, char *psz_name,
+ vlc_thread_func_t func, void *p_data );
+static __inline__ void vlc_thread_exit ( void );
+static __inline__ void vlc_thread_join ( vlc_thread_t thread );
-static __inline__ int vlc_mutex_init ( vlc_mutex_t * mutex );
-static __inline__ int vlc_mutex_lock ( vlc_mutex_t * mutex );
-static __inline__ int vlc_mutex_unlock ( vlc_mutex_t * mtex );
+static __inline__ int vlc_mutex_init ( vlc_mutex_t *p_mutex );
+static __inline__ int vlc_mutex_lock ( vlc_mutex_t *p_mutex );
+static __inline__ int vlc_mutex_unlock ( vlc_mutex_t *p_mutex );
-static __inline__ int vlc_cond_init ( vlc_cond_t * condvar );
-static __inline__ int vlc_cond_signal ( vlc_cond_t * condvar );
-static __inline__ int vlc_cond_wait ( vlc_cond_t * condvar, vlc_mutex_t * mutex );
+static __inline__ int vlc_cond_init ( vlc_cond_t *p_condvar );
+static __inline__ int vlc_cond_signal ( vlc_cond_t *p_condvar );
+static __inline__ int vlc_cond_wait ( vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex );
//static _inline__ int vlc_cond_timedwait ( vlc_cond_t * condvar, vlc_mutex_t * mutex,
// mtime_t absoute_timeout_time );
/*******************************************************************************
- * vlc_thread_create
+ * vlc_thread_create: create a thread
******************************************************************************/
-
-static __inline__ int vlc_thread_create(
- vlc_thread_t * thread,
- char * name,
- vlc_thread_func func,
- void * data)
+static __inline__ int vlc_thread_create( vlc_thread_t *p_thread,
+ char *psz_name, vlc_thread_func_t func,
+ void *p_data)
{
- return pthread_create( thread, NULL, func, data );
+ return pthread_create( p_thread, NULL, func, p_data );
}
/******************************************************************************
- * vlc_thread_exit
+ * vlc_thread_exit: terminate a thread
*******************************************************************************/
-
-static __inline__ void vlc_thread_exit()
+static __inline__ void vlc_thread_exit( void )
{
pthread_exit( 0 );
}
/*******************************************************************************
- * vlc_thread_exit
+ * vlc_thread_join: wait until a thread exits
******************************************************************************/
-
static __inline__ void vlc_thread_join( vlc_thread_t thread )
{
pthread_join( thread, NULL );
}
/*******************************************************************************
- * vlc_mutex_init
+ * vlc_mutex_init: initialize a mutex
*******************************************************************************/
-
-static __inline__ int vlc_mutex_init( vlc_mutex_t * mutex )
+static __inline__ int vlc_mutex_init( vlc_mutex_t *p_mutex )
{
- return pthread_mutex_init( mutex, NULL );
+ return pthread_mutex_init( p_mutex, NULL );
}
/*******************************************************************************
- * vlc_mutex_lock
+ * vlc_mutex_lock: lock a mutex
*******************************************************************************/
-
-static __inline__ int vlc_mutex_lock( vlc_mutex_t * mutex )
+static __inline__ int vlc_mutex_lock( vlc_mutex_t *p_mutex )
{
- return pthread_mutex_lock( mutex );
+ return pthread_mutex_lock( p_mutex );
}
/*******************************************************************************
- * vlc_mutex_unlock
+ * vlc_mutex_unlock: unlock a mutex
*******************************************************************************/
-
-static __inline__ int vlc_mutex_unlock( vlc_mutex_t * mutex )
+static __inline__ int vlc_mutex_unlock( vlc_mutex_t *p_mutex )
{
- return pthread_mutex_unlock( mutex );
+ return pthread_mutex_unlock( p_mutex );
}
/*******************************************************************************
- * vlc_cond_init
+ * vlc_cond_init: initialize a condition
*******************************************************************************/
-
-static __inline__ int vlc_cond_init( vlc_cond_t * condvar )
+static __inline__ int vlc_cond_init( vlc_cond_t *p_condvar )
{
- return pthread_cond_init( condvar, NULL );
+ return pthread_cond_init( p_condvar, NULL );
}
/*******************************************************************************
- * vlc_cond_signal
+ * vlc_cond_signal: start a thread on condition completion
*******************************************************************************/
-
-static __inline__ int vlc_cond_signal( vlc_cond_t * condvar )
+static __inline__ int vlc_cond_signal( vlc_cond_t *p_condvar )
{
- return pthread_cond_signal( condvar );
+ return pthread_cond_signal( p_condvar );
}
+
/*******************************************************************************
- * vlc_cond_wait
+ * vlc_cond_wait: wait until condition completion
*******************************************************************************/
-
-static __inline__ int vlc_cond_wait( vlc_cond_t * condvar, vlc_mutex_t * mutex )
+static __inline__ int vlc_cond_wait( vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex )
{
- return pthread_cond_wait( condvar, mutex );
+ return pthread_cond_wait( p_condvar, p_mutex );
}
+++ /dev/null
-/*******************************************************************************
- * xconsole.h: X11 console for interface
- * (c)1998 VideoLAN
- *******************************************************************************
- * The X11 console is a simple way to get interactive input from the user. It
- * does not disturbs the standard terminal output. In theory, multiple consoles
- * could be openned on different displays.
- *?? will probably evolve
- *******************************************************************************/
-
-/*******************************************************************************
- * xconsole_t: X11 console descriptor
- *******************************************************************************
- * The display pointer is specific to this structure since in theory, multiple
- * console could be openned on different displays. A console is divided in two
- * sections. The lower one is a single line edit control. Above, a multi-line
- * output zone allow to send messages.
- *******************************************************************************/
-typedef struct
-{
- /* Initialization fields - those fields should be initialized before
- * calling intf_OpenX11Console(). */
- char * psz_display; /* display name */
- char * psz_geometry; /* window geometry */
-
- /* following fields are internal */
-
- /* Settings and display properties */
- Display * p_display; /* display pointer */
- int i_screen; /* screen number */
- XFontStruct * p_font; /* used font */
- Window window; /* window instance handler */
-
- /* Graphic contexts */
- GC default_gc; /* graphic context for default text */
-
- /* Pixmaps */
- Pixmap background_pixmap; /* window background */
-
- /* Window properties */
- int i_width, i_height; /* window dimensions */
- int i_text_offset; /* text zone placement from bottom */
- int i_text_line_height;/* height of a single text line */
- int i_edit_height; /* total edit zone height */
- int i_edit_offset; /* edit zone placement from bottom */
-
- /* Text array */
- char * psz_text[INTF_XCONSOLE_MAX_LINES]; /* text */
- int i_text_index; /* last line index */
-
- /* Edit lines properties. The line has one more character than
- * maximum width to allow adding a terminal '\0' when it is sent to
- * execution or text zone. The size must stay between 0 (included) and
- * INTF_X11_CONSOLE_MAX_LINE_WIDTH (included). The cursor position (index)
- * can be between 0 (included) and size (included). */
- char sz_edit[INTF_XCONSOLE_MAX_LINE_WIDTH + 1];
- int i_edit_index; /* cursor position */
- int i_edit_size; /* total size of edit text */
-
- /* History. The history array (composed of asciiz strings) has a base,
- * marking the *next* registered line, and an index, marking the actual
- * line browsed. When an history browse is started, the current line is
- * stored at base (but base isn't increased), and index is modified.
- * When a command is executed, it is registered at base and base is
- * increased. */
- char * psz_history[INTF_XCONSOLE_HISTORY_SIZE + 1];
- int i_history_index; /* index in history */
- int i_history_base; /* history base */
-} xconsole_t;
-
-/*******************************************************************************
- * Prototypes
- *******************************************************************************/
-int intf_OpenXConsole ( xconsole_t *p_console );
-void intf_CloseXConsole ( xconsole_t *p_console );
-
-void intf_ManageXConsole ( xconsole_t *p_console );
-void intf_ClearXConsole ( xconsole_t *p_console );
-void intf_PrintXConsole ( xconsole_t *p_console, char *psz_str );
p_adec->p_aout_fifo = NULL;
/* Spawn the audio decoder thread */
- if ( vlc_thread_create(&p_adec->thread_id, "audio decoder", (vlc_thread_func)RunThread, (void *)p_adec) )
+ if ( vlc_thread_create(&p_adec->thread_id, "audio decoder", (vlc_thread_func_t)RunThread, (void *)p_adec) )
{
intf_ErrMsg("adec error: can't spawn audio decoder thread\n");
free( p_adec );
#include "audio_output.h"
#include "audio_dsp.h"
+#include "main.h"
/******************************************************************************
* Local prototypes
******************************************************************************/
+
+static int aout_SpawnThread( aout_thread_t * p_aout );
+
/* Creating as much aout_Thread functions as configurations is one solution,
* examining the different cases in the Thread loop of an unique function is
* another. I chose the first solution. */
static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo/*, mtime_t aout_date*/ );
/******************************************************************************
- * aout_Open
+ * aout_CreateThread: initialize audio thread
******************************************************************************/
-int aout_Open( aout_thread_t * p_aout )
+aout_thread_t *aout_CreateThread( int *pi_status )
{
- if ( aout_dspOpen( &p_aout->dsp ) )
+ aout_thread_t * p_aout; /* thread descriptor */
+ int i_status; /* thread status */
+
+ /* Allocate descriptor */
+ p_aout = (aout_thread_t *) malloc( sizeof(aout_thread_t) );
+ if( p_aout == NULL )
{
- return( -1 );
+ return( NULL );
}
+ //???? kludge to initialize some audio parameters - place this section somewhere
+ //???? else
+ p_aout->dsp.i_format = AOUT_DEFAULT_FORMAT;
+ p_aout->dsp.psz_device = main_GetPszVariable( AOUT_DSP_VAR, AOUT_DSP_DEFAULT );
+ p_aout->dsp.b_stereo = main_GetIntVariable( AOUT_STEREO_VAR, AOUT_STEREO_DEFAULT );
+ p_aout->dsp.l_rate = main_GetIntVariable( AOUT_RATE_VAR, AOUT_RATE_DEFAULT );
+ // ???? end of kludge
+
+ /*
+ * Initialize DSP
+ */
+ if ( aout_dspOpen( &p_aout->dsp ) )
+ {
+ free( p_aout );
+ return( NULL );
+ }
if ( aout_dspReset( &p_aout->dsp ) )
{
aout_dspClose( &p_aout->dsp );
- return( -1 );
+ free( p_aout );
+ return( NULL );
}
-
if ( aout_dspSetFormat( &p_aout->dsp ) )
{
aout_dspClose( &p_aout->dsp );
- return( -1 );
+ free( p_aout );
+ return( NULL );
}
-
if ( aout_dspSetChannels( &p_aout->dsp ) )
{
aout_dspClose( &p_aout->dsp );
- return( -1 );
+ free( p_aout );
+ return( NULL );
}
-
if ( aout_dspSetRate( &p_aout->dsp ) )
{
aout_dspClose( &p_aout->dsp );
- return( -1 );
+ free( p_aout );
+ return( NULL );
}
-
intf_DbgMsg("aout debug: audio device (%s) opened (format=%i, stereo=%i, rate=%li)\n",
p_aout->dsp.psz_device,
p_aout->dsp.i_format,
p_aout->dsp.b_stereo, p_aout->dsp.l_rate);
- return( 0 );
+ //?? maybe it would be cleaner to change SpawnThread prototype
+ //?? see vout to handle status correctly - however, it is not critical since
+ //?? this thread is only called in main is all calls are blocking
+ if( aout_SpawnThread( p_aout ) )
+ {
+ aout_dspClose( &p_aout->dsp );
+ free( p_aout );
+ return( NULL );
+ }
+
+ return( p_aout );
}
/******************************************************************************
* aout_SpawnThread
******************************************************************************/
-int aout_SpawnThread( aout_thread_t * p_aout )
+static int aout_SpawnThread( aout_thread_t * p_aout )
{
- int i_fifo;
- long l_bytes;
- s64 s64_numerator, s64_denominator;
- void * aout_thread = NULL;
+ int i_fifo;
+ long l_bytes;
+ s64 s64_numerator, s64_denominator;
+ void * aout_thread = NULL;
intf_DbgMsg("aout debug: spawning audio output thread (%p)\n", p_aout);
p_aout->date = mdate();
/* Launch the thread */
- if ( vlc_thread_create( &p_aout->thread_id, "audio output", (vlc_thread_func)aout_thread, p_aout ) )
+ if ( vlc_thread_create( &p_aout->thread_id, "audio output", (vlc_thread_func_t)aout_thread, p_aout ) )
{
intf_ErrMsg("aout error: can't spawn audio output thread (%p)\n", p_aout);
free( p_aout->buffer );
}
/******************************************************************************
- * aout_CancelThread
+ * aout_DestroyThread
******************************************************************************/
-void aout_CancelThread( aout_thread_t * p_aout )
+void aout_DestroyThread( aout_thread_t * p_aout, int *pi_status )
{
+ //???? pi_status is not handled correctly: check vout how to do!
+
intf_DbgMsg("aout debug: requesting termination of audio output thread (%p)\n", p_aout);
/* Ask thread to kill itself and wait until it's done */
p_aout->b_die = 1;
- vlc_thread_join( p_aout->thread_id );
+ vlc_thread_join( p_aout->thread_id ); // only if pi_status is NULL
/* Free the allocated memory */
free( p_aout->buffer );
free( p_aout->s32_buffer );
-}
-/******************************************************************************
- * aout_Close
- ******************************************************************************/
-void aout_Close( aout_thread_t * p_aout )
-{
+ /* Free the structure */
aout_dspClose( &p_aout->dsp );
intf_DbgMsg("aout debug: audio device (%s) closed\n", p_aout->dsp.psz_device);
+ free( p_aout );
}
/******************************************************************************
/******************************************************************************
* Preamble
- ******************************************************************************/
-#include <errno.h>
+ *******************************************************************************/
+#include "vlc.h"
+
+/*#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "thread.h"
#include "intf_msg.h"
-#include "debug.h" /* ?? temporaire, requis par netlist.h */
-
+#include "debug.h" */
+/*
#include "input.h"
#include "input_netlist.h"
#include "decoder_fifo.h"
#include "video.h"
#include "video_output.h"
-#include "video_decoder.h"
+#include "video_decoder.h"*/
/*
* Local prototypes
/*******************************************************************************
* Preamble
- ******************************************************************************/
+ *******************************************************************************/
+#include "vlc.h"
+
+/*
#include <errno.h>
-#include <sys/uio.h> /* iovec */
+#include <sys/uio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/extensions/XShm.h>
#include <sys/soundcard.h>
-#include <stdlib.h> /* atoi(), malloc(), free() */
+#include <stdlib.h>
#include <stdio.h>
-#include <sys/ioctl.h> /* ioctl() */
-#include <net/if.h> /* ifreq */
+#include <sys/ioctl.h>
+#include <net/if.h>
#include <netinet/in.h>
#include "common.h"
#include "video.h"
#include "video_output.h"
#include "video_decoder.h"
+*/
/******************************************************************************
* Local prototypes
#ifdef NO_THREAD
input_Thread( p_input );
#else
- if( vlc_thread_create(&p_input->thread_id, "input", (vlc_thread_func)input_Thread,
+ if( vlc_thread_create(&p_input->thread_id, "input", (vlc_thread_func_t)input_Thread,
(void *) p_input) )
{
intf_ErrMsg("input error: can't spawn input thread (%s)\n",
EndThread( p_input );
intf_DbgMsg("input debug: thread %p destroyed\n", p_input);
- vlc_thread_exit( 0 );
+ vlc_thread_exit();
}
/*******************************************************************************
* Preamble
*******************************************************************************/
+#include "vlc.h"
+
+/*
#include <errno.h>
-#include <sys/uio.h> /* iovec */
-#include <stdlib.h> /* atoi(), malloc(), free() */
+#include <sys/uio.h>
+#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/extensions/XShm.h>
#include <sys/soundcard.h>
-#include <netinet/in.h> /* ntohs */
+#include <netinet/in.h>
#include "common.h"
#include "config.h"
#include "video.h"
#include "video_output.h"
-#include "video_decoder.h"
-
+#include "video_decoder.h" */
/******************************************************************************
* input_AddPgrmElem: Start the extraction and the decoding of a program element
/*******************************************************************************
* Preamble
- ******************************************************************************/
+ *******************************************************************************/
+#include "vlc.h"
+
+/*
+#include <errno.h>
+#include <pthread.h>
#include <errno.h>
#include <stdio.h>
-#include <sys/uio.h> /* iovec */
-#include <stdlib.h> /* atoi(), malloc(), free() */
+#include <sys/uio.h>
+#include <stdlib.h>
#include <string.h>
-#include <netinet/in.h> /* ntohs */
+#include <netinet/in.h>
#include <sys/soundcard.h>
#include <X11/Xlib.h>
#include <X11/extensions/XShm.h>
#include "xconsole.h"
#include "interface.h"
-#include "pgm_data.h"
+#include "pgm_data.h"*/
/*
* Precalculated 32-bits CRC table, shared by all instances of the PSI decoder
* the option (audio and video) passed to the VideoLAN client.
*/
#ifdef AUTO_SPAWN
-extern program_data_t *p_program_data;
+//??extern program_data_t *p_main;
#endif
/*
{
case MPEG1_VIDEO_ES:
case MPEG2_VIDEO_ES:
- if( p_program_data->cfg.b_video )
+ if( p_main->b_video )
{
/* Spawn a video thread */
input_AddPgrmElem( p_input,
break;
case MPEG1_AUDIO_ES:
case MPEG2_AUDIO_ES:
- if( p_program_data->cfg.b_audio )
+ if( p_main->b_audio )
{
/* Spawn an audio thread */
input_AddPgrmElem( p_input,
/*******************************************************************************
* Preamble
*******************************************************************************/
+#include "vlc.h"
+
+/*#include <errno.h>
+#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include "interface.h"
#include "intf_msg.h"
-#include "pgm_data.h"
+#include "pgm_data.h"*/
+
+/*******************************************************************************
+ * input_vlan_iface_t: vlan-capable network interface
+ *******************************************************************************
+ * This structure describes the abilities of a network interface capable of
+ * vlan management. Note that an interface could have several IP adresses, but
+ * since only the MAC address is used to change vlan, only one needs to be
+ * retrieved.
+ * ?? it could be interesting to send a port id on vlan request, to know if two
+ * interfaces are dependant regarding vlan changes.
+ *******************************************************************************/
+typedef struct
+{
+ char * psz_name; /* interface name */
+ struct sockaddr_in sa_in; /* interface IP */
+ char psz_mac[20]; /* interface MAC */
+
+ /* Hardware properties */
+ int i_master; /* master interface index */
+ int i_switch; /* switch number */
+ int i_port; /* port number */
+ int i_sharers; /* number of MACs on this port */
+
+ /* Vlan properties - these are only used if i_master is negative */
+ int i_refcount; /* locks counter */
+ int i_vlan; /* current vlan */
+ int i_default_vlan; /* default vlan */
+} input_vlan_iface_t;
+
+/*******************************************************************************
+ * input_vlan_server_t: vlan server
+ *******************************************************************************
+ * This structure describes a vlan server.
+ *******************************************************************************/
+typedef struct
+{
+ struct sockaddr_in sa_in; /* server address */
+ int i_socket; /* socket descriptor */
+
+ /* Login informations */
+ char * psz_login; /* server login */
+ char * psz_passwd; /* server password */
+} input_vlan_server_t;
+
+/*******************************************************************************
+ * vlan_method_data_t
+ *******************************************************************************
+ * Store global vlan library data.
+ *******************************************************************************/
+typedef struct input_vlan_method_s
+{
+ vlc_mutex_t lock; /* library lock */
+
+ /* Server */
+ input_vlan_server_t server; /* vlan server */
+
+ /* Network interfaces */
+ int i_ifaces; /* number of vlan-compliant interfaces */
+ input_vlan_iface_t * p_iface; /* interfaces */
+} input_vlan_method_t;
/*
* Constants
input_vlan_iface_t *p_iface );
/*******************************************************************************
- * input_VlanMethodInit: initialize global vlan method data
+ * input_VlanCreate: initialize global vlan method data
*******************************************************************************
* Initialize vlan input method global data. This function should be called
* once before any input thread is created or any call to other input_Vlan*()
* function is attempted.
*******************************************************************************/
-int input_VlanMethodInit( input_vlan_method_t *p_method, char *psz_server, int i_port )
+int input_VlanCreate( void )
{
+ char * psz_server; // ??? get from environment
+ int i_port; // ??? get from environment
int i_index; /* interface/servers index */
input_vlan_iface_t * p_iface; /* interfaces */
+ input_vlan_method_t *p_method = p_main->p_input_vlan; //??
/* Build vlan server descriptor */
if( BuildInetAddr( &p_method->server.sa_in, psz_server, i_port ) )
}
/*******************************************************************************
- * input_VlanMethodFree: free global vlan method data
+ * input_VlanDestroy: free global vlan method data
*******************************************************************************
* Free resources allocated by input_VlanMethodInit. This function should be
* called at the end of the program.
*******************************************************************************/
-void input_VlanMethodFree( input_vlan_method_t *p_method )
+void input_VlanDestroy( void )
{
int i_index; /* server/interface index */
+ input_vlan_method_t *p_method = p_main->p_input_vlan; // ??
/* Leave all remaining vlans */
for( i_index = 0; i_index < p_method->i_ifaces; i_index++ )
input_vlan_method_t * p_method; /* method global data */
int i_index; /* interface index */
- p_method = &p_program_data->input_vlan_method;
+ p_method = p_main->p_input_vlan;
/* If psz_iface is NULL, use first (default) interface (if there is one) */
if( psz_iface == NULL )
}
/* Browse all interfaces */
- for( i_index = 0; i_index < p_program_data->input_vlan_method.i_ifaces ; i_index++ )
+ for( i_index = 0; i_index < p_main->p_input_vlan->i_ifaces ; i_index++ )
{
/* If interface has been found, return */
- if( !strcmp( p_program_data->input_vlan_method.p_iface[i_index].psz_name, psz_iface ) )
+ if( !strcmp( p_main->p_input_vlan->p_iface[i_index].psz_name, psz_iface ) )
{
return( VLAN_ID( i_index, i_vlan ) );
}
/* Initialize shortcuts, and use master if interface is dependant */
i_err = 0;
- p_method = &p_program_data->input_vlan_method;
+ p_method = p_main->p_input_vlan;
p_iface = &p_method->p_iface[ VLAN_ID_IFACE( i_vlan_id ) ];
if( p_iface->i_master >= 0 )
{
/* Initialize shortcuts, and use master if interface is dependant */
i_err = 0;
- p_method = &p_program_data->input_vlan_method;
+ p_method = p_main->p_input_vlan;
p_iface = &p_method->p_iface[ VLAN_ID_IFACE( i_vlan_id ) ];
if( p_iface->i_master >= 0 )
{
input_vlan_method_t * p_method; /* method global data */
int i_index; /* interface index */
- p_method = &p_program_data->input_vlan_method;
+ p_method = p_main->p_input_vlan;
/* If psz_iface is NULL, use first (default) interface (if there is one) -
* note that interface 0 can't be dependant, so dependance does not need
int i_vlan; /* vlan for current interface */
/* Get lock */
+ p_method = p_main->p_input_vlan;
+ pthread_mutex_lock( &p_method->lock );
+/* ??
p_method = &p_program_data->input_vlan_method;
vlc_mutex_lock( &p_method->lock );
+*/
for( i_index = 0; i_index < p_method->i_ifaces; i_index++ )
{
/*******************************************************************************
* Preamble
*******************************************************************************/
+#include "vlc.h"
+/*??
+#include <pthread.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/soundcard.h>
#include "intf_msg.h"
#include "control.h"
-#include "pgm_data.h"
+#include "pgm_data.h"*/
-/*******************************************************************************
- * intf_CreateVoutThread: create video output thread in interface
- *******************************************************************************
- * This function creates - if possible - a new video output thread in the
- * interface registery, using interface default settings. It returns the
- * thread number for the interface, or a negative number.
- * If video is desactivated, nothing will be done. If psz_title is not NULL, it
- * will be used as window's title, and width and height will also be used if
- * they are positive.
- *******************************************************************************/
-int intf_CreateVoutThread( intf_thread_t *p_intf, char *psz_title, int i_width, int i_height )
-{
-#if 0
- int i_thread; /* thread index */
- video_cfg_t cfg; /* thread configuration */
-
- /* Verify that video is enabled */
- if( !p_program_data->cfg.b_video )
- {
- return( -1 );
- }
-
- /* Set configuration */
- memcpy( &cfg, &p_program_data->vout_cfg, sizeof( cfg ) );
- if( psz_title != NULL )
- {
- cfg.i_properties |= VIDEO_CFG_TITLE;
- cfg.psz_title = psz_title;
- }
- if( i_width > 0 )
- {
- cfg.i_properties |= VIDEO_CFG_WIDTH;
- cfg.i_width = i_width;
- }
- if( i_height > 0 )
- {
- cfg.i_properties |= VIDEO_CFG_HEIGHT;
- cfg.i_height = i_height;
- }
-
- /* Find an empty place */
- for( i_thread = 0; i_thread < VOUT_MAX_THREADS; i_thread++ )
- {
- if( p_intf->pp_vout[i_thread] == NULL )
- {
- /* The current place is empty: create a thread */
- p_intf->pp_vout[i_thread] = vout_CreateThread( &cfg, NULL );
- if( p_intf->pp_vout[i_thread] == NULL ) /* error */
- {
- return( -1 );
- }
- }
- }
-
- /* No empty place has been found */
- return( -1 );
-#endif
-}
-
-
-/*******************************************************************************
- * intf_DestroyVoutThread: destroy video output thread in interface
- *******************************************************************************
- * This function destroy a video output thread created with
- * intf_CreateVoutThread().
- *******************************************************************************/
-void intf_DestroyVoutThread( intf_thread_t *p_intf, int i_thread )
-{
-#if 0
-#ifdef DEBUG
- /* Check if thread still exists */
- if( p_intf->pp_vout[i_thread] == NULL )
- {
- intf_DbgMsg("intf error: destruction of an inexistant vout thread\n");
- return;
- }
-#endif
-
- /* Destroy thread and marks its place as empty */
- vout_DestroyThread( p_intf->pp_vout[i_thread], NULL );
- p_intf->pp_vout[i_thread] = NULL;
-#endif
-}
-
-
-/*******************************************************************************
- * intf_CreateInputThread: create input thread in interface
- *******************************************************************************
- * This function creates - if possible - a new input thread in the
- * interface registery, using interface default settings. It returns the
- * thread number for the interface, or a negative number.
- *******************************************************************************/
-int intf_CreateInputThread( intf_thread_t *p_intf, input_cfg_t* p_cfg )
-{
- int i_thread; /* thread index */
-
- /* Find an empty place */
- for( i_thread = 0; i_thread < INPUT_MAX_THREADS; i_thread++ )
- {
- if( p_intf->pp_input[i_thread] == NULL )
- {
- /* The current place is empty: create a thread and return */
- p_intf->pp_input[i_thread] = input_CreateThread( p_cfg );
- return( (p_intf->pp_input[i_thread] != NULL) ? i_thread : -1 );
- }
- }
-
- /* No empty place has been found */
- return( -1 );
-}
-
-/*******************************************************************************
- * intf_DestroyInputThread: destroy input thread in interface
- *******************************************************************************
- * This function destroy aa input thread created with
- * intf_CreateInputThread().
- *******************************************************************************/
-void intf_DestroyInputThread( intf_thread_t *p_intf, int i_thread )
-{
-#ifdef DEBUG
- /* Check if thread still exists */
- if( p_intf->pp_input[i_thread] == NULL )
- {
- intf_DbgMsg("intf error: destruction of an inexistant input thread\n");
- return;
- }
-#endif
- /* Destroy thread and marks its place as empty */
- input_DestroyThread( p_intf->pp_input[i_thread] );
- p_intf->pp_input[i_thread] = NULL;
-}
/*******************************************************************************
* Preamble
*******************************************************************************/
+#include <errno.h>
#include <stdio.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <sys/soundcard.h>
-#include <sys/uio.h>
-#include <X11/Xlib.h>
-#include <X11/extensions/XShm.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/uio.h> /* for input.h */
#include "config.h"
#include "common.h"
#include "mtime.h"
#include "vlc_thread.h"
-#include "thread.h"
-#include "debug.h"
-
+#include "input.h"
#include "intf_msg.h"
+#include "interface.h"
+#include "intf_cmd.h"
+#include "intf_console.h"
+#include "main.h"
-#include "input.h"
-#include "input_netlist.h"
-#include "input_vlan.h"
-#include "decoder_fifo.h"
+#include "intf_sys.h"
-#include "audio_output.h"
-#include "audio_decoder.h"
-#include "video.h"
-#include "video_output.h"
-#include "video_decoder.h"
+/*******************************************************************************
+ * intf_Create: prepare interface before main loop
+ *******************************************************************************
+ * This function opens output devices and create specific interfaces. It send
+ * it's own error messages.
+ *******************************************************************************/
+intf_thread_t* intf_Create( void )
+{
+ intf_thread_t *p_intf;
-#include "xconsole.h"
-#include "interface.h"
-#include "intf_cmd.h"
+ /* Allocate structure */
+ p_intf = malloc( sizeof( intf_thread_t ) );
+ if( !p_intf )
+ {
+ errno = ENOMEM;
+ return( NULL );
+ }
+ p_intf->b_die = 0;
+ intf_DbgMsg( "0x%x\n", p_intf );
+
+ /* Initialize structure */
+ p_intf->p_vout = NULL;
+ p_intf->p_input = NULL;
-#include "pgm_data.h"
-/* ?? remove useless headers */
+ /* Start interfaces */
+ p_intf->p_console = intf_ConsoleCreate();
+ if( p_intf->p_console == NULL )
+ {
+ intf_ErrMsg("intf error: can't create control console\n");
+ free( p_intf );
+ return( NULL );
+ }
+ if( intf_SysCreate( p_intf ) )
+ {
+ intf_ErrMsg("intf error: can't create interface\n");
+ intf_ConsoleDestroy( p_intf->p_console );
+ free( p_intf );
+ return( NULL );
+ }
-/*
- * Local prototypes
- */
-static int StartInterface ( intf_thread_t *p_intf );
-static void EndInterface ( intf_thread_t *p_intf );
+ return( p_intf );
+}
/*******************************************************************************
* intf_Run
*******************************************************************************
- * what it does:
- * - Create an X11 console
- * - wait for a command and try to execute it
- * - interpret the order returned after the command execution
- * - print the messages of the message queue (intf_FlushMsg)
- * return value: 0 if successful, < 0 otherwise
+ * Initialization script and main interface loop.
*******************************************************************************/
-int intf_Run( intf_thread_t *p_intf )
-{
- /* When it is started, interface won't die immediatly */
- p_intf->b_die = 0;
- if( StartInterface( p_intf ) ) /* error */
+void intf_Run( intf_thread_t *p_intf )
+{
+ intf_DbgMsg("0x%x begin\n", p_intf );
+
+ /* Execute the initialization script - if a positive number is returned,
+ * the script could be executed but failed */
+ if( intf_ExecScript( main_GetPszVariable( INTF_INIT_SCRIPT_VAR, INTF_INIT_SCRIPT_DEFAULT ) ) > 0 )
{
- return( 1 );
+ intf_ErrMsg("intf error: error during initialization script\n");
}
-
+
/* Main loop */
while(!p_intf->b_die)
{
/* Flush waiting messages */
intf_FlushMsg();
-#ifndef FRAMEBUFFER
- /* Manage specific interfaces */
- intf_ManageXConsole( &p_intf->xconsole ); /* X11 console */
-#endif
+ /* Manage specific interface */
+ intf_SysManage( p_intf );
/* Sleep to avoid using all CPU - since some interfaces needs to access
* keyboard events, a 100ms delay is a good compromise */
msleep( INTF_IDLE_SLEEP );
}
- /* End of interface thread - the main() function will close all remaining
- * output threads */
- EndInterface( p_intf );
- return ( 0 );
+ intf_DbgMsg("0x%x end\n", p_intf );
}
-/* following functions are local */
-
/*******************************************************************************
- * StartInterface: prepare interface before main loop
+ * intf_Destroy: clean interface after main loop
*******************************************************************************
- * This function opens output devices and create specific interfaces. It send
- * it's own error messages.
+ * This function destroys specific interfaces and close output devices.
*******************************************************************************/
-static int StartInterface( intf_thread_t *p_intf )
+void intf_Destroy( intf_thread_t *p_intf )
{
- int i_thread; /* thread index */
-#ifdef INIT_SCRIPT
- int fd;
-#endif
-
-#if 0
- /* Empty all threads array */
- for( i_thread = 0; i_thread < VOUT_MAX_THREADS; i_thread++ )
- {
- p_intf->pp_vout[i_thread] = NULL;
- }
-#endif
- for( i_thread = 0; i_thread < INPUT_MAX_THREADS; i_thread++ )
- {
- p_intf->pp_input[i_thread] = NULL;
- }
-
-#ifdef FRAMEBUFFER
- intf_DbgMsg("intf debug: not opening X11 console\n");
-#else
- /* Start X11 Console*/
- if( intf_OpenXConsole( &p_intf->xconsole ) )
- {
- intf_ErrMsg("intf error: can't open X11 console\n");
- return( 1 );
- }
-#endif
+ intf_DbgMsg("0x%x\n", p_intf );
-#ifdef INIT_SCRIPT
- /* Execute the initialization script (typically spawn an input thread) */
- if ( (fd = open( INIT_SCRIPT, O_RDONLY )) != -1 )
- {
- /* Startup script does exist */
- close( fd );
- intf_ExecScript( INIT_SCRIPT );
- }
-#endif
+ /* Destroy interfaces */
+ intf_SysDestroy( p_intf );
+ intf_ConsoleDestroy( p_intf->p_console );
- return( 0 );
+ /* Free structure */
+ free( p_intf );
}
/*******************************************************************************
- * EndInterface: clean interface after main loop
+ * intf_SelectInput: change input stream
*******************************************************************************
- * This function destroys specific interfaces and close output devices.
+ * Kill existing input, if any, and try to open a new one. If p_cfg is NULL,
+ * no new input will be openned.
*******************************************************************************/
-static void EndInterface( intf_thread_t *p_intf )
+int intf_SelectInput( intf_thread_t * p_intf, input_cfg_t *p_cfg )
{
- int i_thread; /* thread index */
- boolean_t b_thread; /* flag for remaing threads */
- int pi_vout_status[VOUT_MAX_THREADS]; /* vout threads status */
+ intf_DbgMsg("0x%x\n", p_intf );
+ /* Kill existing input, if any */
+ if( p_intf->p_input != NULL )
+ {
+ input_DestroyThread( p_intf->p_input /*??, NULL*/ );
+ p_intf->p_input = NULL;
+ }
-#ifndef FRAMEBUFFER
- /* Close X11 console */
- intf_CloseXConsole( &p_intf->xconsole );
-#endif
-
- /* Destroy all remaining input threads */
- for( i_thread = 0; i_thread < INPUT_MAX_THREADS; i_thread++ )
- {
- if( p_intf->pp_input[i_thread] != NULL )
- {
- input_DestroyThread( p_intf->pp_input[i_thread] );
- }
+ /* Open new one */
+ if( p_cfg != NULL )
+ {
+ p_intf->p_input = input_CreateThread( p_cfg /*??, NULL*/ );
}
+
+ return( (p_cfg != NULL) && (p_intf->p_input == NULL) );
+}
-#if 0
- /* Destroy all remaining video output threads - all destruction orders are send,
- * then all THREAD_OVER status are received */
- for( i_thread = 0, b_thread = 0; i_thread < VOUT_MAX_THREADS; i_thread++ )
- {
- if( p_intf->pp_vout[i_thread] != NULL )
- {
- vout_DestroyThread( p_intf->pp_vout[i_thread], &pi_vout_status[i_thread] );
- b_thread = 1;
- }
- }
- while( b_thread )
- {
- msleep( INTF_IDLE_SLEEP );
- b_thread = 0;
- for( i_thread = 0; i_thread < VOUT_MAX_THREADS; i_thread++ )
- {
- if( (p_intf->pp_vout[i_thread] != NULL)
- && (pi_vout_status[i_thread] != THREAD_OVER) )
- {
- b_thread = 1;
- }
- }
- }
-#endif
-}
/*******************************************************************************
* Preamble
*******************************************************************************/
+#include "vlc.h"
+
+/*
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include "intf_msg.h"
#include "intf_cmd.h"
#include "intf_ctrl.h"
-
-#include "pgm_data.h"
+*/
/*
* Local prototypes
case INTF_FATAL_ERROR: /* fatal error */
/* Print message and terminates the interface thread */
intf_ErrMsg( "intf fatal: in command `%s'\n", psz_argv[0] );
- p_program_data->intf_thread.b_die = 1;
+ p_main->p_intf->b_die = 1;
break;
case INTF_CRITICAL_ERROR: /* critical error */
--- /dev/null
+/*******************************************************************************
+ * intf_console.c: generic console for interface
+ * (c)1998 VideoLAN
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Preamble
+ *******************************************************************************/
+#include <stdlib.h>
+
+#include "config.h"
+
+/*******************************************************************************
+ * intf_console_t: console descriptor
+ *******************************************************************************
+ * Generic console object. This object will have a representation depending of
+ * the interface.
+ *******************************************************************************/
+typedef struct intf_console_s
+{
+ /* Text and history arrays - last line/command has indice 0 */
+ char * psz_text[INTF_CONSOLE_MAX_TEXT];
+ char * psz_history[INTF_CONSOLE_MAX_HISTORY];
+} intf_console_t;
+
+/*******************************************************************************
+ * Local prototypes
+ *******************************************************************************/
+
+/*******************************************************************************
+ * intf_ConsoleCreate: create console
+ *******************************************************************************
+ * This function will initialize the console object.
+ * It returns NULL on error.
+ *******************************************************************************/
+intf_console_t *intf_ConsoleCreate( void )
+{
+ intf_console_t *p_console;
+
+ p_console = malloc( sizeof( intf_console_t ) );
+ return( p_console );
+}
+
+/*******************************************************************************
+ * intf_ConsoleDestroy
+ *******************************************************************************
+ * Destroy the console instance initialized by intf_ConsoleCreate.
+ *******************************************************************************/
+void intf_ConsoleDestroy( intf_console_t *p_console )
+{
+ free( p_console );
+}
+
+/*******************************************************************************
+ * intf_ConsoleClear: clear console
+ *******************************************************************************
+ * Empty all text.
+ *******************************************************************************/
+void intf_ConsoleClear( intf_console_t *p_console )
+{
+ //??
+}
+
+/*******************************************************************************
+ * intf_ConsolePrint: print a message to console
+ *******************************************************************************
+ * Print a message to the console.
+ *******************************************************************************/
+void intf_ConsolePrint( intf_console_t *p_console, char *psz_str )
+{
+ //??
+}
+
+
+/*******************************************************************************
+ * intf_ConsoleExec: execute a command in console
+ *******************************************************************************
+ * This function will run a command and print its result in console.
+ *******************************************************************************/
+void intf_ConsoleExec( intf_console_t *p_console, char *psz_str )
+{
+ //??
+}
+
+/* following functions are local */
/*******************************************************************************
* Preamble
*******************************************************************************/
-#include <errno.h>
+#include "vlc.h"
+/*??#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include "intf_ctrl.h"
#include "pgm_data.h"
+*/
/*
* Local prototypes
struct stat stat_buffer; /* needed to find out the size of psz_file */
int i_arg; /* argument index */
- if ( !p_program_data->cfg.b_audio ) /* audio is disabled */
+ if ( !p_main->b_audio ) /* audio is disabled */
{
intf_IntfMsg("play-audio error: audio is disabled");
return( INTF_NO_ERROR );
close( i_fd );
/* Now we can work out how many output units we can compute with the fifo */
- fifo.l_units = (long)(((s64)fifo.l_units*(s64)p_program_data->aout_thread.dsp.l_rate)/(s64)fifo.l_rate);
+ fifo.l_units = (long)(((s64)fifo.l_units*(s64)p_main->p_aout->dsp.l_rate)/(s64)fifo.l_rate);
/* Create the fifo */
- if ( aout_CreateFifo(&p_program_data->aout_thread, &fifo) == NULL )
+ if ( aout_CreateFifo(p_main->p_aout, &fifo) == NULL )
{
intf_IntfMsg("play-audio error: can't create audio fifo");
free( fifo.buffer );
*******************************************************************************/
static int Quit( int i_argc, intf_arg_t *p_argv )
{
- p_program_data->intf_thread.b_die = 1;
+ p_main->p_intf->b_die = 1;
return( INTF_NO_ERROR );
}
switch( p_argv[i_arg].i_index )
{
case 0:
+ // ?? useless
i_input = p_argv[i_arg].i_num;
break;
case 1:
/* Find to which input this command is destinated */
- if(i_input < INPUT_MAX_THREADS )
- {
- if( p_program_data->intf_thread.pp_input[i_input] )
- {
- intf_IntfMsg( "Adding PID %d to input %d\n", i_pid, i_input );
- input_AddPgrmElem( p_program_data->intf_thread.pp_input[i_input],
- i_pid );
- return( INTF_NO_ERROR );
- }
- }
-
- /* No such input was created */
- intf_IntfMsg("No such input thread is currently running: %d\n", i_input);
- return( INTF_OTHER_ERROR );
+ intf_IntfMsg( "Adding PID %d to input %d\n", i_pid, i_input );
+//???? input_AddPgrmElem( p_main->p_intf->p_x11->p_input,
+//???? i_pid );
+ return( INTF_NO_ERROR );
}
}
/* Default settings for the decoder threads */
- cfg.p_aout = p_program_data->intf_thread.p_aout;
+ cfg.p_aout = p_main->p_aout;
/* Create the input thread */
- if( intf_CreateInputThread( &p_program_data->intf_thread, &cfg ) == -1)
+ if( intf_SelectInput( p_main->p_intf, &cfg ) == -1)
{
return( INTF_OTHER_ERROR );
}
{
int i_thread;
- if( i_argc == 1 )
+/*?? if( i_argc == 1 )
{
- i_thread = intf_CreateVoutThread( &p_program_data->intf_thread, NULL, -1, -1);
+ i_thread = intf_CreateVoutThread( &p_main->intf_thread, NULL, -1, -1);
intf_IntfMsg("return value: %d", i_thread );
}
- else
+ else*/
{
i_thread = p_argv[1].i_num;
- intf_DestroyVoutThread( &p_program_data->intf_thread, i_thread );
+ //?? intf_DestroyVoutThread( &p_main->intf_thread, i_thread );
}
return( INTF_NO_ERROR );
int i_command; /* command argument number */
/* Do not try anything if vlans are desactivated */
- if( !p_program_data->cfg.b_vlans )
+ if( !p_main->b_vlans )
{
intf_IntfMsg("vlans are desactivated");
return( INTF_OTHER_ERROR );
{
int i_index = p_argv[1].i_num;
- if(i_index < INPUT_MAX_THREADS )
- {
- if(p_program_data->intf_thread.pp_input[i_index])
- {
- /* Read the Psi table for that thread */
- intf_IntfMsg("Reading PSI table for input %d\n", i_index);
- input_PsiRead(p_program_data->intf_thread.pp_input[i_index]);
- return( INTF_NO_ERROR );
- }
- }
-
- /* No such input was created */
- intf_IntfMsg("No such input thread is currently running: %d\n", i_index);
-
- return( INTF_OTHER_ERROR );
+ intf_IntfMsg("Reading PSI table for input %d\n", i_index);
+//???? input_PsiRead(p_main->p_intf->p_x11->p_input );
+ return( INTF_NO_ERROR );
}
* (c)1998 VideoLAN
*******************************************************************************
* This library provides basic functions for threads to interact with user
- * interface, such as message output. If INTF_MSG_QUEUE is defined (which is the
- * defaul), messages are not printed directly by threads, to bypass console
- * limitations and slow printf() calls, but sent to a queue and printed later by
- * interface thread.
- * If INTF_MSG_QUEUE is not defined, output is directly performed on stderr.
- * Exported symbols are declared in intf_msg.h.
+ * interface, such as message output. See config.h for output configuration.
*******************************************************************************/
/*******************************************************************************
* Preamble
*******************************************************************************/
#include <errno.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
-#include <netinet/in.h>
-#include <sys/soundcard.h>
-#include <sys/uio.h>
-#include <X11/Xlib.h>
-#include <X11/extensions/XShm.h>
+#include <unistd.h>
#include "config.h"
#include "common.h"
#include "mtime.h"
#include "vlc_thread.h"
-#include "debug.h"
+#include "intf_msg.h"
+#include "interface.h"
+#include "intf_console.h"
+#include "main.h"
-#include "input.h"
-#include "input_vlan.h"
+/*******************************************************************************
+ * intf_msg_item_t
+ *******************************************************************************
+ * Store a single message. Messages have a maximal size of INTF_MSG_MSGSIZE.
+ * If DEBUG is defined, messages have a date field and debug messages are
+ * printed with a date to allow more precise profiling.
+ *******************************************************************************/
+typedef struct
+{
+ int i_type; /* message type, see below */
+ char * psz_msg; /* the message itself */
-#include "audio_output.h"
+#ifdef DEBUG
+ /* Debugging informations - in DEBUG mode, debug messages have calling
+ * location informations printed */
+ mtime_t date; /* date of the message */
+ char * psz_file; /* file in which the function was called */
+ char * psz_function; /* function from which the function was called */
+ int i_line; /* line at which the function was called */
+#endif
+} intf_msg_item_t;
-#include "video.h"
-#include "video_output.h"
+/* Message types */
+#define INTF_MSG_STD 0 /* standard message */
+#define INTF_MSG_ERR 1 /* error message */
+#define INTF_MSG_INTF 2 /* interface message */
+#define INTF_MSG_DBG 3 /* debug message */
-#include "xconsole.h"
-#include "interface.h"
-#include "intf_msg.h"
+/*******************************************************************************
+ * intf_msg_t
+ *******************************************************************************
+ * Store all data requiered by messages interfaces. It has a single reference
+ * int p_main.
+ *******************************************************************************/
+typedef struct intf_msg_s
+{
+#ifdef INTF_MSG_QUEUE
+ /* Message queue */
+ vlc_mutex_t lock; /* message queue lock */
+ int i_count; /* number of messages stored */
+ intf_msg_item_t msg[INTF_MSG_QSIZE]; /* message queue */
+#endif
-#include "pgm_data.h"
+#ifdef DEBUG_LOG
+ /* Log file */
+ int i_log_file; /* log file */
+#endif
+
+#if !defined(INTF_MSG_QUEUE) && !defined(DEBUG_LOG)
+ /* If neither messages queue, neither log file is used, then the structure
+ * is empty. However, empty structures are not allowed in C. Therefore, a
+ * dummy integer is used to fill it. */
+ int i_dummy; /* unused filler */
+#endif
+} intf_msg_t;
-/*
+/*****************************************************************************
* Local prototypes
- */
+ *****************************************************************************/
-static void QueueMsg ( interface_msg_t *p_intf_msg, int i_type,
- char *psz_format, va_list ap );
-static void PrintMsg ( interface_msg_message_t *p_msg );
+static void QueueMsg ( intf_msg_t *p_msg, int i_type,
+ char *psz_format, va_list ap );
+static void PrintMsg ( intf_msg_item_t *p_msg );
#ifdef DEBUG
-static void QueueDbgMsg ( interface_msg_t *p_intf_msg, char *psz_file,
+static void QueueDbgMsg ( intf_msg_t *p_msg, char *psz_file,
char *psz_function, int i_line,
char *psz_format, va_list ap );
#endif
#ifdef INTF_MSG_QUEUE
-static void FlushLockedMsg ( interface_msg_t *p_intf_msg );
+static void FlushLockedMsg ( intf_msg_t *p_msg );
#endif
+
/*******************************************************************************
- * intf_InitMsg: initialize messages interface (ok ?)
+ * intf_MsgCreate: initialize messages interface (ok ?)
*******************************************************************************
* This functions has to be called before any call to other intf_*Msg functions.
- * It set up the locks and the message queue if it is used. On error,
- * it returns errno (without printing its own error messages) and free all
- * alocated resources.
+ * It set up the locks and the message queue if it is used.
*******************************************************************************/
-int intf_InitMsg( interface_msg_t *p_intf_msg )
+p_intf_msg_t intf_MsgCreate( void )
{
+ p_intf_msg_t p_msg;
+
+ /* Allocate structure */
+ p_msg = malloc( sizeof( intf_msg_t ) );
+ if( p_msg == NULL )
+ {
+ errno = ENOMEM;
+ }
+ else
+ {
#ifdef INTF_MSG_QUEUE
/* Message queue initialization */
vlc_mutex_init( &p_intf_msg->lock ); /* intialize lock */
#endif
#ifdef DEBUG_LOG
- /* Log file initialization */
- p_intf_msg->p_log_file = fopen( DEBUG_LOG, "w+" );
- if ( !p_intf_msg->p_log_file )
- {
- return( errno );
- }
+ /* Log file initialization - on failure, file pointer will be null,
+ * and no log will be issued, but this is not considered as an
+ * error */
+ p_msg->i_log_file = open( DEBUG_LOG, O_CREAT | O_APPEND | O_SYNC | O_WRONLY );
#endif
-
- return( 0 );
+ }
+ return( p_msg );
}
/*******************************************************************************
- * intf_TerminateMsg: free resources allocated by intf_InitMsg (ok ?)
+ * intf_MsgDestroy: free resources allocated by intf_InitMsg (ok ?)
*******************************************************************************
* This functions prints all messages remaining in queue, then free all the
* resources allocated by intf_InitMsg.
* No other messages interface functions should be called after this one.
*******************************************************************************/
-void intf_TerminateMsg( interface_msg_t *p_intf_msg )
+void intf_MsgDestroy( void )
{
intf_FlushMsg(); /* print all remaining messages */
#ifdef DEBUG_LOG
- /* Close log file */
- fclose( p_intf_msg->p_log_file );
+ /* Close log file if any */
+ if( p_main->p_msg->i_log_file >= 0 )
+ {
+ close( p_main->p_msg->i_log_file );
+ }
#endif
+
+ /* Free structure */
+ free( p_main->p_msg );
}
/*******************************************************************************
va_list ap;
va_start( ap, psz_format );
- QueueMsg( &p_program_data->intf_msg, INTF_MSG_STD, psz_format, ap );
+ QueueMsg( p_main->p_msg, INTF_MSG_STD, psz_format, ap );
va_end( ap );
}
* This function is the same as intf_Msg, except that it prints its messages
* on stderr.
*******************************************************************************/
-void intf_ErrMsg(char *psz_format, ...)
+void intf_ErrMsg( char *psz_format, ...)
{
va_list ap;
va_start( ap, psz_format );
- QueueMsg( &p_program_data->intf_msg, INTF_MSG_ERR, psz_format, ap );
+ QueueMsg( p_main->p_msg, INTF_MSG_ERR, psz_format, ap );
va_end( ap );
}
va_list ap;
va_start( ap, psz_format );
- QueueMsg( &p_program_data->intf_msg, INTF_MSG_INTF, psz_format, ap );
+ QueueMsg( p_main->p_msg, INTF_MSG_INTF, psz_format, ap );
va_end( ap );
}
va_list ap;
va_start( ap, psz_format );
- QueueDbgMsg( &p_program_data->intf_msg, psz_file, psz_function, i_line,
+ QueueDbgMsg( p_main->p_msg, psz_file, psz_function, i_line,
psz_format, ap );
va_end( ap );
}
va_list ap;
va_start( ap, psz_format );
- QueueMsg( &p_program_data->intf_msg, INTF_MSG_STD, psz_format, ap );
+ QueueMsg( p_main->p_msg, INTF_MSG_STD, psz_format, ap );
va_end( ap );
intf_FlushMsg();
}
va_list ap;
va_start( ap, psz_format );
- QueueMsg( &p_program_data->intf_msg, INTF_MSG_ERR, psz_format, ap );
+ QueueMsg( p_main->p_msg, INTF_MSG_ERR, psz_format, ap );
va_end( ap );
intf_FlushMsg();
}
va_list ap;
va_start( ap, psz_format );
- QueueDbgMsg( &p_program_data->intf_msg, psz_file, psz_function, i_line,
+ QueueDbgMsg( p_main->p_msg, psz_file, psz_function, i_line,
psz_format, ap );
va_end( ap );
intf_FlushMsg();
/* following functions are local */
/*******************************************************************************
- * QueueMsg: add a message to a queue (ok ?)
+ * QueueMsg: add a message to a queue
*******************************************************************************
* This function provide basic functionnalities to other intf_*Msg functions.
* It add a message to a queue (after having printed all stored messages if it
* is full. If the message can't be converted to string in memory, it exit the
* program. If the queue is not used, it prints the message immediately.
*******************************************************************************/
-static void QueueMsg(interface_msg_t *p_intf_msg, int i_type, char *psz_format, va_list ap)
+static void QueueMsg( intf_msg_t *p_msg, int i_type, char *psz_format, va_list ap )
{
- char * psz_str; /* formatted message string */
-#ifndef INTF_MSG_QUEUE
- interface_msg_message_t msg; /* message */
-#endif
+ char * psz_str; /* formatted message string */
+ intf_msg_item_t * p_msg_item; /* pointer to message */
+
+#ifndef INTF_MSG_QUEUE /*..................................... instant mode ...*/
+ intf_msg_item_t msg_item; /* message */
+ p_msg_item = &msg_item;
+#endif /*......................................................................*/
- /* Convert message to string */
+ /*
+ * Convert message to string
+ */
vasprintf( &psz_str, psz_format, ap );
if( psz_str == NULL )
{
- fprintf(stderr, "intf error: *** can not store message (%s) ***\n",
+ fprintf(stderr, "Warning: can't store following message (%s): ",
strerror(errno) );
vfprintf(stderr, psz_format, ap );
exit( errno );
}
-#ifdef INTF_MSG_QUEUE
-
- /*
- * Queue mode: the queue is flushed if it is full, then the message is
- * queued. A lock is required on queue to avoid indexes corruption
- */
- vlc_mutex_lock( &p_intf_msg->lock ); /* get lock */
-
- if( p_intf_msg->i_count == INTF_MSG_QSIZE ) /* flush queue if needed */
+#ifdef INTF_MSG_QUEUE /*........................................ queue mode ...*/
+ vlc_mutex_lock( &p_msg->lock ); /* get lock */
+ if( p_msg->i_count == INTF_MSG_QSIZE ) /* flush queue if needed */
{
-#ifdef DEBUG /* in debug mode, queue overflow causes a waring */
- fprintf(stderr, "intf warning: *** message queue overflow ***\n" );
+#ifdef DEBUG /* in debug mode, queue overflow causes a warning */
+ fprintf(stderr, "Warning: message queue overflow\n" );
#endif
- FlushLockedMsg( p_intf_msg );
+ FlushLockedMsg( p_msg );
}
-
- /* Queue message - if DEBUG if defined, the message is dated */
- p_intf_msg->msg[ p_intf_msg->i_count ].i_type = i_type;
- p_intf_msg->msg[ p_intf_msg->i_count++ ].psz_msg = psz_str;
-#ifdef DEBUG
- p_intf_msg->msg[ p_intf_msg->i_count ].date = mdate();
-#endif
-
- vlc_mutex_unlock( &p_intf_msg->lock ); /* give lock back */
-
-#else
+ p_msg_item = p_msg->msg + p_msg->i_count++; /* select message */
+#endif /*................................................ end of queue mode ...*/
/*
- * Instant mode: the message is converted and printed immediately
+ * Fill message information fields
*/
- msg.i_type = i_type;
- msg.psz_msg = psz_str;
-#ifdef DEBUG
- msg.date = mdate();
-#endif
- PrintMsg( &msg ); /* print message */
- free( psz_str ); /* free message data */
-
-#endif
+ p_msg_item->i_type = i_type;
+ p_msg_item->psz_msg = psz_str;
+
+#ifdef INTF_MSG_QUEUE /*........................................... queue mode */
+ vlc_mutex_unlock( &p_msg->lock ); /* give lock back */
+#else /*......................................................... instant mode */
+ PrintMsg( p_msg_item ); /* print message */
+ free( psz_str ); /* free message data */
+#endif /*......................................................................*/
}
/*******************************************************************************
* DEBUG is define, and require additionnal debugging informations.
*******************************************************************************/
#ifdef DEBUG
-static void QueueDbgMsg(interface_msg_t *p_intf_msg, char *psz_file, char *psz_function,
- int i_line, char *psz_format, va_list ap)
+static void QueueDbgMsg(intf_msg_t *p_msg, char *psz_file, char *psz_function,
+ int i_line, char *psz_format, va_list ap)
{
- char * psz_str; /* formatted message string */
-#ifndef INTF_MSG_QUEUE
- interface_msg_message_t msg; /* message */
-#endif
+ char * psz_str; /* formatted message string */
+ intf_msg_item_t * p_msg_item; /* pointer to message */
+
+#ifndef INTF_MSG_QUEUE /*..................................... instant mode ...*/
+ intf_msg_item_t msg_item; /* message */
+ p_msg_item = &msg_item;
+#endif /*......................................................................*/
- /* Convert message to string */
- vasprintf( &psz_str, psz_format, ap );
+ /*
+ * Convert message to string
+ */
+ vasprintf( &psz_str, psz_format, ap );
if( psz_str == NULL )
- { /* critical error: not enough memory to store message */
- fprintf(stderr, "intf error: *** can not store message (%s) ***\n", strerror(errno) );
+ {
+ fprintf(stderr, "Warning: can't store following message (%s): ",
+ strerror(errno) );
fprintf(stderr, INTF_MSG_DBG_FORMAT, psz_file, psz_function, i_line );
- vfprintf(stderr, psz_format, ap );
+ vfprintf(stderr, psz_format, ap );
exit( errno );
}
-#ifdef INTF_MSG_QUEUE
-
- /*
- * Queue mode: the queue is flushed if it is full, then the message is
- * queued. A lock is required on queue to avoid indexes corruption
- */
- vlc_mutex_lock( &p_intf_msg->lock ); /* get lock */
-
- if( p_intf_msg->i_count == INTF_MSG_QSIZE ) /* flush queue if needed */
+#ifdef INTF_MSG_QUEUE /*........................................ queue mode ...*/
+ vlc_mutex_lock( &p_msg->lock ); /* get lock */
+ if( p_msg->i_count == INTF_MSG_QSIZE ) /* flush queue if needed */
{
- fprintf(stderr, "intf warning: *** message queue overflow ***\n" );
- FlushLockedMsg( p_intf_msg );
+#ifdef DEBUG /* in debug mode, queue overflow causes a warning */
+ fprintf(stderr, "Warning: message queue overflow\n" );
+#endif
+ FlushLockedMsg( p_msg );
}
-
- /* Queue message */
- p_intf_msg->msg[ p_intf_msg->i_count ].i_type = INTF_MSG_DBG;
- p_intf_msg->msg[ p_intf_msg->i_count ].date = mdate();
- p_intf_msg->msg[ p_intf_msg->i_count ].psz_file = psz_file;
- p_intf_msg->msg[ p_intf_msg->i_count ].psz_function = psz_function;
- p_intf_msg->msg[ p_intf_msg->i_count ].i_line = i_line;
- p_intf_msg->msg[ p_intf_msg->i_count++ ].psz_msg = psz_str;
-
- vlc_mutex_unlock( &p_intf_msg->lock ); /* give lock back */
-
-#else
+ p_msg_item = p_msg->msg + p_msg->i_count++; /* select message */
+#endif /*................................................ end of queue mode ...*/
/*
- * Instant mode: the message is converted and printed immediately
+ * Fill message information fields
*/
- msg.i_type = INTF_MSG_DBG;
- msg.psz_file = psz_file;
- msg.psz_function = psz_function;
- msg.i_line = i_line;
-#ifdef DEBUG
-// msg.date = mdate();
-#endif
- msg.psz_msg = psz_str;
- PrintMsg( &msg ); /* print message */
- free( psz_str ); /* free message data */
-
-#endif
+ p_msg_item->i_type = INTF_MSG_DBG;
+ p_msg_item->psz_msg = psz_str;
+ p_msg_item->psz_file = psz_file;
+ p_msg_item->psz_function = psz_function;
+ p_msg_item->i_line = i_line;
+ p_msg_item->date = mdate();
+
+#ifdef INTF_MSG_QUEUE /*........................................... queue mode */
+ vlc_mutex_unlock( &p_msg->lock ); /* give lock back */
+#else /*......................................................... instant mode */
+ PrintMsg( p_msg_item ); /* print message */
+ free( psz_str ); /* free message data */
+#endif /*......................................................................*/
}
#endif
* INTF_MSG_QUEUE is defined.
*******************************************************************************/
#ifdef INTF_MSG_QUEUE
-static void FlushLockedMsg ( interface_msg_t *p_intf_msg )
+static void FlushLockedMsg ( intf_msg_t *p_msg )
{
int i_index;
- for( i_index = 0; i_index < p_intf_msg->i_count; i_index++ )
+ for( i_index = 0; i_index < p_msg->i_count; i_index++ )
{
/* Print message and free message data */
- PrintMsg( &p_intf_msg->msg[i_index] );
- free( p_intf_msg->msg[i_index].psz_msg );
+ PrintMsg( &p_msg->msg[i_index] );
+ free( p_msg->msg[i_index].psz_msg );
}
- p_intf_msg->i_count = 0;
+ p_msg->i_count = 0;
}
#endif
*******************************************************************************/
#ifdef DEBUG
-static void PrintMsg( interface_msg_message_t *p_msg )
+static void PrintMsg( intf_msg_item_t *p_msg )
{
char psz_date[MSTRTIME_MAX_SIZE]; /* formatted time buffer */
char * psz_msg; /* message buffer */
-
- /* Computes date */
- mstrtime( psz_date, p_msg->date );
-
/* Format message - the message is formatted here because in case the log
* file is used, it avoids another format string parsing */
switch( p_msg->i_type )
{
case INTF_MSG_STD: /* regular messages */
case INTF_MSG_ERR:
- asprintf( &psz_msg, "(%s) %s", psz_date, p_msg->psz_msg );
+ asprintf( &psz_msg, "%s", p_msg->psz_msg );
break;
case INTF_MSG_INTF: /* interface messages */
- case INTF_MSG_DBG:
- asprintf( &psz_msg, p_msg->psz_msg );
+ asprintf( &psz_msg, "%s", p_msg->psz_msg );
break;
-#if 0
+
case INTF_MSG_DBG: /* debug messages */
+ mstrtime( psz_date, p_msg->date );
asprintf( &psz_msg, "(%s) " INTF_MSG_DBG_FORMAT "%s",
psz_date, p_msg->psz_file, p_msg->psz_function, p_msg->i_line,
p_msg->psz_msg );
break;
-#endif
}
/* Check if formatting function suceeded */
fprintf( stderr, psz_msg );
break;
case INTF_MSG_INTF: /* interface messages */
- intf_PrintXConsole( &p_program_data->intf_thread.xconsole, psz_msg );
+ intf_ConsolePrint( p_main->p_intf->p_console, psz_msg );
break;
}
#ifdef DEBUG_LOG
/* Append all messages to log file */
- fprintf( p_program_data->intf_msg.p_log_file, psz_msg );
+ if( p_main->p_msg->i_log_file >= 0 )
+ {
+ write( p_main->p_msg->i_log_file, psz_msg, strlen( psz_msg ) );
+ }
#endif
/* Free formatted message */
fprintf( stderr, p_msg->psz_msg );
break;
case INTF_MSG_INTF: /* interface messages */
- intf_PrintXConsole( &p_program_data->intf_thread.xconsole,
+ intf_PrintXConsole( &p_main->intf_thread.xconsole,
p_msg->psz_msg );
break;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <netinet/in.h>
-#include <sys/soundcard.h>
-#include <sys/uio.h>
-#include <X11/Xlib.h>
-#include <X11/extensions/XShm.h>
+
+#include <sys/soundcard.h> /* audio_output.h */
#include "config.h"
#include "common.h"
#include "mtime.h"
#include "vlc_thread.h"
-#include "netutils.h"
-#include "debug.h"
-
-#include "intf_msg.h"
-
-#include "input.h"
#include "input_vlan.h"
-#include "input_netlist.h"
-#include "decoder_fifo.h"
-
-#include "audio_output.h"
-#include "audio_decoder.h"
-
-#include "video.h"
-#include "video_output.h"
-#include "video_decoder.h"
-
-#include "xconsole.h"
+#include "intf_msg.h"
#include "interface.h"
+#include "audio_output.h"
+#include "main.h"
-#include "pgm_data.h"
-
-
-
-/*
+/*******************************************************************************
* Command line options constants. If something is changed here, be sure that
* GetConfiguration and Usage are also changed.
- */
+ *******************************************************************************/
/* Long options return values - note that values corresponding to short options
* chars, and in general any regular char, should be avoided */
-#define OPT_DISPLAY 130
-
-#define OPT_CONSOLE_DISPLAY 140
-#define OPT_CONSOLE_GEOMETRY 141
-
#define OPT_NOAUDIO 150
#define OPT_STEREO 151
#define OPT_MONO 152
#define OPT_RATE 153
#define OPT_NOVIDEO 160
-#define OPT_XSHM 161
-#define OPT_NOXSHM 162
+#define OPT_XDGA 161
+#define OPT_XSHM 162
+#define OPT_XNOSHM 163
+#define OPT_XNODGA 164
#define OPT_NOVLANS 170
#define OPT_VLAN_SERVER 171
/* General/common options */
{ "help", 0, 0, 'h' },
- { "display", 1, 0, OPT_DISPLAY },
-
- /* Interface options */
- { "console-display", 1, 0, OPT_CONSOLE_DISPLAY },
- { "console-geometry", 1, 0, OPT_CONSOLE_GEOMETRY },
/* Audio options */
{ "noaudio", 0, 0, OPT_NOAUDIO },
{ "stereo", 0, 0, OPT_STEREO },
{ "mono", 0, 0, OPT_MONO },
- { "rate", 0, 0, OPT_RATE },
/* Video options */
{ "novideo", 0, 0, OPT_NOVIDEO },
- { "xshm", 0, 0, OPT_XSHM },
- { "noxshm", 0, 0, OPT_NOXSHM },
/* VLAN management options */
{ "novlans", 0, 0, OPT_NOVLANS },
- { "vlanserver", 1, 0, OPT_VLAN_SERVER },
{ 0, 0, 0, 0 }
};
/* Short options */
static const char *psz_shortopts = "h";
-/*
- * Global variable program_data
- */
-program_data_t *p_program_data; /* see pgm_data.h */
+/*******************************************************************************
+ * Global variable program_data - this is the one and only, see main.h
+ *******************************************************************************/
+main_t *p_main;
-/*
+/*******************************************************************************
* Local prototypes
- */
-static void SetDefaultConfiguration ( program_data_t *p_data );
-static int GetConfiguration ( program_data_t *p_config, int i_argc, char *ppsz_argv[],
- char *ppsz_env[] );
+ *******************************************************************************/
+static void SetDefaultConfiguration ( void );
+static int GetConfiguration ( int i_argc, char *ppsz_argv[], char *ppsz_env[] );
static void Usage ( void );
-static long GetIntParam ( const char *psz_param, long i_min, long i_max, int *pi_err );
+
static void InitSignalHandler ( void );
static void SignalHandler ( int i_signal );
*******************************************************************************
* Steps during program execution are:
* -configuration parsing and messages interface initialization
- * -openning of audio output device
+ * -openning of audio output device and some global modules
* -execution of interface, which exit on error or on user request
- * -closing of audio output device
+ * -closing of audio output device and some global modules
* On error, the spawned threads are cancelled, and the openned devices closed.
- *******************************************************************************
- * ?? Signal handlers should be restored to default once the interface has
- * been closed, since they will cause a crash if the message interface is no
- * more active.
*******************************************************************************/
int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
{
- program_data_t program_data; /* root of all data - see pgm_data.h */
-
+ main_t main_data; /* root of all data - see main.h */
+ p_main = &main_data; /* set up the global variable */
+
/*
* Read configuration, initialize messages interface and set up program
- */
- p_program_data = &program_data; /* set up the global variable */
- if( intf_InitMsg( &program_data.intf_msg ) ) /* start messages interface */
+ */
+ p_main->p_msg = intf_MsgCreate();
+ if( !p_main->p_msg ) /* start messages interface */
{
- fprintf(stderr, "intf critical: can't initialize messages interface (%s)\n",
+ fprintf(stderr, "critical error: can't initialize messages interface (%s)\n",
strerror(errno));
return(errno);
}
- if( GetConfiguration( &program_data, /* parse command line */
- i_argc, ppsz_argv, ppsz_env ) )
+ if( GetConfiguration( i_argc, ppsz_argv, ppsz_env ) )/* parse command line */
{
- intf_TerminateMsg( &program_data.intf_msg );
+ intf_MsgDestroy();
return(errno);
}
intf_MsgImm( COPYRIGHT_MESSAGE ); /* print welcome message */
- InitSignalHandler(); /* prepare signals for interception */
/*
* Initialize shared resources and libraries
*/
- if( program_data.cfg.b_vlans
- && input_VlanMethodInit( &program_data.input_vlan_method,
- program_data.cfg.psz_input_vlan_server,
- program_data.cfg.i_input_vlan_server_port) )
+ if( main_data.b_vlans && input_VlanCreate() )
{
/* On error during vlans initialization, switch of vlans */
- intf_Msg("intf: switching off vlans\n");
- program_data.cfg.b_vlans = 0;
+ intf_Msg("Virtual LANs initialization failed : vlans management is desactivated\n");
+ main_data.b_vlans = 0;
}
/*
- * Open audio device
+ * Open audio device and start aout thread
*/
- if( program_data.cfg.b_audio )
- {
- if( aout_Open( &program_data.aout_thread ) )
- {
- /* On error during audio initialization, switch of audio */
- intf_Msg("intf: switching off audio\n");
- program_data.cfg.b_audio = 0;
- }
- else if( aout_SpawnThread( &program_data.aout_thread ) )
- {
- aout_Close( &program_data.aout_thread );
- input_VlanMethodFree( &program_data.input_vlan_method );
- intf_TerminateMsg( &program_data.intf_msg );
- return( -1 );
- }
- program_data.intf_thread.p_aout = &program_data.aout_thread;
+ if( main_data.b_audio )
+ {
+ main_data.p_aout = aout_CreateThread( NULL );
+ if( main_data.p_aout == NULL )
+ {
+ /* On error during audio initialization, switch of audio */
+ intf_Msg("Audio initialization failed : audio is desactivated\n");
+ main_data.b_audio = 0;
+ }
}
/*
* Run interface
*/
- intf_DbgMsg("intf debug: starting interface\n");
- intf_Run( &program_data.intf_thread );
- intf_DbgMsg("intf debug: interface terminated\n");
+ main_data.p_intf = intf_Create();
+ if( main_data.p_intf != NULL )
+ {
+ InitSignalHandler(); /* prepare signals for interception */
+ intf_Run( main_data.p_intf );
+ intf_Destroy( main_data.p_intf );
+ }
/*
* Close audio device
*/
- if( program_data.cfg.b_audio )
+ if( main_data.b_audio )
{
- aout_CancelThread( &program_data.aout_thread );
- aout_Close( &program_data.aout_thread );
+ aout_DestroyThread( main_data.p_aout, NULL );
}
/*
* Free shared resources and libraries
*/
- if( program_data.cfg.b_vlans )
+ if( main_data.b_vlans )
{
- input_VlanMethodFree( &program_data.input_vlan_method );
+ input_VlanDestroy();
}
/*
* Terminate messages interface and program
*/
- intf_Msg( "program terminated.\n" );
- intf_TerminateMsg( &program_data.intf_msg );
+ intf_Msg( "Program terminated.\n" );
+ intf_MsgDestroy();
return( 0 );
}
+/*******************************************************************************
+ * main_GetIntVariable: get the int value of an environment variable
+ *******************************************************************************
+ * This function is used to read some default parameters in modules.
+ *******************************************************************************/
+int main_GetIntVariable( char *psz_name, int i_default )
+{
+ char *psz_env;
+
+ psz_env = getenv( psz_name );
+ if( psz_env )
+ {
+ psz_env = strchr( psz_env, '=' );
+ if( psz_env )
+ {
+ return( atoi( psz_env + 1) );
+ }
+ }
+
+ return( i_default );
+}
+
+/*******************************************************************************
+ * main_GetPszVariable: get the string value of an environment variable
+ *******************************************************************************
+ * This function is used to read some default parameters in modules.
+ *******************************************************************************/
+char * main_GetPszVariable( char *psz_name, char *psz_default )
+{
+ char *psz_env;
+
+ psz_env = getenv( psz_name );
+ if( psz_env )
+ {
+ psz_env = strchr( psz_env, '=' );
+ if( psz_env )
+ {
+ return( psz_env + 1 );
+ }
+ }
+
+ return( psz_default );
+}
+
/* following functions are local */
/*******************************************************************************
* SetDefaultConfiguration: set default options
*******************************************************************************
* This function is called by GetConfiguration before command line is parsed.
- * It sets all the default values required later by the program. Note that
- * all properties must be initialized, wether they are command-line dependant
- * or not.
+ * It sets all the default values required later by the program. At this stage,
+ * most structure are not yet allocated, so initialization must be done using
+ * environment.
*******************************************************************************/
-static void SetDefaultConfiguration( program_data_t *p_data )
+static void SetDefaultConfiguration( void )
{
/*
- * Audio output thread configuration
+ * All features are activated by default
*/
- p_data->cfg.b_audio = 1; /* audio is activated by default */
- p_data->aout_thread.dsp.psz_device = AOUT_DEFAULT_DEVICE;
- /* je rajouterai la détection des formats supportés quand le reste
- * marchera */
- p_data->aout_thread.dsp.i_format = AOUT_DEFAULT_FORMAT;
- p_data->aout_thread.dsp.b_stereo = AOUT_DEFAULT_STEREO;
- p_data->aout_thread.dsp.l_rate = AOUT_DEFAULT_RATE;
+ p_main->b_audio = 1;
+ p_main->b_video = 1;
+ p_main->b_vlans = 1;
/*
- * Interface thread configuration
+ * Audio output thread configuration
*/
- /* X11 console */
- p_data->intf_thread.xconsole.psz_display = NULL;
- p_data->intf_thread.xconsole.psz_geometry = INTF_XCONSOLE_GEOMETRY;
- /* --- ?? following are ok */
+ // ?? initialization using structures is no more available, use putenv/getenv
+ // instead.
+
+
/*
* Video output thread configuration
*/
- p_data->cfg.b_video = 1;
- p_data->vout_cfg.i_properties = 0;
+ // p_data->vout_cfg.i_properties = 0;
/* VLAN management */
- p_data->cfg.b_vlans = 0;
+ /*??? p_data->cfg.b_vlans = 0;
p_data->cfg.psz_input_vlan_server = VLAN_DEFAULT_SERVER;
p_data->cfg.i_input_vlan_server_port = VLAN_DEFAULT_SERVER_PORT;
+ */
}
/*******************************************************************************
*******************************************************************************
* Parse command line and configuration file for configuration. If the inline
* help is requested, the function Usage() is called and the function returns
- * -1 (causing main() to exit). Note than messages interface is initialized at
- * this stage.
+ * -1 (causing main() to exit). The messages interface is initialized at this
+ * stage, but most structures are not allocated, so only environment should
+ * be used.
*******************************************************************************/
-static int GetConfiguration( program_data_t *p_data, int i_argc,
- char *ppsz_argv[], char *ppsz_env[] )
+static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
{
- int c, i_err;
+ int c, i_opt;
/* Set default configuration and copy arguments */
- p_data->i_argc = i_argc;
- p_data->ppsz_argv = ppsz_argv;
- p_data->ppsz_env = ppsz_env;
- SetDefaultConfiguration( p_data );
+ p_main->i_argc = i_argc;
+ p_main->ppsz_argv = ppsz_argv;
+ p_main->ppsz_env = ppsz_env;
+ SetDefaultConfiguration();
- /* Parse command line */
+ /* Parse command line options */
opterr = 0;
while( ( c = getopt_long( i_argc, ppsz_argv, psz_shortopts, longopts, 0 ) ) != EOF )
{
Usage();
return( -1 );
break;
- case OPT_DISPLAY: /* --display */
- p_data->vout_cfg.psz_display = optarg;
- p_data->vout_cfg.i_properties |= VIDEO_CFG_DISPLAY;
- p_data->intf_thread.xconsole.psz_display = optarg;
- break;
-
- /* Interface options */
- case OPT_CONSOLE_DISPLAY: /* --console-display */
- p_data->intf_thread.xconsole.psz_display = optarg;
- break;
- case OPT_CONSOLE_GEOMETRY: /* --console-geometry */
- p_data->intf_thread.xconsole.psz_geometry = optarg;
- break;
/* Audio options */
case OPT_NOAUDIO: /* --noaudio */
- p_data->cfg.b_audio = 0;
+ p_main->b_audio = 0;
break;
- case OPT_STEREO: /* --stereo */
- p_data->aout_thread.dsp.b_stereo = 1;
+ case OPT_STEREO: /* --stereo */
+ // ?? should be replaced by a putenv
+ //p_main->p_aout->dsp.b_stereo = 1;
break;
case OPT_MONO: /* --mono */
- p_data->aout_thread.dsp.b_stereo = 0;
- break;
- case OPT_RATE: /* --rate */
- p_data->aout_thread.dsp.l_rate = GetIntParam(optarg, AOUT_MIN_RATE, AOUT_MAX_RATE, &i_err );
- if( i_err )
- {
- return( EINVAL );
- }
+ // ?? should be replaced by a putenv
+ //p_main->p_aout->dsp.b_stereo = 0;
break;
/* Video options */
case OPT_NOVIDEO: /* --novideo */
- p_data->cfg.b_video = 0;
+ p_main->b_video = 0;
break;
- case OPT_XSHM: /* --xshm */
- p_data->vout_cfg.b_shm_ext = 1;
- p_data->vout_cfg.i_properties |= VIDEO_CFG_SHM_EXT;
- break;
- case OPT_NOXSHM: /* --noxshm */
- p_data->vout_cfg.b_shm_ext = 0;
- p_data->vout_cfg.i_properties |= VIDEO_CFG_SHM_EXT;
- break;
/* VLAN management options */
case OPT_NOVLANS: /* --novlans */
- p_data->cfg.b_vlans = 0;
- break;
- case OPT_VLAN_SERVER: /* --vlanserver */
- p_data->cfg.i_input_vlan_server_port = ServerPort( optarg );
- p_data->cfg.psz_input_vlan_server = optarg;
- break;
+ p_main->b_vlans = 0;
+ break;
/* Internal error: unknown option */
case '?':
}
}
+ /* Parse command line parameters - no check is made for these options */
+ for( i_opt = optind; i_opt < i_argc; i_opt++ )
+ {
+ putenv( ppsz_argv[ i_opt ] );
+ }
return( 0 );
}
static void Usage( void )
{
intf_Msg(COPYRIGHT_MESSAGE);
- /* General options */
- intf_Msg("usage: vlc [options...]\n" \
+ /* Usage */
+ intf_Msg("usage: vlc [options...] [parameters]\n" \
+ " parameters can be passed using environment variables\n" \
+ " example: vlan_server=vlan-server.via.ecp.fr:1234\n" \
+ );
+
+ /* Options */
+ intf_Msg("Options:" \
" -h, --help print usage\n" \
- );
- /* Audio options */
- intf_Msg(" --noaudio disable audio\n" \
+ " --noaudio disable audio\n" \
" --stereo enable stereo\n" \
" --mono disable stereo\n"
- " --rate <rate> audio output rate (kHz)\n" \
- );
- /* Video options */
- intf_Msg(" --novideo disable video\n" \
- " --xshm, --noxshm enable/disable use of XShm extension\n" \
- " -d, --display <display> set display name\n" \
+ " --novideo disable video\n" \
+ " --novlans disable vlans\n" \
);
- /* VLAN management options */
- intf_Msg(" --novlans disable vlans\n" \
- " --vlanserver <server[:port]> set vlan server address\n" \
- );
+ /* Interface parameters */
+ intf_Msg("Interface parameters:\n" \
+ " " INTF_INIT_SCRIPT_VAR "=<filename> initialization script\n" \
+ );
+
+ /* Audio parameters */
+ intf_Msg("Audio parameters:\n" \
+ " " AOUT_DSP_VAR "=<filename> dsp device path\n" \
+ " " AOUT_STEREO_VAR "={1|0} stereo or mono output\n" \
+ " " AOUT_RATE_VAR "=<rate> output rate\n" \
+ );
+
+ /* Video parameters */
+ intf_Msg("Video parameters:\n" \
+ );
+
+ /* Vlan parameters */
+ intf_Msg("VLANs (Virtual Local Aera Networks) parameters:\n" \
+ " vlan_server=<host>[:<port>] VLANs server address and port\n" \
+ );
}
-/*******************************************************************************
- * GetIntParam: convert a string to an integer
- *******************************************************************************
- * This function convert a string to an integer, check range of the value
- * and that there is no error during convertion. pi_err is a pointer to an
- * error flag, which contains non 0 on error. This function prints its own
- * error messages.
- *******************************************************************************/
-static long GetIntParam( const char *psz_param, long i_min, long i_max, int *pi_err )
-{
- char *psz_endptr;
- long int i_value;
-
- i_value = strtol( psz_param, &psz_endptr, 0 );
- if( (psz_param[0] == '\0') && (*psz_endptr != '\0') ) /* conversion error */
- {
- intf_ErrMsg("intf error: conversion error ('%s' should be an integer between %ld and %ld)\n",
- psz_param, i_min, i_max );
- *pi_err = EINVAL;
- return( 0 );
- }
- if( (i_value < i_min) || (i_value > i_max) ) /* range error */
- {
- intf_ErrMsg("intf error: range error ('%s' should be an integer between %ld and %ld)\n",
- psz_param, i_min, i_max );
- *pi_err = EINVAL;
- return( 0 );
- }
- *pi_err = 0;
- return( i_value );
-}
/*******************************************************************************
* InitSignalHandler: system signal handler initialization
*******************************************************************************
*******************************************************************************/
static void InitSignalHandler( void )
{
- /* Termination signals */
- signal( SIGHUP, SignalHandler );
- signal( SIGINT, SignalHandler );
- signal( SIGQUIT, SignalHandler );
+ /* Termination signals */
+ signal( SIGHUP, SignalHandler );
+ signal( SIGINT, SignalHandler );
+ signal( SIGQUIT, SignalHandler );
}
/*******************************************************************************
* SignalHandler: system signal handler
*******************************************************************************
- * This function is called when a signal is received by the program. It ignores
- * it or tries to terminate cleanly.
+ * This function is called when a signal is received by the program. It tries to
+ * end the program in a clean way.
*******************************************************************************/
static void SignalHandler( int i_signal )
{
- /* Once a signal has been trapped, the signal handler needs to be re-armed on
- * linux systems */
- signal( i_signal, SignalHandler );
+ /* Once a signal has been trapped, the termination sequence will be armed and
+ * following signals will be ignored to avoid sending messages to an interface
+ * having been destroyed */
+ signal( SIGHUP, SIG_IGN );
+ signal( SIGINT, SIG_IGN );
+ signal( SIGQUIT, SIG_IGN );
+
+ /* Acknowledge the signal received */
+ intf_ErrMsgImm("intf: signal %d received\n", i_signal );
+
+ /* Try to terminate everything - this is done by requesting the end of the
+ * interface thread */
+ p_main->p_intf->b_die = 1;
+}
+
- /* Acknowledge the signal received */
- intf_ErrMsgImm("intf: signal %d received\n", i_signal );
- /* Try to terminate everything */
- /* ?? this probably needs to be changed */
- p_program_data->intf_thread.b_die = 1;
-}
+++ /dev/null
-/*******************************************************************************
- * xconsole.c: X11 console for interface
- * (c)1998 VideoLAN
- *******************************************************************************
- * The X11 console is a simple way to get interactive input from the user. It
- * does not disturbs the standard terminal output. In theory, multiple consoles
- * could be opened on different displays.
- * The console has 2 parts: a multi-line display on top, able to display
- * messages, and an input line at bottom.
- *******************************************************************************/
-
-/* ?? todo: background color, color lines, pixmaps in front of line,
- * multiple fonts, control-like implementation, mouse management (copy/paste)...
- * add a scroller to text zone
- * It will probably be better to use something esier to use than plain xlib.
- *
- * There is no prompt yet since a pixmap would be sexier as a text prompt :)
- * issue beeps (using audio_output, of course) on 'errors' (eol, end of history
- * browse, ...)
- * remove dups from history */
-
-/*******************************************************************************
- * Preamble
- *******************************************************************************/
-#include <errno.h>
-#include <keysym.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/xpm.h>
-
-#include "config.h"
-#include "common.h"
-#include "mtime.h"
-#include "vlc_thread.h"
-#include "xutils.h"
-
-#include "xconsole.h"
-#include "intf_msg.h"
-#include "intf_cmd.h"
-
-/*
- * Local prototypes
- */
-static int CreateXConsoleWindow ( xconsole_t *p_console );
-static void DestroyXConsoleWindow ( xconsole_t *p_console );
-static void PrintXConsoleLine ( xconsole_t *p_console, int i_line,
- char *psz_str );
-static void RedrawXConsoleText ( xconsole_t *p_console );
-static void RedrawXConsoleEdit ( xconsole_t *p_console );
-static void RegisterXConsoleHistory ( xconsole_t *p_console );
-static void RecallXConsoleHistory ( xconsole_t *p_console, int i_index );
-
-/*******************************************************************************
- * intf_OpenXConsole: open console
- *******************************************************************************
- * This function try to open an X11 display and create a simple text window.
- * It returns 0 on success.
- *******************************************************************************/
-int intf_OpenXConsole( xconsole_t *p_console )
-{
- int i_index; /* all purposes index */
-
- /* Open display */
- p_console->psz_display = XDisplayName( p_console->psz_display );
- p_console->p_display = XOpenDisplay( p_console->psz_display );
- if( !p_console->p_display ) /* error */
- {
- intf_ErrMsg("intf error: can't open display %s\n",
- p_console->psz_display );
- return( -1 );
- }
-
- /* Get the screen number */
- p_console->i_screen = DefaultScreen( p_console->p_display );
-
- /* Create window and set console attributes */
- if( CreateXConsoleWindow( p_console ) ) /* error */
- {
- XFreeFont( p_console->p_display, p_console->p_font ); /* free font */
- XCloseDisplay( p_console->p_display ); /* close display */
- return( 1 ); /* return error code */
- }
-
- /* Set all text as empty */
- for( i_index = 0; i_index < INTF_XCONSOLE_MAX_LINES; i_index++ )
- {
- p_console->psz_text[i_index] = 0; /* clear the line */
- }
- p_console->i_text_index = 0;
-
- /* Clear edit line and history */
- for( i_index = 0; i_index < INTF_XCONSOLE_HISTORY_SIZE; i_index++ )
- {
- p_console->psz_history[i_index] = 0; /* clear the line */
- }
- p_console->i_history_index = 0;
- p_console->i_history_base = 0;
- p_console->i_edit_index = 0;
- p_console->i_edit_size = 0;
-
- /* Print welcome message */
- intf_PrintXConsole( p_console, INTF_XCONSOLE_WELCOME_MSG );
-
- intf_DbgMsg("intf debug: X11 console %p opened\n", p_console );
- return( 0 );
-}
-
-/*******************************************************************************
- * intf_CloseXConsole: close console (ok ?)
- *******************************************************************************
- * Destroy a console window and close the display. This function should be
- * called when the interface thread ends, and any further access to this console
- * is vorbidden.
- *******************************************************************************/
-void intf_CloseXConsole( xconsole_t *p_console )
-{
- int i_index; /* all purposes index */
-
- /* Destroy history */
- for( i_index = 0; i_index < INTF_XCONSOLE_HISTORY_SIZE; i_index++ )
- {
- if( p_console->psz_history[i_index] ) /* history line isn't empty */
- {
- free( p_console->psz_history[i_index] ); /* free the line */
- }
- }
-
- /* Destroy text */
- for( i_index = 0; i_index < INTF_XCONSOLE_MAX_LINES; i_index++ )
- {
- if( p_console->psz_text[i_index] ) /* line isn't empty */
- {
- free( p_console->psz_text[i_index] ); /* free the line */
- }
- }
-
- /* Destroy window and resources */
- DestroyXConsoleWindow( p_console );
-
- /* Close display */
- XSetErrorHandler( NULL ); /* ?? reset non-fatal error handler */
- XSetIOErrorHandler( NULL ); /* ?? reset IO error handler */
- XCloseDisplay( p_console->p_display ); /* close display */
-
- intf_DbgMsg("intf debug: X11 console %p closed\n", p_console );
-}
-
-/*******************************************************************************
- * intf_ManageXConsole: manage X11 console events
- *******************************************************************************
- * This function manage events received in X11 console such as key pressed,
- * messages received, and so on... It also run commands typed in the console.
- *******************************************************************************/
-void intf_ManageXConsole( xconsole_t *p_console )
-{
- XEvent x_event; /* generic event */
- char x_char; /* keyboard event character */
- KeySym keysym; /* keysym */
- int i_index; /* multi purpose index */
- int i_next_index; /* next history index */
-
- /* If window has been resized, update attributes and redraw */
- while( XCheckTypedEvent( p_console->p_display, ConfigureNotify, &x_event ) )
- {
- /* ?? check if move, expose or resize !!! */
- p_console->i_width = ((XConfigureEvent *) &x_event)->width;
- p_console->i_height = ((XConfigureEvent *) &x_event)->height;
- RedrawXConsoleText( p_console );
- RedrawXConsoleEdit( p_console );
- XFlush( p_console->p_display );
- }
-
- /* Check keyboard events */
- while( XCheckTypedEvent( p_console->p_display, KeyPress, &x_event ) )
- {
- /* If XLookupString returns a single character, the key is probably an
- * ascii character and is added to the edit line, except if it is a
- * control character (ascii < 32) or DEL (ascii = 127) */
- if( (XLookupString( (XKeyEvent *) &x_event, &x_char, 1, &keysym, 0 ) == 1)
- && ( x_char >= 32 ) && ( x_char != 127 ) )
- {
- /* Increase line size, except if maximal size has been reached */
- if( ++p_console->i_edit_size > INTF_XCONSOLE_MAX_LINE_WIDTH )
- {
- /* Maximal size reached */
- p_console->i_edit_size = INTF_XCONSOLE_MAX_LINE_WIDTH;
- }
-
- /* Shift right line from cursor position to the end of line */
- for( i_index = p_console->i_edit_size - 1; i_index > p_console->i_edit_index; i_index-- )
- {
- p_console->sz_edit[i_index] = p_console->sz_edit[i_index - 1];
- }
-
- /* Insert character at the cursor position and increase cursor position,
- * except if the cursor reached the right of the line */
- if( p_console->i_edit_index < INTF_XCONSOLE_MAX_LINE_WIDTH )
- {
- p_console->sz_edit[p_console->i_edit_index++] = x_char;
- }
- }
- /* Else, the key is a control key, and keysym is used to process it. */
- else
- {
- switch( keysym )
- {
- /* Cursor position modification */
- case XK_Delete: /* Delete */
- /* Delete has effect only if cursor is not at the end of the line */
- if( p_console->i_edit_index < p_console->i_edit_size )
- {
- /* Shift left line from cursor position (excluded) to the end of line */
- for( i_index = p_console->i_edit_index + 1; i_index < p_console->i_edit_size; i_index++ )
- {
- p_console->sz_edit[i_index - 1] = p_console->sz_edit[i_index];
- }
- /* Decrease line size */
- p_console->i_edit_size--;
- }
- break;
- case XK_BackSpace: /* BackSpace */
- /* BackSpace has effect only if cursor is not at the beginning of the line */
- if( p_console->i_edit_index > 0 )
- {
- /* Shift left line from cursor position (included) to the end of line */
- for( i_index = p_console->i_edit_index; i_index < p_console->i_edit_size; i_index++ )
- {
- p_console->sz_edit[i_index - 1] = p_console->sz_edit[i_index];
- }
- /* Decrease line size and cursor position */
- p_console->i_edit_size--;
- p_console->i_edit_index--;
- }
- break;
- case XK_Left: /* Left */
- /* Move left */
- if( --p_console->i_edit_index < 0 )
- {
- p_console->i_edit_index = 0;
- }
- break;
- case XK_Right: /* Right */
- /* Move right */
- if( ++p_console->i_edit_index > p_console->i_edit_size )
- {
- p_console->i_edit_index = p_console->i_edit_size;
- }
- break;
- case XK_Home: /* Home */
- /* Go to beginning of line */
- p_console->i_edit_index = 0;
- break;
- case XK_End: /* End */
- /* Go to end of line */
- p_console->i_edit_index = p_console->i_edit_size;
- break;
-
- /* Clear */
- case XK_Escape:
- /* Clear line and reset history index and record */
- p_console->i_edit_index = 0;
- p_console->i_edit_size = 0;
- p_console->i_history_index = p_console->i_history_base;
- break;
-
- /* History */
- case XK_Up:
- /* If history index is history base, this marks the beginning of
- * an history browse, and the current edited line needs to be
- * registered */
- if( p_console->i_history_index == p_console->i_history_base )
- {
- RegisterXConsoleHistory( p_console );
- }
-
- /* Calculate next index */
- if( p_console->i_history_index )
- {
- i_next_index = p_console->i_history_index - 1;
- }
- else
- {
- i_next_index = INTF_XCONSOLE_HISTORY_SIZE - 1;
- }
-
- /* Go to previous record, if it not blank and a loop hasn't been made */
- if( (i_next_index != p_console->i_history_base) && p_console->psz_history[i_next_index] )
- {
- RecallXConsoleHistory( p_console, i_next_index );
- }
- break;
- case XK_Down:
- /* If history index is not history base, Calculate next index */
- if( p_console->i_history_index != p_console->i_history_base )
- {
- /* Calculate next index */
- if( p_console->i_history_index == INTF_XCONSOLE_HISTORY_SIZE - 1 )
- {
- i_next_index = 0;
- }
- else
- {
- i_next_index = p_console->i_history_index + 1;
- }
-
- /* Go to previous record */
- RecallXConsoleHistory( p_console, i_next_index );
- }
- break;
-
- /* Command execution */
- case XK_Return:
- /* Command is executed only if line is not empty */
- if( p_console->i_edit_size )
- {
- /* Add current line to history and increase history base. The
- * called function also add a terminal '\0' to sz_edit, which
- * allow to send it without furhter modification to execution. */
- RegisterXConsoleHistory( p_console );
- if( ++p_console->i_history_base > INTF_XCONSOLE_HISTORY_SIZE )
- {
- p_console->i_history_base = 0;
- }
-
- /* Execute command */
- intf_ExecCommand( p_console->sz_edit );
-
- /* Clear line and reset history index */
- p_console->i_edit_index = 0;
- p_console->i_edit_size = 0;
- p_console->i_history_index = p_console->i_history_base;
- }
- break;
- }
- }
-
- /* Redraw edit zone */
- RedrawXConsoleEdit( p_console );
- XFlush( p_console->p_display );
- }
-}
-
-/*******************************************************************************
- * intf_ClearXConsole: clear all lines in an X11 console (ok ?)
- *******************************************************************************
- * This function clears a X11 console, destroying all its text. The input
- * line is not reset.
- *******************************************************************************/
-void intf_ClearXConsole( xconsole_t *p_console )
-{
- int i_index; /* all purposes index */
-
- /* Clear all lines - once a line has been cleared, it's data pointer
- * must be set to 0 to avoid clearing it again. */
- for( i_index = 0; i_index < INTF_XCONSOLE_MAX_LINES; i_index++ )
- {
- if( p_console->psz_text[i_index] )
- {
- free( p_console->psz_text[i_index] );
- p_console->psz_text[i_index] = 0;
- }
- }
-
- /* Redraw the window */
- RedrawXConsoleText( p_console );
- XFlush( p_console->p_display );
-}
-
-/*******************************************************************************
- * intf_PrintXConsole: print a message in a X11 console (ok ?)
- *******************************************************************************
- * This function print a message in an X11 console window. On error, it prints
- * an error message and exit. The message is processed and copied and can be
- * freed once the function has been called. During processing, the string can
- * be splitted in several lines if '\n' are encountered or if a line is larger
- * than INTF_XCONSOLE_MAX_LINE_WIDTH. A trailing '\n' will be ignored.
- *******************************************************************************/
-void intf_PrintXConsole( xconsole_t *p_console, char *psz_str )
-{
- char sz_line_buffer[INTF_XCONSOLE_MAX_LINE_WIDTH + 1]; /* buffer */
- char * psz_index; /* string index */
- int i_char_index; /* char index in line */
- boolean_t b_eol; /* end of line flag */
-
- /* Split the string in different lines. A line */
- i_char_index = 0; /* character 0 */
- b_eol = 0;
- for( psz_index = psz_str; *psz_index; psz_index++ )
- {
- /* Check if we reached an end of line: if the current character is
- * really an end of line or if the next one marks the end of the
- * string. An end of line at then end of a string will be only
- * processed once. */
- if( (*psz_index == '\n') || ( psz_index[1] == '\0' ) )
- {
- b_eol = 1;
- }
- /* Else, the current character is added at the end of the line buffer */
- {
- sz_line_buffer[ i_char_index++ ] = *psz_index;
- /* If we reached the maximal size for the line buffer, we also need
- * to treat the end of line */
- if( i_char_index == INTF_XCONSOLE_MAX_LINE_WIDTH )
- {
- b_eol = 1;
- }
- }
-
- /* Check if an end of line has been detected */
- if( b_eol )
- {
- /* Add a '\0' character at the end of the line buffer - note that
- * i_char_index is now the line size + 1. */
- sz_line_buffer[ i_char_index++ ] = '\0';
-
- /* Increase line index */
- if( p_console->i_text_index++ /* loop */
- == INTF_XCONSOLE_MAX_LINES )
- {
- p_console->i_text_index = 0;
- }
- /* If there was a line in the current location, it needs to be
- * erased. It will disappear from the console messages history. */
- if( p_console->psz_text[ p_console->i_text_index] )
- {
- free( p_console->psz_text[ p_console->i_text_index] );
- }
-
- /* Allocate memory in lines array, and copy string - a memcpy is used
- * since the size of the string is already known. On error during the
- * allocation (ENOMEM), the line is set as blank and an error message
- * is issued. */
- p_console->psz_text[ p_console->i_text_index ]
- = (char *) malloc( sizeof(char) * i_char_index );
- if( !p_console->psz_text[ p_console->i_text_index] ) /* error */
- {
- intf_ErrMsg("intf error: can't copy `%s' (%s)\n",
- sz_line_buffer, strerror(ENOMEM) );
- p_console->psz_text[ p_console->i_text_index] = 0;
- }
- else /* success */
- {
- memcpy( p_console->psz_text[ p_console->i_text_index ],
- sz_line_buffer, i_char_index );
- }
-
- /* Reset end of line indicator and char index */
- b_eol = 0;
- i_char_index = 0;
- }
- }
-
- /* Display lines */
- /* ?? now: redraw... would be better to scroll and draw only the good one */
- RedrawXConsoleText( p_console );
- XFlush( p_console->p_display );
-}
-
-/* following functions are local */
-
-/*******************************************************************************
- * RegisterXConsoleHistory: send current edit line to history (ok ?)
- *******************************************************************************
- * This function add a '\0' termination character at the end of the editing
- * buffer, and copy it to the actual history base. If there is already a
- * command registered at this place, it is removed.
- * Note that the base index isn't updated.
- * If there is not enough memory to allocate history record, the previous
- * record is still cleared, and the new one is left blank. Note that this will
- * probably cause problems when the history will be browsed, since the line
- * won't be able to be recovered.
- *******************************************************************************/
-static void RegisterXConsoleHistory( xconsole_t *p_console )
-{
- /* Add a null character to mark the end of the edit line */
- p_console->sz_edit[p_console->i_edit_size] = '\0';
-
- /* Free current history record if required */
- if( p_console->psz_history[p_console->i_history_base] )
- {
- free( p_console->psz_history[p_console->i_history_base] );
- }
-
- /* Allocate memory */
- p_console->psz_history[p_console->i_history_base]
- = (char *) malloc( sizeof(char) * ( p_console->i_edit_size + 1 ) );
-
- /* On error, an error message is issued and the line is left blank */
- if( !p_console->psz_history[p_console->i_history_base] ) /* error */
- {
- intf_ErrMsg("intf error: can't register `%s' in history\n", p_console->sz_edit );
- p_console->psz_history[p_console->i_history_base] = 0;
- }
- /* If the allocation succeeded, the line is copied. Memcpy is used rather than
- * strcpy because the line size is already known. */
- else
- {
- memcpy( p_console->psz_history[p_console->i_history_base],
- p_console->sz_edit, p_console->i_edit_size + 1 );
- }
-}
-
-/*******************************************************************************
- * RecallXConsoleHistory: copy an historic record to edit line (ok ?)
- *******************************************************************************
- * This function copy an historic record to edit line and update historic
- * index.
- *******************************************************************************/
-static void RecallXConsoleHistory( xconsole_t *p_console, int i_index )
-{
- /* Calculate line size and copy it to edit line */
- for( p_console->i_edit_size = 0;
- p_console->psz_history[i_index][p_console->i_edit_size];
- p_console->i_edit_size++ )
- {
- p_console->sz_edit[p_console->i_edit_size] = p_console->psz_history[i_index][p_console->i_edit_size];
- }
-
- /* Update indexes */
- p_console->i_history_index = i_index;
- p_console->i_edit_index = p_console->i_edit_size;
-}
-
-
-/*******************************************************************************
- * CreateXConsoleWindow: open and set-up X11 console window (ok ?)
- *******************************************************************************
- * This function tries to create and set up a console window. This window is
- * resizeable.
- *******************************************************************************/
-static int CreateXConsoleWindow( xconsole_t *p_console )
-{
- XSizeHints xsize_hints;
- XSetWindowAttributes xwindow_attributes;
- XGCValues xgcvalues;
- int i_dummy; /* dummy for geometry */
-
- /* Load first (edit) font - some of its properties are required to adapt
- * window properties */
- if( XTryLoadFont( p_console->p_display, INTF_XCONSOLE_FONT, &p_console->p_font ) )
- {
- return( 1 );
- }
-
- /* Set size related console properties */
- p_console->i_edit_height = p_console->p_font->ascent + p_console->p_font->descent + 5;
- p_console->i_edit_offset = p_console->p_font->descent + 2;
- p_console->i_text_offset = p_console->i_edit_height + p_console->p_font->descent;
- p_console->i_text_line_height = p_console->p_font->ascent + p_console->p_font->descent;
-
- /* Read window geometry and prepare size hints */
- XParseGeometry( p_console->psz_geometry,
- &i_dummy, &i_dummy, &p_console->i_width, &p_console->i_height );
- xsize_hints.base_width = p_console->i_height;
- xsize_hints.base_height = p_console->i_width;
- xsize_hints.min_width = p_console->i_text_line_height;
- xsize_hints.min_height = p_console->i_text_line_height;
- xsize_hints.flags = PSize | PMinSize;
-
- /* Prepare the window attributes */
- xwindow_attributes.backing_store = Always;
- xwindow_attributes.background_pixel = WhitePixel( p_console->p_display, p_console->i_screen );
- xwindow_attributes.event_mask = KeyPressMask | StructureNotifyMask;
-
- /* Create the window */
- p_console->window = XCreateWindow( p_console->p_display,
- DefaultRootWindow( p_console->p_display ),
- 0, 0, p_console->i_width, p_console->i_height, 0,
- CopyFromParent, InputOutput, CopyFromParent,
- CWBackingStore | CWBackPixel | CWEventMask,
- &xwindow_attributes );
- XSetWMNormalHints( p_console->p_display, p_console->window, &xsize_hints );
- XStoreName(p_console->p_display, p_console->window, INTF_XCONSOLE_TITLE);
-
- /* Creation of a graphic contexts */
- xgcvalues.background = WhitePixel( p_console->p_display, p_console->i_screen );
- xgcvalues.foreground = BlackPixel( p_console->p_display, p_console->i_screen );
- p_console->default_gc = XCreateGC( p_console->p_display, p_console->window,
- GCForeground | GCBackground,
- &xgcvalues);
-
-/* ?? pixmap is always freed, etc... -> to be fixed ! */
-#ifdef INTF_XCONSOLE_BACKGROUND_PIXMAP
- /* Load background pixmap */
- if( XpmReadFileToPixmap( p_console->p_display, /* error */
- p_console->window, INTF_XCONSOLE_BACKGROUND_PIXMAP,
- &p_console->background_pixmap, NULL, NULL) )
- {
- intf_ErrMsg("intf error: can't load background pixmap `%s'\n",
- INTF_XCONSOLE_BACKGROUND_PIXMAP );
- }
- else /* success */
- {
- /* Set window background */
- XSetWindowBackgroundPixmap(p_console->p_display, p_console->window,
- p_console->background_pixmap );
- }
-#endif
-
- /* Map the window */
- XMapWindow( p_console->p_display, p_console->window ); /* map */
- XFlush( p_console->p_display );
-
- return( 0 );
-}
-
-/*******************************************************************************
- * DestroyXConsoleWindow: destroy console window (ok ?)
- *******************************************************************************
- * Destroy a console window opened by CreateXConsoleWindow.
- *******************************************************************************/
-static void DestroyXConsoleWindow( xconsole_t *p_console )
-{
- /* Unmap window */
- XUnmapWindow( p_console->p_display, p_console->window );
-
- /* Destroy graphic contexts */
- XFreeGC( p_console->p_display, p_console->default_gc );
-
- /* Free pixmaps */
- XFreePixmap( p_console->p_display, p_console->background_pixmap );
-
- /* Free font */
- XFreeFont( p_console->p_display, p_console->p_font );
-
- /* Destroy window */
- XDestroyWindow( p_console->p_display, p_console->window );
-}
-
-/*******************************************************************************
- * PrintXConsoleLine: print a message in console (ok ?)
- *******************************************************************************
- * Print a message in console. Line 0 is just above the edit line, and line
- * number increase while going up. The string is scanned for control
- * characters.
- *******************************************************************************/
-static void PrintXConsoleLine( xconsole_t *p_console, int i_line, char *psz_str )
-{
- XTextItem textitem[INTF_XCONSOLE_MAX_LINE_WIDTH]; /* text */
- int i_nb_textitems; /* total number of textitems */
-
- int i_x; /* horizontal position */
- int i_y; /* base vertical position */
-
- /* If string is a null pointer, return */
- if( !psz_str )
- {
- return;
- }
-
- /* Prepare array of textitems */
- for( i_nb_textitems = 0;
- *psz_str && (i_nb_textitems < INTF_XCONSOLE_MAX_LINE_WIDTH);
- i_nb_textitems++ )
- {
- /* Check if first character is a control character - if a control
- * character has been successfully processed, process next one */
- while( *psz_str == '\033' )
- {
- psz_str++;
- switch( *psz_str )
- {
- case 'g': /* bell */
- /* ?? ring bell */
- psz_str++;
- break;
-
- case '\0': /* error: end of string */
- /* Print error message */
- intf_ErrMsg("intf error: unauthorized control character `\\0'\n");
- break;
-
- default: /* error: unknown control character */
- /* Print error message */
- intf_ErrMsg("intf error: unknown control character `%c'\n", *psz_str );
- break;
- }
- }
-
- /* Prepare textitem */
- textitem[i_nb_textitems].chars = psz_str;
- textitem[i_nb_textitems].nchars = 0;
- textitem[i_nb_textitems].delta = 0;
- textitem[i_nb_textitems].font = p_console->p_font->fid;
-
- /* Reach next control character or end of string */
- do
- {
- psz_str++;
- textitem[i_nb_textitems].nchars++;
- }while( *psz_str && (*psz_str != '\033') );
- }
-
- /* Calulcate base position */
- i_x = 0;
- i_y = p_console->i_height - p_console->i_text_offset - i_line * p_console->i_text_line_height;
-
- /* Print text */
- XDrawText( p_console->p_display, p_console->window, p_console->default_gc, i_x, i_y,
- textitem, i_nb_textitems );
-}
-
-/*******************************************************************************
- * RedrawXConsoleEdit: redraw console edit zone (ok ?)
- *******************************************************************************
- * This function redraw just the edit zone of the console. It has to be called
- * when the window is resized.
- *******************************************************************************/
-static void RedrawXConsoleEdit( xconsole_t *p_console )
-{
- XTextItem textitem; /* text */
- int i_x; /* cursor position */
-
- /* Clear window edit zone */
- XClearArea( p_console->p_display, p_console->window, 0,
- p_console->i_height - p_console->i_edit_height,
- p_console->i_width, p_console->i_edit_height, False );
-
- /* Draw separation line */
- XDrawLine( p_console->p_display, p_console->window, p_console->default_gc,
- 0, p_console->i_height - p_console->i_edit_height,
- p_console->i_width, p_console->i_height - p_console->i_edit_height );
-
- /* Prepare text to be printed */
- textitem.chars = p_console->sz_edit;
- textitem.nchars = p_console->i_edit_size;
- textitem.delta = 0;
- textitem.font = p_console->p_font->fid;
-
- /* Print text */
- XDrawText( p_console->p_display, p_console->window, p_console->default_gc,
- 0, p_console->i_height - p_console->i_edit_offset,
- &textitem, 1 );
-
- /* Get cursor position */
- i_x = XTextWidth( p_console->p_font, p_console->sz_edit, p_console->i_edit_index );
-
- /* Print cursor. Cursor is placed at the beginning of the edited character,
- * and it's size is calculated from maximal character size in the font. */
- XDrawLine( p_console->p_display, p_console->window, p_console->default_gc,
- i_x, p_console->i_height - p_console->i_edit_offset - p_console->p_font->ascent,
- i_x, p_console->i_height - p_console->i_edit_offset + p_console->p_font->descent );
-}
-
-/*******************************************************************************
- * RedrawXConsoleText: redraw console text zone (ok ?)
- *******************************************************************************
- * This function redraw all lines in the console. It has to be called when
- * the window is resized.
- *******************************************************************************/
-static void RedrawXConsoleText( xconsole_t *p_console )
-{
- int i_line; /* current line */
- int i_index; /* multi-purposes index */
- int i_maxline; /* maximum line number */
-
- /* Clear window text zone */
- XClearArea( p_console->p_display, p_console->window, 0, 0, p_console->i_width,
- p_console->i_height - p_console->i_edit_height, False );
-
- /* Get maximum line number from window height */
- i_maxline = (p_console->i_height - p_console->i_text_offset)
- / p_console->i_text_line_height;
-
- /* Re-print messages zone: start from first message, line 0 and print
- * messages until top of window is reached or all lines have been printed,
- * which happens when i_index is the start index again */
- i_line = 0;
- i_index = p_console->i_text_index;
- do
- {
- /* Print line */
- PrintXConsoleLine( p_console, i_line, p_console->psz_text[i_index] );
-
- /* Decrease i_index. Note that lines must be printed in reverse order
- * since they are added in order. */
- if( !i_index-- ) /* loop */
- {
- i_index = INTF_XCONSOLE_MAX_LINES - 1;
- }
- }
- while( (i_line++ < i_maxline) && (i_index != p_console->i_text_index) );
-}
/*******************************************************************************
* Preamble
*******************************************************************************/
+#include "vlc.h"
+
+/*#include <errno.h>
+#include <pthread.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include "vlc_thread.h"
#include "intf_msg.h"
-#include "debug.h" /* ?? temporaire, requis par netlist.h */
+#include "debug.h"
#include "input.h"
#include "input_netlist.h"
#include "decoder_fifo.h"
#include "video.h"
#include "video_output.h"
+#include "video_decoder.h"*/
+
#include "vdec_idct.h"
#include "video_decoder.h"
--- /dev/null
+/*******************************************************************************
+ * vout_x11.c: X11 video output display method
+ * (c)1998 VideoLAN
+ *******************************************************************************
+ * The X11 method for video output thread. It's properties (and the vout_x11_t
+ * type) are defined in vout.h. The functions declared here should not be
+ * needed by any other module than vout.c.
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Preamble
+ *******************************************************************************/
+
+#include "vlc.h"
+/*
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <sys/shm.h>
+#include <sys/soundcard.h>
+#include <sys/uio.h>
+
+
+#include "config.h"
+#include "common.h"
+#include "mtime.h"
+#include "vlc_thread.h"
+#include "xutils.h"
+
+#include "input.h"
+#include "input_vlan.h"
+
+#include "audio_output.h"
+
+#include "video.h"
+#include "video_output.h"
+#include "video_sys.h"
+
+#include "xconsole.h"
+#include "interface.h"
+#include "intf_msg.h"
+*/
+
+/*******************************************************************************
+ * vout_sys_t: video output framebuffer method descriptor
+ *******************************************************************************
+ * This structure is part of the video output thread descriptor.
+ * It describes the FB specific properties of an output thread. FB video
+ * output is performed through regular resizable windows. Windows can be
+ * dynamically resized to adapt to the size of the streams.
+ *******************************************************************************/
+typedef struct vout_sys_s
+{
+ int i_dummy;
+
+} vout_sys_t;
+
+/*******************************************************************************
+ * Local prototypes
+ *******************************************************************************/
+
+
+/*******************************************************************************
+ * vout_SysCreate: allocate X11 video thread output method
+ *******************************************************************************
+ * This function allocate and initialize a X11 vout method.
+ *******************************************************************************/
+int vout_SysCreate( vout_thread_t *p_vout )
+{
+ p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
+ if( p_vout->p_sys != NULL )
+ {
+ //??
+ return( 0 );
+ }
+
+ return( 1 );
+}
+
+/*******************************************************************************
+ * vout_SysInit: initialize Sys video thread output method
+ *******************************************************************************
+ * This function create a Sys window according to the user configuration.
+ *******************************************************************************/
+int vout_SysInit( vout_thread_t *p_vout )
+{
+ //??
+ intf_DbgMsg("%p -> success, depth=%d bpp",
+ p_vout, p_vout->i_screen_depth );
+ return( 0 );
+}
+
+/*******************************************************************************
+ * vout_SysEnd: terminate Sys video thread output method
+ *******************************************************************************
+ * Terminate an output method created by vout_SysCreateOutputMethod
+ *******************************************************************************/
+void vout_SysEnd( vout_thread_t *p_vout )
+{
+ intf_DbgMsg("%p\n", p_vout );
+ //??
+}
+
+/*******************************************************************************
+ * vout_SysDestroy: destroy Sys video thread output method
+ *******************************************************************************
+ * Terminate an output method created by vout_SysCreateOutputMethod
+ *******************************************************************************/
+void vout_SysDestroy( vout_thread_t *p_vout )
+{
+ //??
+ free( p_vout->p_sys );
+}
+
+/*******************************************************************************
+ * vout_SysManage: handle Sys events
+ *******************************************************************************
+ * This function should be called regularly by video output thread. It manages
+ * Sys events and allows window resizing. It returns a negative value if
+ * something happened which does not allow the thread to continue, and a
+ * positive one if the thread can go on, but the images have been modified and
+ * therefore it is useless to display them.
+ *******************************************************************************
+ * Messages type: vout, major code: 103
+ *******************************************************************************/
+int vout_SysManage( vout_thread_t *p_vout )
+{
+ //??
+
+ return( 0 );
+}
+
+/*******************************************************************************
+ * vout_SysDisplay: displays previously rendered output
+ *******************************************************************************
+ * This function send the currently rendered image to Sys server, wait until
+ * it is displayed and switch the two rendering buffer, preparing next frame.
+ *******************************************************************************/
+void vout_SysDisplay( vout_thread_t *p_vout )
+{
+ //??
+
+ /* Swap buffers */
+//?? p_vout->p_sys->i_buffer_index = ++p_vout->p_sys->i_buffer_index & 1;
+}
+
+++ /dev/null
-/*******************************************************************************
- * video_graphics.c: pictures manipulation functions
- * (c)1999 VideoLAN
- *******************************************************************************
- * Includes function to compose, convert and display pictures, and also basic
- * functions to copy/convert pictures data or descriptors and read pictures
- * from a file.
- *******************************************************************************/
-
-/*******************************************************************************
- * Preamble
- *******************************************************************************/
-
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <netinet/in.h>
-
-#include "common.h"
-#include "config.h"
-#include "mtime.h"
-
-#include "video.h"
-#include "video_graphics.h"
-
-#include "intf_msg.h"
-
-/*
- * Local prototypes
- */
-static int ReadPictureConfiguration ( int i_file, video_cfg_t *p_cfg );
-
-/*******************************************************************************
- * video_CreatePicture: create an empty picture
- *******************************************************************************
- * This function create an empty image. A null pointer is returned if the
- * function fails.
- * Following configuration properties are used:
- * VIDEO_CFG_WIDTH picture width (required)
- * VIDEO_CFG_HEIGHT picture height (required)
- * VIDEO_CFG_TYPE picture type (required)
- * VIDEO_CFG_FLAGS flags
- * VIDEO_CFG_BPP padded bpp (required for pixel pictures)
- * VIDEO_CFG_POSITION position in output window
- * VIDEO_CFG_ALIGN base position in output window
- * VIDEO_CFG_RATIO display ratio
- * VIDEO_CFG_LEVEL overlay hierarchical level
- * VIDEO_CFG_REFCOUNT links reference counter
- * VIDEO_CFG_STREAM video stream id
- * VIDEO_CFG_DATE display date
- * VIDEO_CFG_DURATION duration for overlay pictures
- * VIDEO_CFG_PIXEL pixel value for mask pictures
- * VIDEO_CFG_DATA picture data (required if not owner and non blank)
- *******************************************************************************/
-picture_t *video_CreatePicture( video_cfg_t *p_cfg )
-{
- picture_t *p_newpic; /* new picture descriptor */
-
-#ifdef DEBUG
- /* Check base configuration */
- if( (p_cfg->i_properties & (VIDEO_CFG_WIDTH | VIDEO_CFG_HEIGHT | VIDEO_CFG_TYPE))
- != (VIDEO_CFG_WIDTH | VIDEO_CFG_HEIGHT | VIDEO_CFG_TYPE) )
- {
- intf_DbgMsg("invalid picture configuration\n");
- return( NULL );
- }
- /* Check flags validity */
- if( (p_cfg->i_properties & VIDEO_CFG_FLAGS)
- && (p_cfg->i_flags & ( RESERVED_PICTURE | DISPLAYED_PICTURE
- | DISPLAY_PICTURE | DESTROY_PICTURE )) )
- {
- intf_DbgMsg("invalid picture flags\n");
- return( NULL );
- }
-#endif
-
- /* Allocate descriptor */
- p_newpic = malloc( sizeof(picture_t) );
- if( !p_newpic ) /* error: malloc() failed */
- {
- return( NULL );
- }
-
- /* Create picture */
- if( video_CreatePictureBody( p_newpic, p_cfg ) ) /* error */
- {
- free( p_newpic );
- return( NULL );
- }
-
- /* Log and return */
-#ifdef VOUT_DEBUG /* ?? -> video_debug ? */
- video_PrintPicture( p_newpic, "video: created picture " );
-#else
- intf_DbgMsg("created picture %dx%d at %p\n", p_newpic->i_width, p_newpic->i_height, p_newpic);
-#endif
- return( p_newpic );
-}
-
-/*******************************************************************************
- * video_CopyPicture: create a copy of a picture
- *******************************************************************************
- * This function creates a copy of a picture. It returns NULL on error.
- *******************************************************************************
- * Messages type: video, major code: 102
- *******************************************************************************/
-picture_t * video_CopyPicture( picture_t *p_pic )
-{
- picture_t * p_newpic; /* new picture descriptor */
-
- p_newpic = malloc( sizeof(picture_t) );
- if( p_newpic != NULL )
- {
- video_CopyPictureDescriptor( p_newpic, p_pic );
- /* If source picture owns its data, make a copy */
- if( p_pic->i_flags & OWNER_PICTURE )
- {
- p_newpic->p_data = malloc( p_pic->i_height * p_pic->i_bytes_per_line );
- if( p_newpic->p_data == NULL ) /* error */
- {
- free( p_newpic );
- return( NULL );
- }
- memcpy( p_newpic->p_data, p_pic->p_data,
- p_pic->i_height * p_pic->i_bytes_per_line );
- }
- /* If source picture does not owns its data, copy the reference */
- else
- {
- p_newpic->p_data = p_pic->p_data;
- }
- }
- return( p_newpic );
-}
-
-/*******************************************************************************
- * video_ReplicatePicture: creates a replica of a picture
- *******************************************************************************
- * This function creates a replica of the original picture. It returns NULL on
- * error.
- *******************************************************************************
- * Messages type: video, major code: 103
- *******************************************************************************/
-picture_t * video_ReplicatePicture( picture_t *p_pic )
-{
- picture_t * p_newpic; /* new picture descrpitor */
-
- p_newpic = malloc( sizeof(picture_t) );
- if( p_newpic != NULL )
- {
- video_CopyPictureDescriptor( p_newpic, p_pic );
- p_newpic->i_flags &= ~OWNER_PICTURE;
- p_newpic->p_data = p_pic->p_data;
- }
- return( p_newpic );
-}
-
-/*******************************************************************************
- * video_DestroyPicture: destroys a picture
- *******************************************************************************
- * This function destroy a picture created with any of the video_*Picture
- * functions.
- *******************************************************************************
- * Messages type: video, major code: 104
- *******************************************************************************/
-void video_DestroyPicture( picture_t *p_pic )
-{
- intf_DbgMsg("video debug 104-1: destroying picture %p\n", p_pic );
-
- /* Destroy data if picture owns it */
- if( p_pic->i_flags & OWNER_PICTURE )
- {
- free( p_pic->p_data );
- }
- /* Destroy descriptor */
- free( p_pic );
-}
-
-/*******************************************************************************
- * video_ClearPicture: clear a picture
- *******************************************************************************
- * Set all pixel to 0 (black).
- *******************************************************************************
- * Messages type: video, major code: 105
- *******************************************************************************/
-void video_ClearPicture( picture_t *p_pic )
-{
- switch( p_pic->i_type )
- {
- case RGB_BLANK_PICTURE:
- case PIXEL_BLANK_PICTURE:
- /* Blank pictures will have their pixel value set to 0 */
- p_pic->pixel = 0;
- break;
- default:
- /* All pictures types except blank ones have a meaningfull i_bytes_per_line
- * field, and blank ones don't need to be cleared. */
- memset( p_pic->p_data, 0, p_pic->i_height * p_pic->i_bytes_per_line );
- break;
- }
-}
-
-/*******************************************************************************
- * video_DrawPixel: set a pixel in a picture
- *******************************************************************************
- * This function set a pixel's value in an picture. It is an easy, but slow way
- * to render an image, and should be avoided. Exact meaning of value depends of
- * the picture type.
- *******************************************************************************
- * Messages type: video, major code: 106
- *******************************************************************************/
-void video_DrawPixel( picture_t *p_pic, int i_x, int i_y, pixel_t value )
-{
- switch( p_pic->i_type )
- {
- case RGB_PICTURE: /* 24 bits encoded RGB pictures */
- p_pic->p_data[i_y * p_pic->i_bytes_per_line + i_x * 3 ] = RGBVALUE2RED( value );
- p_pic->p_data[i_y * p_pic->i_bytes_per_line + i_x * 3 + 1] = RGBVALUE2GREEN( value );
- p_pic->p_data[i_y * p_pic->i_bytes_per_line + i_x * 3 + 2] = RGBVALUE2BLUE( value );
- break;
-
- case PIXEL_PICTURE: /* pixel encoded pictures */
- /* ?? */
- break;
-
- case RGB_MASK_PICTURE: /* 1 bpp rgb mask pictures */
- case PIXEL_MASK_PICTURE: /* 1 bpp pixel mask pictures */
- /* ?? */
- break;
-#ifdef DEBUG
- default:
- intf_DbgMsg("video debug 106-1: invalid picture %p type %d\n",
- p_pic, p_pic->i_type);
- break;
-#endif
- }
-}
-
-
-
-/*******************************************************************************
- * video_DrawHLine: draw an horizontal line in a picture
- *******************************************************************************
- *
- *******************************************************************************
- * Messages type: video, major code: 107
- *******************************************************************************/
-void video_DrawHLine( picture_t *p_pic, int i_x, int i_y, int i_width, pixel_t value )
-{
- /* ?? */
-}
-
-/*******************************************************************************
- * video_DrawVLine: draw a vertical line in a picture
- *******************************************************************************
- *
- *******************************************************************************
- * Messages type: video, major code: 108
- *******************************************************************************/
-void video_DrawVLine( picture_t *p_pic, int i_x, int i_y, int i_width, pixel_t value )
-{
- /* ?? */
-}
-
-/*******************************************************************************
- * video_DrawLine: draw a line in a picture
- *******************************************************************************
- * video_DrawHLine() and video_DrawVLine() functions should be prefered if
- * possible.
- *******************************************************************************
- * Messages type: video, major code: 109
- *******************************************************************************/
-void video_DrawLine( picture_t *p_pic, int i_x1, int i_y1, int i_x2, int i_y2, pixel_t value )
-{
- /* ?? */
-}
-
-/*******************************************************************************
- * video_DrawBar: draw a bar in a picture
- *******************************************************************************
- * Draw a bar (filled rectangle) in a picture/
- *******************************************************************************
- * Messages type: video, major code: 110
- *******************************************************************************/
-void video_DrawBar( picture_t *p_pic, int i_x, int i_y, int i_width, int i_height,
- pixel_t value )
-{
- /* ?? */
-}
-
-/*******************************************************************************
- * video_DrawRectangle: draw a rectangle in a picture
- *******************************************************************************
- * Draw a rectangle (empty) in an image
- *******************************************************************************
- * Messages type: video, major code: 111
- *******************************************************************************/
-void video_DrawRectangle( picture_t *p_pic, int i_x, int i_y,
- int i_width, int i_height, pixel_t value )
-{
- /* ?? */
-}
-
-/*******************************************************************************
- * video_DrawImage: insert a picture in another one
- *******************************************************************************
- * ??
- *******************************************************************************
- * Messages type: video, major code: 112
- *******************************************************************************/
-void video_DrawPicture( picture_t *p_pic, picture_t *p_insert, int i_x, int i_y )
-{
- /* ?? */
-}
-
-/*******************************************************************************
- * video_DrawText: insert text in a picture
- *******************************************************************************
- * This function prints a simple text in an image. It does not support
- * different fonts, or complex text settings, but is designed to provide a
- * simple way to display messages, counters and indications.
- *******************************************************************************
- * Messages type: video, major code: 113
- *******************************************************************************/
-void video_DrawText( picture_t *p_picture, int i_x, int i_y, char *psz_text,
- int i_size, pixel_t value )
-{
- /* ?? */
-}
-
-/*******************************************************************************
- * video_CopyPictureDescriptor: copy a picture descriptor
- *******************************************************************************
- * This function is used when a picture is added to the video heap. It does not
- * copy the p_data field. Some post-treatment must obviously be done, especially
- * concerning the OWNER_PICTURE flag, the i_refcount and p_data fields.
- * Although it is exported, since it is used in several of the vout_* modules,
- * it should not be used directly outside the video output module.
- *******************************************************************************
- * Messages type: video, major code 114
- *******************************************************************************/
-void video_CopyPictureDescriptor( picture_t *p_dest, picture_t *p_src )
-{
- p_dest->i_type = p_src->i_type;
- p_dest->i_flags = p_src->i_flags;
-
- p_dest->i_width = p_src->i_width;
- p_dest->i_height = p_src->i_height;
- p_dest->i_bpp = p_src->i_bpp;
- p_dest->i_bytes_per_line = p_src->i_bytes_per_line;
-
- p_dest->i_x = p_src->i_x;
- p_dest->i_y = p_src->i_y;
- p_dest->i_h_align = p_src->i_h_align;
- p_dest->i_v_align = p_src->i_v_align;
- p_dest->i_h_ratio = p_src->i_h_ratio;
- p_dest->i_v_ratio = p_src->i_v_ratio;
- p_dest->i_level = p_src->i_level;
-
- p_dest->i_refcount = p_src->i_refcount;
-
- p_dest->i_stream = p_src->i_stream;
- p_dest->date = p_src->date;
- p_dest->duration = p_src->duration;
-
- p_dest->pixel = p_src->pixel;
-}
-
-/*******************************************************************************
- * video_CreatePictureBody: create a picture in an descriptor
- *******************************************************************************
- * This function is used vy vout_CreateReservedPicture and vout_CreatePicture.
- * It should not be called directly outside the video output module.
- * It returns non 0 if the creation failed.
- *******************************************************************************
- * Messages type: video, major code 115
- *******************************************************************************/
-int video_CreatePictureBody( picture_t *p_pic, video_cfg_t *p_cfg )
-{
-#ifdef DEBUG
- /* Check base configuration */
- if( (p_cfg->i_properties & (VIDEO_CFG_WIDTH | VIDEO_CFG_HEIGHT | VIDEO_CFG_TYPE))
- != (VIDEO_CFG_WIDTH | VIDEO_CFG_HEIGHT | VIDEO_CFG_TYPE) )
- {
- intf_DbgMsg("video debug 115-1: invalid picture configuration\n");
- return( 1 );
- }
- /* Check flags validity */
- if( (p_cfg->i_properties & VIDEO_CFG_FLAGS)
- && (p_cfg->i_flags & ( RESERVED_PICTURE | DISPLAYED_PICTURE
- | DISPLAY_PICTURE | DESTROY_PICTURE )) )
- {
- intf_DbgMsg("video debug 115-2: invalid picture flags\n");
- return( 1 );
- }
-#endif
-
- /* Initialize types, flags and dimensions */
- p_pic->i_type = p_cfg->i_type;
- p_pic->i_flags = ( p_cfg->i_properties & VIDEO_CFG_FLAGS ) ? p_cfg->i_flags : 0;
- p_pic->i_width = p_cfg->i_width;
- p_pic->i_height = p_cfg->i_height;
-
- /* Initialize other pictures properties */
- if( p_cfg->i_properties & VIDEO_CFG_POSITION )
- {
- p_pic->i_x = p_cfg->i_x;
- p_pic->i_y = p_cfg->i_y;
- }
- else
- {
- p_pic->i_x = 0;
- p_pic->i_y = 0;
- }
- if( p_cfg->i_properties & VIDEO_CFG_ALIGN )
- {
- p_pic->i_h_align = p_cfg->i_h_align;
- p_pic->i_v_align = p_cfg->i_v_align;
- }
- else
- {
- p_pic->i_h_align = ALIGN_H_DEFAULT;
- p_pic->i_v_align = ALIGN_V_DEFAULT;
- }
- if( p_cfg->i_properties & VIDEO_CFG_RATIO )
- {
- p_pic->i_h_ratio = p_cfg->i_h_ratio;
- p_pic->i_v_ratio = p_cfg->i_v_ratio;
- }
- else
- {
- p_pic->i_h_ratio = DISPLAY_RATIO_NORMAL;
- p_pic->i_v_ratio = DISPLAY_RATIO_NORMAL;
- }
- p_pic->i_level = ( p_cfg->i_properties & VIDEO_CFG_LEVEL )
- ? p_cfg->i_level : ( (p_pic->i_flags & OVERLAY_PICTURE) ? 1 : 0 );
- p_pic->i_refcount = ( p_cfg->i_properties & VIDEO_CFG_REFCOUNT ) ? p_cfg->i_refcount : 0;
- p_pic->i_stream = ( p_cfg->i_properties & VIDEO_CFG_STREAM ) ? p_cfg->i_stream : 0;
- p_pic->date = ( p_cfg->i_properties & VIDEO_CFG_DATE ) ? p_cfg->date : 0;
- p_pic->duration = ( p_cfg->i_properties & VIDEO_CFG_DURATION ) ? p_cfg->duration : 0;
-
- /* Initialize type-dependant properties */
- switch( p_pic->i_type )
- {
- case RGB_BLANK_PICTURE: /* rgb blank picture */
- case PIXEL_BLANK_PICTURE: /* pixel blank picture */
-#ifdef DEBUG
- /* Check validity: blank pictures can't be transparent or owner */
- if( p_pic->i_flags & ( OWNER_PICTURE | TRANSPARENT_PICTURE ) )
- {
- intf_DbgMsg("video debug 115-3: invalid blank picture flags\n");
- return( 1 );
- }
- /* Set to 0 unused fields */
- p_pic->i_bpp = 0;
- p_pic->i_bytes_per_line = 0;
- p_pic->p_data = NULL;
-#endif
- /* Set color */
- p_pic->pixel = ( p_cfg->i_properties & VIDEO_CFG_PIXEL ) ? p_cfg->pixel : 0;
- break;
-
- case RGB_PICTURE: /* 24 bpp RGB */
-#ifdef DEBUG
- /* Set to 0 unused fields */
- p_pic->pixel = 0;
-#endif
- /* Set fields */
- p_pic->i_bpp = 24;
- p_pic->i_bytes_per_line = PAD( p_pic->i_width * 3, sizeof(int) );
- break;
-
- case PIXEL_PICTURE: /* pixel encoded picture */
-#ifdef DEBUG
- /* Check validity: pixel pictures must have the bpp property defined,
- * and it must be a multiple of 8 */
- if( ! (p_cfg->i_properties & VIDEO_CFG_BPP) )
- {
- intf_DbgMsg("video debug 115-4: missing bpp for pixel picture\n");
- return( 1 );
- }
- else if( p_cfg->i_bpp % 8 )
- {
- intf_DbgMsg("video debug 115-5: invalid bpp for pixel picture\n");
- return( 1 );
- }
-
- /* Set to 0 unused fields */
- p_pic->pixel = 0;
-#endif
- /* Set fields */
- p_pic->i_bpp = p_cfg->i_bpp;
- p_pic->i_bytes_per_line = PAD( p_pic->i_width * (p_cfg->i_bpp / 8), sizeof(int) );
- break;
-
- case RGB_MASK_PICTURE: /* 1 bpp rgb mask */
- case PIXEL_MASK_PICTURE: /* 1 bpp pixel mask */
- /* Set fields */
- p_pic->i_bpp = 1;
- p_pic->i_bytes_per_line = PAD( p_pic->i_width / 8, sizeof(int) );
- p_pic->pixel = ( p_cfg->i_properties & VIDEO_CFG_PIXEL ) ? p_cfg->pixel : 0;
- break;
-
-#ifdef DEBUG
- default: /* error: unknown picture type */
- intf_DbgMsg("video debug 115-6: unknown picture type\n");
- return( 1 );
- break;
-#endif
- }
-
- /* If picture is not blank, the p_data has some meaning */
- if( (p_pic->i_type != RGB_BLANK_PICTURE)
- && (p_pic->i_type != PIXEL_BLANK_PICTURE) )
- {
- /* If picture owns its data, allocate p_data */
- if( p_pic->i_flags & OWNER_PICTURE )
- {
- p_pic->p_data = malloc( p_pic->i_height * p_pic->i_bytes_per_line );
- if( p_pic->p_data == NULL ) /* error */
- {
- return( 1 );
- }
- }
- /* If picture is a reference, copy pointer */
- else
- {
-#ifdef DEBUG
- /* Check configuration */
- if( !(p_cfg->i_properties & VIDEO_CFG_DATA) )
- {
- intf_DbgMsg("video debug 115-7: missing picture data\n");
- return( 1 );
- }
-#endif
- p_pic->p_data = p_cfg->p_data;
- }
- }
-
- return( 0 );
-}
-
-/*******************************************************************************
- * video_ReadPicture: read a picture from a file
- *******************************************************************************
- * This function reads a picture from an openned file. The picture must be
- * stored in native format, ie: header, according to ReadPictureConfiguration
- * function specifications, then raw data.
- *******************************************************************************
- * Messages type: video, major code 116
- *******************************************************************************/
-picture_t * video_ReadPicture( int i_file )
-{
- video_cfg_t p_cfg; /* new picture configuration */
- picture_t * p_newpic; /* new picture descriptor */
-
- /* Read picture configuration */
- if( ReadPictureConfiguration( i_file, &p_cfg ) )
- {
- return( NULL );
- }
-
- /* Create picture and allocate data */
- p_newpic = video_CreatePicture( &p_cfg );
- if( p_newpic == NULL )
- {
- return( NULL );
- }
-
- /* Read data if required */
- if( (p_newpic->i_type != RGB_BLANK_PICTURE) && (p_newpic->i_type != RGB_BLANK_PICTURE) )
- {
- if( read( i_file, p_newpic->p_data, p_newpic->i_height * p_newpic->i_bytes_per_line )
- != p_newpic->i_height * p_newpic->i_bytes_per_line )
- {
- intf_ErrMsg("video error 116-2: %s\n", strerror(errno));
- video_DestroyPicture( p_newpic );
- return( NULL );
- }
-
- }
-
- /* Log and return */
-#ifdef VOUT_DEBUG /* ?? -> video_debug ? */
- video_PrintPicture( p_newpic, "video debug 116-1: read picture " );
-#endif
- return( p_newpic );
-}
-
-/* following functions are debugging functions */
-
-/*******************************************************************************
- * video_PrintPicture: display picture state (debugging function)
- *******************************************************************************
- * This function, which is only defined if DEBUG is defined, can be used for
- * debugging purposes. It prints on debug stream the main characteristics of
- * a picture. The second parameter is printed in front of data. Note that no
- * header is printed by default.
- *******************************************************************************
- * Messages type: video, major code 141
- *******************************************************************************/
-#ifdef DEBUG
-void video_PrintPicture( picture_t *p_pic, char *psz_str )
-{
- char * psz_type; /* type string */
- char sz_flags[9]; /* flags string */
- char sz_date[MSTRTIME_MAX_SIZE]; /* date buffer */
- char sz_duration[MSTRTIME_MAX_SIZE]; /* duration buffer */
-
- /* Non empty picture */
- if( p_pic->i_type != EMPTY_PICTURE )
- {
- /* Build picture type information string */
- switch( p_pic->i_type )
- {
- case RGB_BLANK_PICTURE:
- psz_type = "rgb-blank";
- break;
- case PIXEL_BLANK_PICTURE:
- psz_type = "pixel-blank";
- break;
- case RGB_PICTURE:
- psz_type = "rgb";
- break;
- case PIXEL_PICTURE:
- psz_type = "pixel";
- break;
- case RGB_MASK_PICTURE:
- psz_type = "rgb mask";
- break;
- case PIXEL_MASK_PICTURE:
- psz_type = "pixel mask";
- break;
- default:
- psz_type = "?";
- break;
- }
-
- /* Build flags information strings */
- sz_flags[0] = ( p_pic->i_flags & RESERVED_PICTURE ) ? 'r' : '-';
- sz_flags[1] = ( p_pic->i_flags & PERMANENT_PICTURE ) ? 'p' : '-';
- sz_flags[2] = ( p_pic->i_flags & DISPLAYED_PICTURE ) ? 'D' : '-';
- sz_flags[3] = ( p_pic->i_flags & OWNER_PICTURE ) ? 'O' : '-';
- sz_flags[4] = ( p_pic->i_flags & DISPLAY_PICTURE ) ? 'd' : '-';
- sz_flags[5] = ( p_pic->i_flags & DESTROY_PICTURE ) ? 'x' : '-';
- sz_flags[6] = ( p_pic->i_flags & TRANSPARENT_PICTURE ) ? 't' : '-';
- sz_flags[7] = ( p_pic->i_flags & OVERLAY_PICTURE ) ? 'o' : '-';
- sz_flags[8] = '\0';
-
- /* Print information strings */
- intf_DbgMsg("%s%p: %s (%s) %dx%d-%d.%d s=%d rc=%d d=%s t=%s\n",
- psz_str, p_pic,
- psz_type, sz_flags,
- p_pic->i_width, p_pic->i_height, p_pic->i_bpp, p_pic->i_bytes_per_line,
- p_pic->i_stream,
- p_pic->i_refcount,
- mstrtime( sz_date, p_pic->date ), mstrtime( sz_duration, p_pic->duration) );
- }
- /* Empty picture */
- else
- {
- intf_DbgMsg("%sempty\n", psz_str);
- }
-}
-#endif
-
-/* following functions are local */
-
-/*******************************************************************************
- * ReadPictureConfiguration: read a vout_cfg_t structure from a file
- *******************************************************************************
- * This function reads a picture configuration and properties from a file. Note
- * that some fields of the vout_cft_t, which do not concern pictures, are
- * ignored. Note that the file is in MSB (little-endian).
- *******************************************************************************
- * Messages type: video, major code 151
- *******************************************************************************/
-static int ReadPictureConfiguration( int i_file, video_cfg_t *p_cfg )
-{
- byte_t p_buffer[42]; /* buffer used to store the packed structure */
-
- /* Read buffer */
- if( read( i_file, p_buffer, 42 ) != 42 )
- {
- intf_ErrMsg("video error 151-1: %s\n", strerror(errno) );
- return( errno );
- }
-
- /* Parse buffer */
- p_cfg->i_properties = ntoh32( *(u32 *)( p_buffer ) );
- p_cfg->i_type = *(u8 *)( p_buffer + 4 );
- p_cfg->i_bpp= *(u8 *)( p_buffer + 5 );
- p_cfg->i_width = ntoh16( *(u16 *)( p_buffer + 6 ) );
- p_cfg->i_height = ntoh16( *(u16 *)( p_buffer + 8 ) );
- p_cfg->i_flags = ntoh16( *(u16 *)( p_buffer + 10 ) );
- p_cfg->i_x = ntoh16( *(s16 *)( p_buffer + 12 ) );
- p_cfg->i_y = ntoh16( *(s16 *)( p_buffer + 14 ) );
- p_cfg->i_h_align = *(s8 *)( p_buffer + 16 );
- p_cfg->i_v_align = *(s8 *)( p_buffer + 17 );
- p_cfg->i_h_ratio = *(s8 *)( p_buffer + 19 );
- p_cfg->i_v_ratio = *(s8 *)( p_buffer + 19 );
- p_cfg->i_level = *(s8 *)( p_buffer + 20 );
- p_cfg->i_stream = *(u8 *)( p_buffer + 21 );
- p_cfg->date = ntoh64( *(u64 *)( p_buffer + 22 ) );
- p_cfg->duration = ntoh64( *(u64 *)( p_buffer + 30 ) );
- p_cfg->pixel = ntoh32( *(u32 *)( p_buffer + 38 ) );
-
- return( 0 );
-}
-
-
/*******************************************************************************
* Preamble
*******************************************************************************/
+#include "vlc.h"
+/*
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/XShm.h>
#include "common.h"
#include "config.h"
#include "video_graphics.h"
#include "video_output.h"
#include "video_x11.h"
-
-#include "intf_msg.h"
+*/
/*
* Local prototypes
*/
-static int CheckConfiguration ( video_cfg_t *p_cfg );
static int InitThread ( vout_thread_t *p_vout );
static void RunThread ( vout_thread_t *p_vout );
static void ErrorThread ( vout_thread_t *p_vout );
static void EndThread ( vout_thread_t *p_vout );
-static picture_t * FindPicture ( vout_thread_t *p_vout );
-static void EmptyPicture ( vout_thread_t *p_vout, picture_t *p_pic );
-static mtime_t FirstPass ( vout_thread_t *p_vout, mtime_t current_date );
-static void SecondPass ( vout_thread_t *p_vout, mtime_t display_date );
-static void SortPictures ( vout_thread_t *p_vout, picture_t **pp_picture );
-static void RenderPicture ( vout_thread_t *p_vout, picture_t *p_pic );
-static void ClipPicture ( int *pi_ofs, int i_size, int *pi_pic_ofs, int *pi_pic_size,
- int i_ratio, int i_placement );
+static void RenderPicture ( vout_thread_t *p_vout, picture_t *p_pic );
/*******************************************************************************
* vout_CreateThread: creates a new video output thread
* If pi_status is NULL, then the function will block until the thread is ready.
* If not, pi_error will be updated using one of the THREAD_* constants.
*******************************************************************************/
-vout_thread_t *vout_CreateThread( video_cfg_t *p_cfg, int *pi_status )
+vout_thread_t * vout_CreateThread (
+#if defined(VIDEO_X11)
+ Display *p_display, Window root_window,
+#elif defined(VIDEO_FB)
+ //??
+#endif
+ int i_width, int i_height, int *pi_status
+ )
{
vout_thread_t * p_vout; /* thread descriptor */
int i_status; /* thread status */
- /*
- * Check configuration
- */
- if( CheckConfiguration( p_cfg ) )
- {
- return( NULL );
- }
-
- /* Allocate descriptor and initialize flags */
+ /* Allocate descriptor and create method */
p_vout = (vout_thread_t *) malloc( sizeof(vout_thread_t) );
if( p_vout == NULL ) /* error */
{
return( NULL );
}
- if( vout_X11AllocOutputMethod( p_vout, p_cfg ) )
+ intf_DbgMsg( "0x%x\n", p_vout );
+ if( vout_SysCreate( p_vout
+#if defined(VIDEO_X11)
+ , p_display, root_window
+#elif defined(VIDEO_FB)
+ //??
+#endif
+ ) )
{
- free( p_vout );
- return( NULL );
+ free( p_vout );
+ return( NULL );
}
-
- /* Copy configuration */
- p_vout->i_max_pictures = p_cfg->i_size;
- p_vout->i_width = p_cfg->i_width;
- p_vout->i_height = p_cfg->i_height;
-
- /* Set status */
- p_vout->pi_status = (pi_status != NULL) ? pi_status : &i_status;
- *p_vout->pi_status = THREAD_CREATE;
-
- /* Initialize flags */
- p_vout->b_die = 0;
- p_vout->b_error = 0;
- p_vout->b_active = 0;
+
+ /* Initialize */
+ p_vout->i_width = i_width;
+ p_vout->i_height = i_height;
+ p_vout->pi_status = (pi_status != NULL) ? pi_status : &i_status;
+ *p_vout->pi_status = THREAD_CREATE;
+ p_vout->b_die = 0;
+ p_vout->b_error = 0;
+ p_vout->b_active = 0;
/* Create thread and set locks */
- vlc_mutex_init( &p_vout->streams_lock );
- vlc_mutex_init( &p_vout->pictures_lock );
- if( vlc_thread_create( &p_vout->thread_id, "video output", (vlc_thread_func)RunThread, (void *) p_vout) )
+ vlc_mutex_init( &p_vout->lock );
+ if( vlc_thread_create( &p_vout->thread_id, "video output",
+ (void *) RunThread, (void *) p_vout) )
{
intf_ErrMsg("vout error: %s\n", strerror(ENOMEM));
- intf_DbgMsg("failed\n");
- vout_X11FreeOutputMethod( p_vout );
+ vout_SysDestroy( p_vout );
free( p_vout );
return( NULL );
}
&& (i_status != THREAD_FATAL) );
if( i_status != THREAD_READY )
{
- intf_DbgMsg("failed\n");
return( NULL );
}
}
- intf_DbgMsg("succeeded -> %p\n", p_vout);
return( p_vout );
}
{
int i_status; /* thread status */
+ intf_DbgMsg( "0x%x\n", p_vout );
+
/* Set status */
p_vout->pi_status = (pi_status != NULL) ? pi_status : &i_status;
- *p_vout->pi_status = THREAD_DESTROY;
+ *p_vout->pi_status = THREAD_DESTROY;
/* Request thread destruction */
p_vout->b_die = 1;
}while( (i_status != THREAD_OVER) && (i_status != THREAD_ERROR)
&& (i_status != THREAD_FATAL) );
}
-
- intf_DbgMsg("%p -> succeeded\n", p_vout);
-}
-
-/*******************************************************************************
- * vout_DisplayPicture: add a picture to a thread
- *******************************************************************************
- * The picture will be placed in an empty place of the video heap of the thread.
- * If this is impossible, NULL will be returned. Else, the original picture
- * is destroyed.
- *******************************************************************************/
-picture_t * vout_DisplayPicture( vout_thread_t *p_vout, picture_t *p_pic )
-{
- picture_t * p_newpic; /* new picture index */
-
- p_newpic = FindPicture( p_vout );
- if( p_newpic != NULL )
- {
- /* Copy picture information */
- video_CopyPictureDescriptor( p_newpic, p_pic );
- p_newpic->p_data = p_pic->p_data;
- free( p_pic );
-
- /* Update heap size and stats */
- p_vout->i_pictures++;
-#ifdef STATS
- p_vout->c_pictures++;
- p_vout->p_stream[ p_newpic->i_stream ].c_pictures++;
-#endif
- }
-
- /* Release lock and return */
- vlc_mutex_unlock( &p_vout->pictures_lock );
- return( p_newpic );
-}
-
-/*******************************************************************************
- * vout_DisplayPictureCopy: copy a picture to a thread
- *******************************************************************************
- * The picture will be copied in an empty place of the video heap of the thread.
- * If this is impossible, NULL will be returned. The picture used is the copy
- * of the picture passed as argument, which remains usable.
- * The picture data are copied only if the original picture owns its own data.
- * The link reference counter is set to 0.
- *******************************************************************************/
-picture_t * vout_DisplayPictureCopy( vout_thread_t *p_vout, picture_t *p_pic )
-{
- picture_t * p_newpic; /* new picture index */
-
- p_newpic = FindPicture( p_vout );
- if( p_newpic != NULL )
- {
- /* Copy picture information */
- video_CopyPictureDescriptor( p_newpic, p_pic );
-
- /* If source picture owns its data, make a copy */
- if( p_pic->i_flags & OWNER_PICTURE )
- {
- p_newpic->p_data = malloc( p_pic->i_height * p_pic->i_bytes_per_line );
- if( p_newpic->p_data == NULL ) /* error */
- {
- intf_ErrMsg("vout error: %s\n", strerror(ENOMEM) );
-
- /* Restore type and flags */
- p_newpic->i_type = EMPTY_PICTURE;
- p_newpic->i_flags = 0;
- vlc_mutex_unlock( &p_vout->pictures_lock );
- return( NULL );
- }
- memcpy( p_newpic->p_data, p_pic->p_data,
- p_pic->i_height * p_pic->i_bytes_per_line );
- }
- /* If source picture does not owns its data, copy the reference */
- else
- {
- p_newpic->p_data = p_pic->p_data;
- }
- p_newpic->i_refcount = 0;
-
- /* Update heap size and stats */
- p_vout->i_pictures++;
-#ifdef STATS
- p_vout->c_pictures++;
- p_vout->p_stream[ p_newpic->i_stream ].c_pictures++;
-#endif
- }
-
- /* Release lock and return */
- vlc_mutex_unlock( &p_vout->pictures_lock );
- return( p_newpic );
}
/*******************************************************************************
- * vout_DisplayPictureReplicate: copy a picture to a thread
+ * vout_DisplayPicture: display a picture
*******************************************************************************
- * The picture will be copied in an empty place of the video heap of the thread.
- * If this is impossible, NULL will be returned. The picture used is the copy
- * of the picture passed as argument, which remains usable.
- * The picture data are a reference to original picture (the picture in the heap
- * does not owns its data). Link reference counter is set to 0.
+ * Remove the reservation flag of a picture, which will cause it to be ready for
+ * display.
*******************************************************************************/
-picture_t * vout_DisplayPictureReplicate( vout_thread_t *p_vout, picture_t *p_pic )
+void vout_DisplayPicture( vout_thread_t *p_vout, picture_t *p_pic )
{
- picture_t * p_newpic; /* new picture descrpitor */
-
- p_newpic = FindPicture( p_vout );
- if( p_newpic != NULL )
- {
- /* Copy picture information */
- video_CopyPictureDescriptor( p_newpic, p_pic );
- p_newpic->i_flags &= ~OWNER_PICTURE;
- p_newpic->p_data = p_pic->p_data;
- p_newpic->i_refcount = 0;
-
- /* Update heap size and stats */
- p_vout->i_pictures++;
-#ifdef STATS
- p_vout->c_pictures++;
- p_vout->p_stream[ p_newpic->i_stream ].c_pictures++;
-#endif
- }
-
- /* Release lock and return */
- vlc_mutex_unlock( &p_vout->pictures_lock );
- return( p_newpic );
-}
-
-/*******************************************************************************
- * vout_DisplayReservedPicture: add a reserved picture to a thread
- *******************************************************************************
- * The picture will be placed in an empty place of the video heap of the thread.
- * If the picture has been declared on reservation as permanent, it remains
- * usable. Else, it will be destroyed by this call.
- * This function can't fail, since it is the purpose of picture reservation to
- * provide such a robust mechanism.
- *******************************************************************************/
-picture_t * vout_DisplayReservedPicture( vout_thread_t *p_vout, picture_t *p_pic )
-{
- vlc_mutex_lock( &p_vout->pictures_lock );
+ vlc_mutex_lock( &p_vout->lock );
/* Remove reservation flag */
- p_pic->i_flags &= ~RESERVED_PICTURE;
+ p_pic->i_status = READY_PICTURE;
#ifdef STATS
/* Update stats */
p_vout->c_pictures++;
- p_vout->p_stream[ p_pic->i_stream ].c_pictures++;
#endif
- vlc_mutex_unlock( &p_vout->pictures_lock );
- return( p_pic );
+ vlc_mutex_unlock( &p_vout->lock );
}
/*******************************************************************************
- * vout_CreateReservedPicture: reserve a place for a new picture in heap
+ * vout_CreatePicture: allocate a picture in the video output heap.
*******************************************************************************
* This function create a reserved image in the video output heap.
- * A null pointer is returned if the function fails.
- * Following configuration properties are used:
- * VIDEO_CFG_WIDTH picture width (required)
- * VIDEO_CFG_HEIGHT picture height (required)
- * VIDEO_CFG_TYPE picture type (required)
- * VIDEO_CFG_FLAGS flags
- * VIDEO_CFG_BPP padded bpp (required for pixel pictures)
- * VIDEO_CFG_POSITION position in output window
- * VIDEO_CFG_ALIGN base position in output window
- * VIDEO_CFG_RATIO display ratio
- * VIDEO_CFG_LEVEL overlay hierarchical level
- * VIDEO_CFG_REFCOUNT links reference counter
- * VIDEO_CFG_STREAM video stream id
- * VIDEO_CFG_DATE display date
- * VIDEO_CFG_DURATION duration for overlay pictures
- * VIDEO_CFG_PIXEL pixel value for mask pictures
- * VIDEO_CFG_DATA picture data (required if not owner and non blank)
- * Pictures created using this function are always reserved, even if they did
- * not had the RESERVED_PICTURE flag set.
- * This function is very similar to the video_CreatePicture function.
+ * A null pointer is returned if the function fails. This method provides an
+ * already allocated zone of memory in the picture data fields.
*******************************************************************************/
-picture_t *vout_CreateReservedPicture( vout_thread_t *p_vout, video_cfg_t *p_cfg )
+picture_t *vout_CreatePicture( vout_thread_t *p_vout, int i_type,
+ int i_width, int i_height, int i_bytes_per_line )
{
- picture_t * p_newpic; /* new picture index */
+ int i_picture; /* picture index */
+ picture_t * p_free_picture = NULL; /* first free picture */
+ picture_t * p_destroyed_picture = NULL; /* first destroyed picture */
- p_newpic = FindPicture( p_vout );
- if( p_newpic != NULL )
- {
- /* Create new picture */
- if( video_CreatePictureBody( p_newpic, p_cfg ) )
- {
- intf_ErrMsg("vout error: %s\n", strerror(ENOMEM));
- /* Error: restore type and flags */
- p_newpic->i_type = EMPTY_PICTURE;
- p_newpic->i_flags = 0;
- vlc_mutex_unlock( &p_vout->pictures_lock );
- return( NULL );
- }
- p_newpic->i_flags |= RESERVED_PICTURE;
+ /* Get lock */
+ vlc_mutex_lock( &p_vout->lock );
- /* Update heap size, release lock and return */
- p_vout->i_pictures++;
+ /*
+ * Look for an empty place
+ */
+ for( i_picture = 0;
+ i_picture < VOUT_MAX_PICTURES;
+ i_picture++ )
+ {
+ if( p_vout->p_picture[i_picture].i_status == DESTROYED_PICTURE )
+ {
+ /* Picture is marked for destruction, but is still allocated */
+ if( (p_vout->p_picture[i_picture].i_type == i_type) &&
+ (p_vout->p_picture[i_picture].i_height == i_height) &&
+ (p_vout->p_picture[i_picture].i_bytes_per_line == i_bytes_per_line) )
+ {
+ /* Memory size do match : memory will not be reallocated, and function
+ * can end immediately - this is the best possible case, since no
+ * memory allocation needs to be done */
+ p_vout->p_picture[i_picture].i_width = i_width;
+ p_vout->p_picture[i_picture].i_status = RESERVED_PICTURE;
+ vlc_mutex_unlock( &p_vout->lock );
+ return( &p_vout->p_picture[i_picture] );
+ }
+ else if( p_destroyed_picture == NULL )
+ {
+ /* Memory size do not match, but picture index will be kept in
+ * case no other place are left */
+ p_destroyed_picture = &p_vout->p_picture[i_picture];
+ }
+ }
+ else if( (p_free_picture == NULL) &&
+ (p_vout->p_picture[i_picture].i_status == FREE_PICTURE ))
+ {
+ /* Picture is empty and ready for allocation */
+ p_free_picture = &p_vout->p_picture[i_picture];
+ }
}
- /* Release lock and return */
- vlc_mutex_unlock( &p_vout->pictures_lock );
- return( p_newpic );
-}
-
-/*******************************************************************************
- * vout_ReservePicture: reserve a place for a picture in heap
- *******************************************************************************
- * This function transforms an existing picture in a reserved picture in a
- * video heap. The picture will be placed in an empty place of the video heap
- * of the thread. If this is impossible, NULL will be returned. Else, the
- * original picture is destroyed.
- *******************************************************************************/
-picture_t *vout_ReservePicture( vout_thread_t *p_vout, picture_t *p_pic )
-{
- picture_t * p_newpic; /* new picture index */
-
- p_newpic = FindPicture( p_vout );
- if( p_newpic != NULL )
- {
- /* Copy picture information */
- video_CopyPictureDescriptor( p_newpic, p_pic );
- p_newpic->p_data = p_pic->p_data;
- p_newpic->i_flags |= RESERVED_PICTURE;
- free( p_pic );
-
- /* Update heap size */
- p_vout->i_pictures++;
+ /* If no free picture is available, use a destroyed picture */
+ if( (p_free_picture == NULL) && (p_destroyed_picture != NULL ) )
+ {
+ /* No free picture or matching destroyed picture has been found, but
+ * a destroyed picture is still avalaible */
+ free( p_destroyed_picture->p_data );
+ p_free_picture = p_destroyed_picture;
}
- /* Release lock and return */
- vlc_mutex_unlock( &p_vout->pictures_lock );
- return( p_newpic );
-}
-
-/*******************************************************************************
- * vout_ReservePictureCopy: reserve a place for a picture in heap
- *******************************************************************************
- * This function returns a pointer to a picture which can be processed. The
- * returned picture is a copy of the one passed as parameter.
- * This function returns NULL if the reservation fails.
- *******************************************************************************/
-picture_t *vout_ReservePictureCopy( vout_thread_t *p_vout, picture_t *p_pic )
-{
- picture_t * p_newpic; /* new picture index */
-
- p_newpic = FindPicture( p_vout );
- if( p_newpic != NULL )
- {
- /* Copy picture information */
- video_CopyPictureDescriptor( p_newpic, p_pic );
-
- /* If source picture owns its data, make a copy */
- if( p_pic->i_flags & OWNER_PICTURE )
- {
- p_newpic->p_data = malloc( p_pic->i_height * p_pic->i_bytes_per_line );
- if( p_newpic->p_data == NULL ) /* error */
- {
- intf_ErrMsg("vout error: %s\n", strerror(ENOMEM));
- /* Restore type and flags */
- p_newpic->i_type = EMPTY_PICTURE;
- p_newpic->i_flags = 0;
- vlc_mutex_unlock( &p_vout->pictures_lock );
- return( NULL );
- }
- memcpy( p_newpic->p_data, p_pic->p_data,
- p_pic->i_height * p_pic->i_bytes_per_line );
- }
- /* If source picture does not owns its data, copy the reference */
- else
+ /*
+ * Prepare picture
+ */
+ if( p_free_picture != NULL )
+ {
+ /* Allocate memory */
+ switch( i_type )
{
- p_newpic->p_data = p_pic->p_data;
+ case YUV_422_PICTURE: /* YUV picture: 3*16 ?? bits per pixel */
+ case YUV_442_PICTURE:
+ case YUV_444_PICTURE:
+ p_free_picture->p_data = malloc( 3 * i_height * i_bytes_per_line );
+ p_free_picture->p_y = p_free_picture->p_data;
+ p_free_picture->p_u = (byte_t *)p_free_picture->p_data + i_height * i_bytes_per_line;
+ p_free_picture->p_v = (byte_t *)p_free_picture->p_data + i_height * i_bytes_per_line * 2;
+ break;
+#ifdef DEBUG
+ default:
+ intf_DbgMsg("0x%x error: unknown picture type %d\n", p_vout, i_type );
+ p_free_picture->p_data = NULL;
+#endif
}
- p_newpic->i_refcount = 0;
- p_newpic->i_flags |= RESERVED_PICTURE;
- /* Update heap size */
- p_vout->i_pictures++;
- }
-
- /* Release lock and return */
- vlc_mutex_unlock( &p_vout->pictures_lock );
- return( p_newpic );
-}
-
-/*******************************************************************************
- * vout_ReservePictureReplicate: reserve a place for a picture in heap
- *******************************************************************************
- * This function returns a pointer to a picture which can be processed. The
- * returned picture is a copy of the one passed as parameter.
- * This function returns NULL if the reservation fails.
- *******************************************************************************/
-picture_t *vout_ReservePictureReplicate( vout_thread_t *p_vout, picture_t *p_pic )
-{
- picture_t * p_newpic; /* new picture index */
-
- p_newpic = FindPicture( p_vout );
- if( p_newpic != NULL )
- {
- /* Copy picture information */
- video_CopyPictureDescriptor( p_newpic, p_pic );
- p_newpic->p_data = p_pic->p_data;
- p_newpic->i_refcount = 0;
- p_newpic->i_flags &= ~OWNER_PICTURE;
- p_newpic->i_flags |= RESERVED_PICTURE;
-
- /* Update heap size */
- p_vout->i_pictures++;
+ if( p_free_picture->p_data != NULL )
+ {
+ /* Copy picture informations */
+ p_free_picture->i_type = i_type;
+ p_free_picture->i_status = RESERVED_PICTURE;
+ p_free_picture->i_width = i_width;
+ p_free_picture->i_height = i_height;
+ p_free_picture->i_bytes_per_line = i_bytes_per_line;
+ p_free_picture->i_refcount = 0;
+ }
+ else
+ {
+ /* Memory allocation failed : set picture as empty */
+ p_free_picture->i_type = EMPTY_PICTURE;
+ p_free_picture->i_status = FREE_PICTURE;
+ p_free_picture = NULL;
+ intf_DbgMsg("0x%x malloc for new picture failed\n");
+ }
+
+ vlc_mutex_unlock( &p_vout->lock );
+ return( p_free_picture );
}
-
- /* Release lock and return */
- vlc_mutex_unlock( &p_vout->pictures_lock );
- return( p_newpic );
+
+ // No free or destroyed picture could be found
+ intf_DbgMsg("0x%x no picture available\n");
+ vlc_mutex_unlock( &p_vout->lock );
+ return( NULL );
}
/*******************************************************************************
* vout_RemovePicture: remove a permanent or reserved picture from the heap
*******************************************************************************
* This function frees a previously reserved picture or a permanent
- * picture. The picture data is destroyed if required.
+ * picture. It is meant to be used when the construction of a picture aborted.
+ * Note that the picture will be destroyed even if it is linked !
*******************************************************************************/
-void vout_RemovePicture( vout_thread_t *p_vout, picture_t *p_pic )
+void vout_DestroyPicture( vout_thread_t *p_vout, picture_t *p_pic )
{
- vlc_mutex_lock( &p_vout->pictures_lock );
+ vlc_mutex_lock( &p_vout->lock );
/* Mark picture for destruction */
- p_pic->i_flags |= DESTROY_PICTURE;
- /* Since permanent pictures can normally not be destroyed by the vout thread,
- * the permanent flag needs to be removed */
- p_pic->i_flags &= ~PERMANENT_PICTURE;
- intf_DbgMsg("%p -> picture %p removing requested\n", p_vout, p_pic );
+ p_pic->i_status = DESTROYED_PICTURE;
+ intf_DbgMsg("%p -> picture %p destroyed\n", p_vout, p_pic );
- vlc_mutex_unlock( &p_vout->pictures_lock );
-}
-
-/*******************************************************************************
- * vout_RefreshPermanentPicture:
- *******************************************************************************
- * Set the DISPLAYED_PICTURE flag of a permanent picture to 0, allowing to
- * display it again if it not overlaid. The display date is also updated.
- *******************************************************************************/
-void vout_RefreshPermanentPicture( vout_thread_t *p_vout, picture_t *p_pic,
- mtime_t display_date )
-{
- vlc_mutex_lock( &p_vout->pictures_lock );
- p_pic->i_flags &= ~DISPLAYED_PICTURE;
- p_pic->date = display_date;
- vlc_mutex_lock( &p_vout->pictures_lock );
+ vlc_mutex_unlock( &p_vout->lock );
}
/*******************************************************************************
*******************************************************************************/
void vout_LinkPicture( vout_thread_t *p_vout, picture_t *p_pic )
{
- vlc_mutex_lock( &p_vout->pictures_lock );
+ vlc_mutex_lock( &p_vout->lock );
p_pic->i_refcount++;
- vlc_mutex_unlock( &p_vout->pictures_lock );
+ vlc_mutex_unlock( &p_vout->lock );
}
/*******************************************************************************
*******************************************************************************/
void vout_UnlinkPicture( vout_thread_t *p_vout, picture_t *p_pic )
{
- vlc_mutex_lock( &p_vout->pictures_lock );
+ vlc_mutex_lock( &p_vout->lock );
p_pic->i_refcount--;
-#ifdef DEBUG
- if( p_pic->i_refcount < 0 )
- {
- intf_DbgMsg("%p -> picture %p i_refcount < 0\n", p_vout, p_pic);
- }
-#endif
- vlc_mutex_unlock( &p_vout->pictures_lock );
-}
-
-/*******************************************************************************
- * vout_CreateStream: get a new stream id
- *******************************************************************************
- * Stream ids are used to create list of pictures in a video output thread.
- * The function returns an unused stream id, or a negative number on error.
- * Stream id 0 is never returned, since it is not a stream descriptor but a set
- * of independant images.
- *******************************************************************************/
-int vout_CreateStream( vout_thread_t *p_vout )
-{
- int i_index; /* stream index */
-
- /* Find free (inactive) stream id */
- vlc_mutex_lock( &p_vout->streams_lock ); /* get lock */
- for( i_index = 1; i_index < VOUT_MAX_STREAMS; i_index++ ) /* find free id */
+ if( (p_pic->i_refcount == 0) && (p_pic->i_status == DISPLAYED_PICTURE) )
{
- if( p_vout->p_stream[i_index].i_status == VOUT_INACTIVE_STREAM )
- {
- /* Initialize stream */
- p_vout->p_stream[i_index].i_status = VOUT_ACTIVE_STREAM;
-#ifdef STATS
- p_vout->p_stream[i_index].c_pictures = 0;
- p_vout->p_stream[i_index].c_rendered_pictures = 0;
-#endif
-
- /* Return stream id */
- intf_DbgMsg("%p -> stream %i created\n", p_vout, i_index);
- vlc_mutex_unlock( &p_vout->streams_lock ); /* release lock */
- return( i_index ); /* return id */
- }
+ p_pic->i_status = DESTROYED_PICTURE;
}
-
- /* Failure: all streams id are already active */
- intf_DbgMsg("%p -> failed\n", p_vout);
- vlc_mutex_unlock( &p_vout->streams_lock );
- return( -1 );
-}
-
-/*******************************************************************************
- * vout_EndStream: free a previously allocated stream
- *******************************************************************************
- * This function must be called once a stream is no more used. It can be called
- * even if there are remaining pictures in the video heap, since the stream will
- * only be destroyed once all pictures of the stream have been displayed.
- *******************************************************************************/
-void vout_EndStream( vout_thread_t *p_vout, int i_stream )
-{
- vlc_mutex_lock( &p_vout->streams_lock ); /* get lock */
- p_vout->p_stream[i_stream].i_status = VOUT_ENDING_STREAM; /* mark stream */
- vlc_mutex_unlock( &p_vout->streams_lock ); /* release lock */
- intf_DbgMsg("%p -> stream %d\n", p_vout, i_stream);
-}
-
-/*******************************************************************************
- * vout_DestroyStream: free a previously allocated stream
- *******************************************************************************
- * This function must be called once a stream is no more used. It can be called
- * even if there are remaining pictures in the video heap, since all pictures
- * will be removed before the stream is destroyed.
- *******************************************************************************/
-void vout_DestroyStream( vout_thread_t *p_vout, int i_stream )
-{
- vlc_mutex_lock( &p_vout->streams_lock ); /* get lock */
- p_vout->p_stream[i_stream].i_status = VOUT_DESTROYED_STREAM;/* mark stream */
- vlc_mutex_unlock( &p_vout->streams_lock ); /* release lock */
- intf_DbgMsg("%p -> stream %d\n", p_vout, i_stream);
-}
-
-/* following functions are debugging functions */
-
-/*******************************************************************************
- * vout_PrintHeap: display heap state (debugging function)
- *******************************************************************************
- * This functions, which is only defined if DEBUG is defined, can be used
- * for debugging purposes. It prints on debug stream the current state of the
- * heap. The second parameter is used to identify the output.
- *******************************************************************************/
-#ifdef DEBUG
-void vout_PrintHeap( vout_thread_t *p_vout, char *psz_str )
-{
- int i_picture; /* picture index */
-
- intf_Msg("vout: --- thread %p heap status (%s) ---\n", p_vout, psz_str );
-
- /* Browse all pictures in heap */
- for( i_picture = 0; i_picture < p_vout->i_max_pictures; i_picture++ )
- {
- if( p_vout->p_picture[i_picture].i_type != EMPTY_PICTURE )
- {
- video_PrintPicture( &p_vout->p_picture[i_picture], "vout: ..." );
- }
- }
-
- intf_Msg("vout: --- end ---\n");
+ vlc_mutex_unlock( &p_vout->lock );
}
-#endif
/* following functions are local */
-/*******************************************************************************
- * CheckConfiguration: check vout_CreateThread() configuration
- *******************************************************************************
- * Set default parameters where required. In DEBUG mode, check if configuration
- * is valid.
- *******************************************************************************/
-static int CheckConfiguration( video_cfg_t *p_cfg )
-{
- /* Heap size */
- if( !( p_cfg->i_properties & VIDEO_CFG_SIZE ) )
- {
- p_cfg->i_size = VOUT_HEAP_SIZE;
- }
-
- return( 0 );
-}
-
/*******************************************************************************
* InitThread: initialize video output thread
*******************************************************************************
/* Update status */
*p_vout->pi_status = THREAD_START;
- /* Allocate video heap */
- p_vout->p_picture =
- (picture_t *) malloc( sizeof(picture_t) * p_vout->i_max_pictures );
- if( !p_vout->p_picture ) /* error */
- {
- intf_ErrMsg("vout error: %s\n", strerror(ENOMEM));
- intf_DbgMsg("%p -> failed\n", p_vout);
- *p_vout->pi_status = THREAD_ERROR;
- return( 1 );
- }
-
/* Initialize pictures */
- for( i_index = 0; i_index < p_vout->i_max_pictures; i_index++)
+ 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_flags = 0;
+ p_vout->p_picture[i_index].i_type = EMPTY_PICTURE;
+ p_vout->p_picture[i_index].i_status= FREE_PICTURE;
}
- /* Initialize video streams - note that stream 0 is always active */
- p_vout->p_stream[0].i_status = VOUT_ACTIVE_STREAM;
-#ifdef STATS
- p_vout->p_stream[0].c_pictures = 0;
- p_vout->p_stream[0].c_rendered_pictures = 0;
-#endif
- for( i_index = 1; i_index < VOUT_MAX_STREAMS; i_index++ )
- {
- p_vout->p_stream[i_index].i_status = VOUT_INACTIVE_STREAM;
- }
-
/* Initialize other properties */
p_vout->i_pictures = 0;
#ifdef STATS
/* Initialize output method - width, height, screen depth and bytes per
* pixel are initialized by this call. */
- if( vout_X11CreateOutputMethod( p_vout ) ) /* error */
+ if( vout_SysInit( p_vout ) ) /* error */
{
- free( p_vout->p_picture );
*p_vout->pi_status = THREAD_ERROR;
return( 1 );
}
*******************************************************************************/
static void RunThread( vout_thread_t *p_vout)
{
- int i_stream; /* stream index */
int i_picture; /* picture index */
- int i_active_streams; /* number of active streams */
int i_err; /* error code */
- mtime_t display_date; /* display date */
mtime_t current_date; /* current date */
- picture_t * pp_sorted_picture[VOUT_MAX_PICTURES]; /* sorted pictures */
+ picture_t * p_pic = NULL;
#ifdef VOUT_DEBUG
char sz_date[MSTRTIME_MAX_SIZE]; /* date buffer */
#endif
/*
* Initialize thread and free configuration
*/
+ intf_DbgMsg( "0x%x begin\n", p_vout );
p_vout->b_error = InitThread( p_vout );
if( p_vout->b_error )
{
*/
while( (!p_vout->b_die) && (!p_vout->b_error) )
{
- /* Get locks on pictures and streams */
- vlc_mutex_lock( &p_vout->streams_lock );
- vlc_mutex_lock( &p_vout->pictures_lock );
-
- /* Initialise streams: clear images from all streams */
- for( i_stream = 0; i_stream < VOUT_MAX_STREAMS; i_stream++ )
+ /*
+ * Find the picture to display - this is the only operation requiring
+ * the lock on the picture, since once a READY_PICTURE has been found,
+ * it can't be modified by the other threads (except if it is unliked,
+ * but its data remains)
+ */
+ vlc_mutex_lock( &p_vout->lock );
+
+ for( i_picture = 0; i_picture < VOUT_MAX_PICTURES; i_picture++ )
+ {
+ if( (p_vout->p_picture[i_picture].i_status == READY_PICTURE) &&
+ ( (p_pic == NULL) ||
+ (p_vout->p_picture[i_picture].date < p_pic->date) ) )
+ {
+ p_pic = &p_vout->p_picture[i_picture];
+ }
+ }
+
+ vlc_mutex_unlock( &p_vout->lock );
+
+ /*
+ * Render picture if any
+ */
+ if( p_pic )
{
- p_vout->p_stream[i_stream].p_next_picture = NULL;
+ current_date = mdate();
+ if( p_pic->date < current_date )
+ {
+ /* Picture is late: it will be destroyed and the thread will go
+ * immediately to next picture */
+ vlc_mutex_lock( &p_vout->lock );
+ if( p_pic->i_refcount )
+ {
+ p_pic->i_status = DISPLAYED_PICTURE;
+ }
+ else
+ {
+ p_pic->i_status = DESTROYED_PICTURE;
+ }
+ vlc_mutex_unlock( &p_vout->lock );
+ intf_ErrMsg( "vout error: picture %p was late - skipped\n", p_pic );
+ p_pic = NULL;
+ }
+ else if( p_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;
+ }
+ else
+ {
+ /* Picture has not yet been displayed, and has a valid display
+ * date : render it */
+ RenderPicture( p_vout, p_pic );
+ }
}
-
- /* First pass: a set of pictures is selected - all unselected pictures
- * which should be removed are removed, and a display date is computed.
- * If a stream has no next_picture after this step, then the heap does
- * not include any picture from that stream. */
- current_date = mdate();
- display_date = FirstPass( p_vout, current_date );
-
- /* Stream management: streams which are in ENDING or DESTROYED state and
- * which have no more pictures are destroyed */
- for( i_active_streams = i_stream = 1;
- i_stream < VOUT_MAX_STREAMS;
- i_stream++ )
- {
- switch( p_vout->p_stream[i_stream].i_status )
- {
- case VOUT_ACTIVE_STREAM: /* active stream */
- i_active_streams++;
- break;
-
- case VOUT_ENDING_STREAM: /* ending or destroyed streams */
- case VOUT_DESTROYED_STREAM:
- /* Those streams can be destroyed if there are no more picture
- * remaining. This should always be the case for destroyed
- * streams, except if it includes permanent pictures */
- if( p_vout->p_stream[i_stream].p_next_picture == NULL )
- {
- p_vout->p_stream[i_stream].i_status = VOUT_INACTIVE_STREAM;
-#ifdef STATS
- intf_DbgMsg("%p -> stream %d destroyed %d pictures, %d rendered pictures\n",
- p_vout, i_stream, p_vout->p_stream[i_stream].c_pictures,
- p_vout->p_stream[i_stream].c_rendered_pictures );
-#else
- intf_DbgMsg("%p -> stream %d destroyed\n", p_vout, i_stream );
-#endif
- }
- /* If the stream can't be destroyed, it means it is still
- * active - in that case, the next image pointer needs to be
- * cleard */
- else
- {
- i_active_streams++;
- p_vout->p_stream[i_stream].p_next_picture = NULL;
- }
- break;
- }
- }
-
- /* From now until next loop, only next_picture field in streams
- * will be used, and selected pictures structures won't modified.
- * Therefore, locks can be released */
- vlc_mutex_unlock( &p_vout->pictures_lock );
- vlc_mutex_unlock( &p_vout->streams_lock );
-
- /* If there are some pictures to display, then continue */
- if( display_date != LAST_MDATE )
- {
- /* Increase display_date if it is too low */
- if( display_date < current_date + VOUT_DISPLAY_DELAY )
- {
- intf_Msg("vout: late picture(s) detected\n");
- display_date = current_date + VOUT_DISPLAY_DELAY;
- }
-#ifdef VOUT_DEBUG
- intf_DbgMsg("%p -> display_date is %s\n", p_vout,
- mstrtime( sz_date, display_date ));
-#endif
-
- /* Second pass: a maximum of one picture per stream is selected
- * (except for stream 0), and some previously selected pictures may
- * be removed */
- SecondPass( p_vout, display_date );
-#ifdef VOUT_DEBUG
- vout_PrintHeap( p_vout, "ready for rendering" );
-#endif
-
- /* Rendering: sort pictures and render them */
- SortPictures( p_vout, pp_sorted_picture );
- for( i_picture = 0; pp_sorted_picture[i_picture] != NULL; i_picture++ )
- {
- /* Render picture */
- RenderPicture( p_vout, pp_sorted_picture[i_picture] );
- }
-
- /* Handle output method events - this function can return a negative
- * value, which means a fatal error and the end of the display loop
- * (i.e. the X11 window has been destroyed), a positive one, meaning
- * a modification occured in the pictures and they do have need to
- * be displayed, or 0 */
- i_err = vout_X11ManageOutputMethod( p_vout );
- if( !i_err )
- {
- /* Sleep and display */
- mwait( display_date );
- vout_X11DisplayOutput( p_vout );
- }
- else if( i_err < 0 )
- {
- /* An error occured, and the thread must terminate immediately,
- * without displaying anything - setting b_error to 1 cause the
- * immediate end of the main while() loop. */
- p_vout->b_error = 1;
- }
- }
- /* If there is nothing to display, just handle events and sleep a while,
- * hopping there will be something to do later */
- else
- {
- if( vout_X11ManageOutputMethod( p_vout ) < 0)
- {
- p_vout->b_error = 1;
-
- }
- else
- {
- msleep( VOUT_IDLE_SLEEP );
- }
+
+ /*
+ * Check events, sleep and display picture
+ */
+ i_err = vout_SysManage( p_vout );
+ if( i_err < 0 )
+ {
+ /* A fatal error occured, and the thread must terminate immediately,
+ * without displaying anything - setting b_error to 1 cause the
+ * immediate end of the main while() loop. */
+ p_vout->b_error = 1;
+ }
+ else
+ {
+ if( p_pic )
+ {
+ /* A picture is ready to be displayed : sleep until its display date */
+ mwait( p_pic->date );
+
+ if( !i_err )
+ {
+ vout_SysDisplay( p_vout );
+ }
+
+ /* Picture has been displayed : destroy it */
+ vlc_mutex_lock( &p_vout->lock );
+ if( p_pic->i_refcount )
+ {
+ p_pic->i_status = DISPLAYED_PICTURE;
+ }
+ else
+ {
+ p_pic->i_status = DESTROYED_PICTURE;
+ }
+ vlc_mutex_unlock( &p_vout->lock );
+ }
+ else
+ {
+ /* Sleep to wait for new pictures */
+ msleep( VOUT_IDLE_SLEEP );
#ifdef STATS
- /* Update counters */
- p_vout->c_idle_loops++;
+ /* Update counters */
+ p_vout->c_idle_loops++;
#endif
- }
+ }
+ }
#ifdef STATS
/* Update counters */
/* End of thread */
EndThread( p_vout );
+ intf_DbgMsg( "0x%x end\n", p_vout );
}
/*******************************************************************************
*******************************************************************************/
static void ErrorThread( vout_thread_t *p_vout )
{
- int i_picture; /* picture index */
-
/* Wait until a `die' order */
while( !p_vout->b_die )
{
- /* Get lock on pictures */
- vlc_mutex_lock( &p_vout->pictures_lock );
-
- /* Try to remove all pictures - only removable pictures will be
- * removed */
- for( i_picture = 0; i_picture < p_vout->i_max_pictures; i_picture++ )
- {
- if( p_vout->p_picture[i_picture].i_type != EMPTY_PICTURE )
- {
- EmptyPicture( p_vout, &p_vout->p_picture[i_picture] );
- }
- }
-
- /* Release locks on pictures */
- vlc_mutex_unlock( &p_vout->pictures_lock );
-
/* Sleep a while */
msleep( VOUT_IDLE_SLEEP );
}
static void EndThread( vout_thread_t *p_vout )
{
int * pi_status; /* thread status */
-#ifdef DEBUG
- int i_stream; /* video stream index */
-#endif
+ int i_picture;
/* Store status */
pi_status = p_vout->pi_status;
*pi_status = THREAD_END;
-
-#ifdef DEBUG
- /* Check for remaining pictures or video streams */
- if( p_vout->i_pictures )
- {
- intf_DbgMsg("%p -> remaining pictures\n", p_vout);
- }
- for( i_stream = 1;
- (i_stream < VOUT_MAX_STREAMS) && (p_vout->p_stream[i_stream].i_status == VOUT_INACTIVE_STREAM);
- i_stream++ )
- {
- ;
- }
- if( i_stream != VOUT_MAX_STREAMS )
- {
- intf_DbgMsg("%p -> remaining video streams\n", p_vout);
- }
-#endif
+ /* Destroy all remaining pictures */
+ for( i_picture = 0; i_picture < VOUT_MAX_PICTURES; i_picture++ )
+ {
+ if( p_vout->p_picture[i_picture].i_status != FREE_PICTURE )
+ {
+ free( p_vout->p_picture[i_picture].p_data );
+ }
+ }
+
/* Destroy thread structures allocated by InitThread */
- vout_X11DestroyOutputMethod( p_vout ); /* destroy output method */
- free( p_vout->p_picture ); /* free heap */
+ vout_SysEnd( p_vout );
+ vout_SysDestroy( p_vout ); /* destroy output method */
free( p_vout );
/* Update status */
intf_DbgMsg("%p\n", p_vout);
}
-/*******************************************************************************
- * FindPicture: find an empty picture in a video heap
- *******************************************************************************
- * This function is used by most of the vout_*Picture*() functions. It locks the
- * video heap, look for an empty picture in it and return a pointer to this
- * picture, or NULL if the heap is full.
- * Not that the heap is not unlocked when this function returns, and it needs
- * to be donne by the calling function.
- *******************************************************************************/
-static picture_t *FindPicture( vout_thread_t *p_vout )
-{
- int i_picture; /* picture index */
-
- /* Get lock */
- vlc_mutex_lock( &p_vout->pictures_lock );
-
- /* Look for an empty place */
- for( i_picture = 0; i_picture < p_vout->i_max_pictures; i_picture++ )
- {
- /* An empty place has been found: return */
- if( p_vout->p_picture[i_picture].i_type == EMPTY_PICTURE )
- {
- return( &p_vout->p_picture[i_picture] );
- }
- }
-
- /* Nothing has been found */
- return( NULL );
-}
-
-/*******************************************************************************
- * EmptyPicture: empty a picture without destroying its descriptor
- *******************************************************************************
- * When a picture is no more used in video heap or must be destroyed, this
- * function is called to destroy associated data and set picture type to empty.
- * Only non permanent and unlinked pictures can be destroyed.
- * Only non-empty pictures should be sent to this function.
- * All picture flags are cleared, and the heap size is decreased.
- *******************************************************************************
- * Messages type: vout, major code 15
- *******************************************************************************/
-static void EmptyPicture( vout_thread_t *p_vout, picture_t *p_pic )
-{
-#ifdef DEBUG
- /* Check if picture is non-empty */
- if( p_pic->i_type == EMPTY_PICTURE )
- {
- intf_DbgMsg("%p -> trying to remove empty picture %p\n",
- p_vout, p_pic);
- return;
- }
-#endif
-
- /* Mark as ready for destruction */
- p_pic->i_flags |= DESTROY_PICTURE;
- p_pic->i_flags &= ~DISPLAY_PICTURE;
-
- /* If picture is no more referenced and is not permanent, destroy */
- if( (p_pic->i_refcount == 0) && !(p_pic->i_flags & PERMANENT_PICTURE) )
- {
- /* If picture owns its data, free them */
- if( p_pic->i_flags & OWNER_PICTURE )
- {
- free( p_pic->p_data );
- }
- p_pic->i_type = EMPTY_PICTURE;
- p_pic->i_flags = 0;
- p_vout->i_pictures--;
- intf_DbgMsg("%p -> picture %p removed\n", p_vout, p_pic);
- }
-}
-
-/*******************************************************************************
- * FirstPass: first pass of the vout thread on pictures
- *******************************************************************************
- * A set of pictures is selected according to the current date and their display
- * date. Some unselected and already displayed pictures are removed, and the
- * next display date is computed.
- * The next_picture fields of all the streams are updated. Note that streams
- * are initialized before this function is called.
- *******************************************************************************
- * Messages type: vout, major code 18
- *******************************************************************************/
-static mtime_t FirstPass( vout_thread_t *p_vout, mtime_t current_date )
-{
- mtime_t display_date; /* display date */
- int i_picture; /* picture index */
- picture_t * p_picture; /* picture pointer (shortcut) */
-
- /* Set up date */
- display_date = LAST_MDATE;
-
- /* Browse all pictures */
- for( i_picture = 0; i_picture < p_vout->i_max_pictures; i_picture++ )
- {
- p_picture = &p_vout->p_picture[i_picture];
-
- /* Empty pictures are never selected */
- if( p_picture->i_type == EMPTY_PICTURE )
- {
- ;
- }
- /* Destroyed pictures are never selected, they can be emptied if needed */
- else if( p_picture->i_flags & DESTROY_PICTURE )
- {
- EmptyPicture( p_vout, p_picture );
- }
-#ifdef DEBUG
- /* Pictures in an inactive stream are submitted to a deletion attempt,
- * and nether selected - this case should never happen */
- else if( p_vout->p_stream[ p_picture->i_stream ].i_status == VOUT_INACTIVE_STREAM )
- {
- intf_DbgMsg("%p -> picture %p belongs to an inactive stream\n",
- p_vout, p_picture);
- EmptyPicture( p_vout, p_picture );
- }
-#endif
- /* Pictures in a destroyed stream are submitted to a deletion attempt,
- * and nether selected */
- else if( p_vout->p_stream[ p_picture->i_stream ].i_status == VOUT_DESTROYED_STREAM )
- {
- EmptyPicture( p_vout, p_picture );
- }
- /* Reserved pictures are never selected */
- else if( p_picture->i_flags & RESERVED_PICTURE )
- {
- p_picture->i_flags &= ~DISPLAY_PICTURE;
- }
- /* Overlay pictures */
- else if( p_picture->i_flags & OVERLAY_PICTURE )
- {
- /* A picture is outdated if it is not permanent and if it's maximal
- * date is passed */
- if( !(p_picture->i_flags & PERMANENT_PICTURE )
- && (p_picture->date + p_picture->duration < current_date) )
- {
- p_picture->i_flags &= ~DISPLAY_PICTURE;
- EmptyPicture( p_vout, p_picture );
- }
- /* Else if picture is in stream 0, it will always be selected */
- else if( p_picture->i_stream == 0 )
- {
- p_picture->i_flags |= DISPLAY_PICTURE;
- /* Update display_date if picture has never been displayed */
- if( !(p_picture->i_flags & DISPLAYED_PICTURE) && (p_picture->date < display_date) )
- {
- display_date = p_picture->date;
- }
- }
- /* The picture can be considered as a regular picture, because it
- * has never been displayed */
- else if( !(p_picture->i_flags & DISPLAYED_PICTURE) )
- {
- /* Select picture if can be updated */
- if( (p_vout->p_stream[ p_picture->i_stream].p_next_picture == NULL)
- || (p_vout->p_stream[p_picture->i_stream].p_next_picture->date > p_picture->date))
- {
- p_picture->i_flags |= DISPLAY_PICTURE;
- p_vout->p_stream[p_picture->i_stream].p_next_picture = p_picture;
- /* Update display_date */
- if( p_picture->date < display_date )
- {
- display_date = p_picture->date;
- }
- }
- }
- /* In other cases (overlay pictures which have already been displayed),
- * the picture is always selected */
- else
- {
- p_picture->i_flags |= DISPLAY_PICTURE;
- /* The stream is only updated if there is no picture in that stream */
- if( p_vout->p_stream[ p_picture->i_stream].p_next_picture == NULL )
- {
- p_vout->p_stream[p_picture->i_stream].p_next_picture = p_picture;
- }
- }
- }
- /* Non overlay pictures are deleted if they have been displayed, and
- * selected if there date is valid */
- else
- {
- /* Remove already displayed pictures */
- if( p_picture->i_flags & DISPLAYED_PICTURE )
- {
- EmptyPicture( p_vout, p_picture );
- }
- /* Remove passed pictures, The picture is marked as displayed in case it
- * could not be removed */
- else if( p_picture->date < current_date )
- {
- intf_DbgMsg("%p -> picture %p detected late\n",
- p_vout, p_picture );
- p_picture->i_flags |= DISPLAYED_PICTURE;
- EmptyPicture( p_vout, p_picture );
- }
- /* Update streams for other pictures */
- else
- {
- p_picture->i_flags |= DISPLAY_PICTURE;
- /* Update 'next picture' field in stream descriptor */
- if( (p_vout->p_stream[ p_picture->i_stream].p_next_picture == NULL)
- || (p_vout->p_stream[p_picture->i_stream].p_next_picture->date > p_picture->date))
- {
- p_vout->p_stream[p_picture->i_stream].p_next_picture = p_picture;
- /* Update display_date */
- if( p_picture->date < display_date )
- {
- display_date = p_picture->date;
- }
- }
- }
- }
- }
-
- return( display_date );
-}
-
-/*******************************************************************************
- * SecondPass: second pass of the vout thread on pictures
- *******************************************************************************
- * Select only one picture per stream other than stream 0, and remove pictures
- * which should have been displayed.... but arrived too late. Note that nothing
- * is locked when this function is called, and therefore pictures should not
- * be removed here.
- * Only previously selected pictures are processed.
- *******************************************************************************
- * Messages type: vout, major code 19
- *******************************************************************************/
-static void SecondPass( vout_thread_t *p_vout, mtime_t display_date )
-{
- int i_picture; /* picture index */
- picture_t * p_picture; /* picture pointer (shortcut) */
-
- for( i_picture = 0; i_picture < p_vout->i_max_pictures; i_picture++ )
- {
- p_picture = &p_vout->p_picture[i_picture];
-
- /* Process only previously selected pictures */
- if( p_picture->i_flags & DISPLAY_PICTURE )
- {
- /* Deselect picture if it is too youg */
- if( p_picture->date > display_date + VOUT_DISPLAY_TOLERANCE )
- {
- p_picture->i_flags &= ~DISPLAY_PICTURE;
- }
- /* Pictures in stream 0 are selected depending only of their date */
- else if( p_picture->i_stream == 0 )
- {
- /* Overlay pictures are not selected if they are
- * outdated */
- if( p_picture->i_flags & OVERLAY_PICTURE )
- {
- if( !(p_picture->i_flags & PERMANENT_PICTURE)
- && (display_date > p_picture->date + p_picture->duration) )
- {
- p_picture->i_flags |= DESTROY_PICTURE;
- p_picture->i_flags &= ~DISPLAY_PICTURE;
- }
- }
- /* Regular pictures are selected if they are not too late */
- else if( p_picture->date < display_date - VOUT_DISPLAY_TOLERANCE )
- {
- intf_DbgMsg("%p -> picture %p detected late\n",
- p_vout, p_picture );
- p_picture->i_flags |= DISPLAYED_PICTURE | DESTROY_PICTURE;
- p_picture->i_flags &= ~DISPLAY_PICTURE;
- }
- }
- /* Overlay pictures which have been displayed have special
- * processing */
- else if( (p_picture->i_flags & OVERLAY_PICTURE)
- && (p_picture->i_flags & DISPLAYED_PICTURE) )
- {
- /* If the stream is not empty, or the picture has been
- * outdated, de select */
- if( (p_vout->p_stream[p_picture->i_stream].p_next_picture != NULL)
- || (!(p_picture->i_flags & PERMANENT_PICTURE)
- && (display_date > p_picture->date + p_picture->duration) ) )
- {
- p_picture->i_flags |= DESTROY_PICTURE;
- p_picture->i_flags &= ~DISPLAY_PICTURE;
- }
- }
- /* Other pictures are 'regular' pictures */
- else
- {
- /* If the stream is empty, always select */
- if( p_vout->p_stream[p_picture->i_stream].p_next_picture == NULL)
- {
- p_vout->p_stream[p_picture->i_stream].p_next_picture = p_picture;
- }
- /* Else, remove and mark as displayed (skip) if the picture is too old */
- else if( p_picture->date < display_date - VOUT_DISPLAY_TOLERANCE )
- {
- intf_DbgMsg("%p -> picture %p detected late\n",
- p_vout, p_picture );
- p_picture->i_flags |= DISPLAYED_PICTURE | DESTROY_PICTURE;
- p_picture->i_flags &= ~DISPLAY_PICTURE;
- }
- /* Else, select if the picture is younger than the current selected one */
- else if( p_picture->date
- < p_vout->p_stream[p_picture->i_stream].p_next_picture->date )
- {
- /* Deselect the previous picture */
- p_vout->p_stream[p_picture->i_stream].p_next_picture->i_flags
- &= ~DISPLAY_PICTURE;
- /* Select the current one */
- p_vout->p_stream[p_picture->i_stream].p_next_picture = p_picture;
- }
- /* Else, select if the current selected one is an already displayed overlay */
- else if( (p_vout->p_stream[p_picture->i_stream].p_next_picture->i_flags
- & ( OVERLAY_PICTURE | DISPLAYED_PICTURE ))
- == (OVERLAY_PICTURE | DISPLAYED_PICTURE) )
-
- {
- /* Deselect and remove the previous picture */
- p_picture->i_flags |= DESTROY_PICTURE;
- p_picture->i_flags &= ~DISPLAY_PICTURE;
- /* Select the current one */
- p_vout->p_stream[p_picture->i_stream].p_next_picture = p_picture;
- }
- /* Else, deselect the picture */
- else
- {
- p_picture->i_flags &= ~DISPLAY_PICTURE;
- }
- }
- }
- }
-}
-
-/*******************************************************************************
- * SortPictures: sort pictures ready for display by hierarchical level
- *******************************************************************************
- * Build an array of pictures in rendering order, starting from minimal to
- * level to maximal level. A NULL pointer always ends the array, which size is
- * limited to VOUT_MAX_PICTURES.
- *******************************************************************************
- * Messages type: vout, major code 26
- *******************************************************************************/
-static void SortPictures( vout_thread_t *p_vout, picture_t **pp_picture )
-{
- int i_picture; /* picture index in sorted array */
- int i_heap_picture; /* picture index in heap */
- picture_t * p_previous_picture; /* first shift register */
- picture_t * p_current_picture; /* second shift register */
-
- /* Initialize array */
- pp_picture[0] = NULL;
-
- /* Copy and sort pictures */
- for( i_heap_picture = 0; i_heap_picture < p_vout->i_max_pictures ; i_heap_picture++ )
- {
- /* Sort only selected pictures */
- if( p_vout->p_picture[ i_heap_picture ].i_flags & DISPLAY_PICTURE )
- {
- /* Find picture position */
- for( i_picture = 0; (pp_picture[i_picture] != NULL)
- && (pp_picture[i_picture]->i_level
- <= p_vout->p_picture[ i_heap_picture ].i_level);
- i_picture++ )
- {
- ;
- }
- p_current_picture = &p_vout->p_picture[ i_heap_picture ];
-
- /* Insert picture and shift end of array */
- for( ; p_previous_picture != NULL; i_picture++ )
- {
- p_previous_picture = p_current_picture;
- p_current_picture = pp_picture[i_picture];
- if( i_picture == VOUT_MAX_PICTURES - 1 )
- {
- p_previous_picture = NULL;
- }
- pp_picture[i_picture] = p_previous_picture;
- }
- }
- }
-
-}
-
/*******************************************************************************
* RenderPicture: render a picture
*******************************************************************************
* This function convert a picture from a video heap to a pixel-encoded image
* and copy it to the current rendering buffer. No lock is required, since the
* rendered picture has been determined as existant, and will only be destroyed
- * by the vout_Thread() later.
- *******************************************************************************
- * Messages types: vout, major code 27
+ * by the vout thread later.
*******************************************************************************/
static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
{
- int i_x, i_y; /* position in display */
- int i_pic_x; /* x offset in clipped picture */
- int i_pic_y; /* y offset in clipped picture */
- int i_height, i_width; /* clipped picture dimensions */
- int i_line_width; /* line width */
- void (*RenderLine)(vout_thread_t *p_vout, picture_t *p_pic, /* renderer */
- int i_x, int i_y, int i_pic_x, int i_pic_y, int i_width,
- int i_line_width, int i_ratio );
-
- /* Update counters - this is done now since for blank pictures, the function
- * may never reach it's regular end */
- p_pic->i_flags |= DISPLAYED_PICTURE;
-#ifdef STATS
- p_vout->c_rendered_pictures++;
- p_vout->p_stream[ p_pic->i_stream ].c_rendered_pictures++;
-#endif
-
- /* Computes position and size of the picture zone to render */
- i_x = p_pic->i_x;
- i_y = p_pic->i_y;
- i_width = p_pic->i_width;
- i_height = p_pic->i_height;
- ClipPicture( &i_x, p_vout->i_width, &i_pic_x, &i_width, p_pic->i_h_ratio, p_pic->i_h_align );
- ClipPicture( &i_y, p_vout->i_height, &i_pic_y, &i_height, p_pic->i_v_ratio, p_pic->i_v_align );
-#ifdef VOUT_DEBUG
- intf_DbgMsg("%p -> picture %p, (%d-%d:%d-%d, %dx%d)\n",
- p_vout, p_pic, i_x, i_pic_x, i_y, i_pic_y, i_width, i_height );
-
-#endif
-
- /* If there is noting to display, returns immediately */
- if( (i_pic_x >= i_width) || (i_pic_y >= i_height) )
- {
- return;
- }
-
- /* Determine method used to render line. This function is choosed here to
- * avoid multiple conditions tests later */
- switch( p_pic->i_type )
- {
- case RGB_BLANK_PICTURE: /* picture is blank, RGB encoded (no data) */
- case PIXEL_BLANK_PICTURE: /* picture is blank, pixel encoded (no data) */
- /* Blank pictures are displayed immediately - dimensions are real ones,
- * and should be recalculated */
- switch( p_pic->i_h_ratio )
- {
- case DISPLAY_RATIO_HALF: /* 1:2 half size */
- i_width = (i_width - i_pic_x) / 2;
- break;
- case DISPLAY_RATIO_NORMAL: /* 1:1 normal size */
- i_width -= i_pic_x;
- break;
- case DISPLAY_RATIO_DOUBLE: /* 2:1 double size */
- i_width = (i_width - i_pic_x) * 2;
- break;
- /* ?? add others display ratio */
- }
- switch( p_pic->i_v_ratio )
- {
- case DISPLAY_RATIO_HALF: /* 1:2 half size */
- i_height = (i_height - i_pic_y) / 2;
- break;
- case DISPLAY_RATIO_NORMAL: /* 1:1 normal size */
- i_height -= i_pic_y;
- break;
- case DISPLAY_RATIO_DOUBLE: /* 2:1 double size */
- i_height = (i_height - i_pic_y) * 2;
- break;
- /* ?? add others display ratio */
- }
- if( p_pic->i_type == RGB_BLANK_PICTURE ) /* RGB blank picture */
- {
- p_vout->RenderRGBBlank( p_vout, p_pic->pixel, i_x, i_y, i_width, i_height );
- }
- else /* pixel blank picture */
- {
- p_vout->RenderPixelBlank( p_vout, p_pic->pixel, i_x, i_y, i_width, i_height );
- }
- return;
- break;
- case RGB_PICTURE: /* picture is 24 bits rgb encoded */
- RenderLine = p_vout->RenderRGBLine;
- break;
- case PIXEL_PICTURE: /* picture is pixel encoded */
- RenderLine = p_vout->RenderPixelLine;
- break;
- case RGB_MASK_PICTURE: /* picture is a 1 rgb bpp mask */
- RenderLine = p_vout->RenderRGBMaskLine;
- break;
- case PIXEL_MASK_PICTURE: /* picture is a 1 pixel bpp mask */
- RenderLine = p_vout->RenderPixelMaskLine;
- break;
- /* ?? add YUV types */
-#ifdef DEBUG
- default: /* internal error, which should never happen */
- intf_DbgMsg("%p -> unknown type for picture %p\n", p_vout, p_pic);
- break;
-#endif
- }
-
- /* For non blank pictures, loop on lines */
- for( ; i_pic_y < i_height; i_pic_y++ )
- {
- /* First step: check if line has to be rendered. This is not obvious since
- * if display ratio is less than 1:1, some of the lines don't need to
- * be displayed, and therefore do not need to be rendered. */
- switch( p_pic->i_v_ratio )
- {
- case DISPLAY_RATIO_HALF: /* 1:2 half size */
- /* Only even lines are rendered, and copied once */
- i_line_width = i_pic_y % 2;
- break;
-
- case DISPLAY_RATIO_NORMAL: /* 1:1 normal size */
- /* All lines are rendered and copied once */
- i_line_width = 1;
- break;
-
- case DISPLAY_RATIO_DOUBLE: /* 2:1 double size */
- /* All lines are rendered and copied twice */
- i_line_width = 2;
- break;
- }
-
- if( i_line_width )
- {
- /* Computed line width can be reduced if it would cause to render
- * outside the display */
- if( i_y + i_line_width > p_vout->i_height )
- {
- i_line_width = p_vout->i_height - i_y;
- }
-
- /* Second step: render line. Since direct access to the rendering
- * buffer is required, functions in charge of rendering the line
- * are part of the display driver. Because this step is critical
- * and require high optimization, different methods are used
- * depending of the horizontal display ratio, the image type and
- * the screen depth. */
- RenderLine( p_vout, p_pic, i_x, i_y, i_pic_x, i_pic_y,
- i_width, i_line_width, p_pic->i_h_ratio );
-
- /* Increment display line index */
- i_y += i_line_width;
- }
- }
-}
-
-/*******************************************************************************
- * ClipPicture: clip a picture in display window
- *******************************************************************************
- * This function computes picture placement in display window and rendering
- * zone, according to wished picture placement and display ratio. It must be
- * called twice, once and with the x coordinates and once with the y
- * coordinates.
- * The pi_pic_ofs parameter is only written, but pi_ofs and pi_pic_size must
- * be valid arguments. Note that *pi_pic_size is still the rendering zone size,
- * starting from picture offset 0 and not the size starting from *pi_pic_ofs
- * (same thing for i_size).
- *******************************************************************************
- * Messages types: vout, major code 28
- *******************************************************************************/
-static void ClipPicture( int *pi_ofs, int i_size, int *pi_pic_ofs, int *pi_pic_size,
- int i_ratio, int i_placement )
-{
- int i_ofs; /* temporary picture position */
-
- /* Computes base picture position */
- switch( i_placement )
- {
- case -1: /* left/top aligned */
- i_ofs = *pi_ofs;
- break;
- case 0: /* centered */
- i_ofs = *pi_ofs + (i_size - *pi_pic_size) / 2;
- break;
- case 1: /* right/bottom aligned */
- i_ofs = *pi_ofs + i_size - *pi_pic_size;
- break;
-#ifdef DEBUG
- default: /* internal error, which should never happen */
- intf_DbgMsg("invalid placement\n");
- break;
-#endif
- }
-
- /* Computes base rendering position and update picture position - i_ofs is
- * the picture position, and can be negative */
- if( i_ofs < 0 ) /* picture starts outside the screen */
- {
- switch( i_ratio )
- {
- case DISPLAY_RATIO_HALF: /* 1:2 half size */
- *pi_pic_ofs = - *pi_ofs * 2;
- break;
- case DISPLAY_RATIO_NORMAL: /* 1:1 normal size */
- *pi_pic_ofs = -*pi_ofs;
- break;
- case DISPLAY_RATIO_DOUBLE: /* 2:1 double size */
- *pi_pic_ofs = -CEIL(*pi_ofs, 2);
- break;
-#ifdef DEBUG
- default: /* internal error, which should never happen */
- intf_DbgMsg("unsupported ratio\n");
- break;
-#endif
- }
- *pi_ofs = 0;
- }
- else /* picture starts inside the screen */
- {
- *pi_pic_ofs = 0;
- *pi_ofs = i_ofs;
- }
-
- /* Computes rendering size - i_ofs is the picture position, and can be
- * negative, *pi_ofs is the real picture position, and is always positive */
- switch( i_ratio )
- {
- case DISPLAY_RATIO_HALF: /* 1:2 half size */
- if( i_ofs + CEIL(*pi_pic_size, 2) > i_size )
- {
- *pi_pic_size = ( i_size - i_ofs ) * 2;
- }
- break;
- case DISPLAY_RATIO_NORMAL: /* 1:1 normal size */
- if( i_ofs + *pi_pic_size > i_size )
- {
- *pi_pic_size = i_size - i_ofs;
- }
- break;
- case DISPLAY_RATIO_DOUBLE: /* 2:1 double size */
- if( *pi_ofs + *pi_pic_size * 2 > i_size )
- {
- *pi_pic_size = ( i_size - i_ofs ) / 2;
- }
- break;
-#ifdef DEBUG
- default: /* internal error, which should never happen */
- intf_DbgMsg("unsupported ratio\n");
- break;
-#endif
- }
+ /*???*/
}
/*******************************************************************************
* Preamble
*******************************************************************************/
+
+#include "vlc.h"
+/*
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include "xconsole.h"
#include "interface.h"
#include "intf_msg.h"
+*/
-#include "pgm_data.h"
+/*******************************************************************************
+ * vout_sys_t: video output X11 method descriptor
+ *******************************************************************************
+ * This structure is part of the video output thread descriptor.
+ * It describes the X11 specific properties of an output thread. X11 video
+ * output is performed through regular resizable windows. Windows can be
+ * dynamically resized to adapt to the size of the streams.
+ *******************************************************************************/
+typedef struct vout_sys_s
+{
+ /* User settings */
+ boolean_t b_shm; /* shared memory extension flag */
-/*
- * Local prototypes
- */
-static int X11CheckConfiguration ( video_cfg_t *p_cfg );
+ /* Internal settings and properties */
+ Display * p_display; /* display pointer */
+ int i_screen; /* screen number */
+ Window root_window; /* root window */
+ Window window; /* window instance handler */
+ GC gc; /* graphic context instance handler */
+
+ /* Color maps and translation tables - some of those tables are shifted,
+ * see x11.c for more informations. */
+ u8 * trans_16bpp_red; /* red (16 bpp) (SHIFTED !) */
+ u8 * trans_16bpp_green; /* green (16 bpp) (SHIFTED !) */
+ u8 * trans_16bpp_blue; /* blue (16 bpp) (SHIFTED !) */
+
+ /* Display buffers and shared memory information */
+ int i_buffer_index; /* buffer index */
+ XImage * p_ximage[2]; /* XImage pointer */
+ XShmSegmentInfo shm_info[2]; /* shared memory zone information */
-static int X11OpenDisplay ( vout_thread_t *p_vout );
+ int i_completion_type; /* ?? */
+} vout_sys_t;
+
+/*******************************************************************************
+ * Local prototypes
+ *******************************************************************************/
+static int X11GetProperties ( vout_thread_t *p_vout );
static int X11CreateWindow ( vout_thread_t *p_vout );
static int X11CreateImages ( vout_thread_t *p_vout );
static void X11DestroyImages ( vout_thread_t *p_vout );
static void X11DestroyWindow ( vout_thread_t *p_vout );
-static void X11CloseDisplay ( vout_thread_t *p_vout );
static int X11CreateImage ( vout_thread_t *p_vout, XImage **pp_ximage );
static void X11DestroyImage ( XImage *p_ximage );
static int X11CreateShmImage ( vout_thread_t *p_vout, XImage **pp_ximage,
static void X11DestroyShmImage ( vout_thread_t *p_vout, XImage *p_ximage,
XShmSegmentInfo *p_shm_info );
-static vout_render_blank_t X11RenderRGBBlank;
-static vout_render_blank_t X11RenderPixelBlank8bpp;
-static vout_render_blank_t X11RenderPixelBlank16bpp;
-static vout_render_blank_t X11RenderPixelBlank24bpp;
-static vout_render_blank_t X11RenderPixelBlank32bpp;
-static vout_render_line_t X11RenderRGBLine8bpp;
-static vout_render_line_t X11RenderRGBLine16bpp;
-static vout_render_line_t X11RenderRGBLine24bpp;
-static vout_render_line_t X11RenderRGBLine32bpp;
-static vout_render_line_t X11RenderPixelLine8bpp;
-static vout_render_line_t X11RenderPixelLine16bpp;
-static vout_render_line_t X11RenderPixelLine24bpp;
-static vout_render_line_t X11RenderPixelLine32bpp;
-static vout_render_line_t X11RenderRGBMaskLine;
-static vout_render_line_t X11RenderPixelMaskLine8bpp;
-static vout_render_line_t X11RenderPixelMaskLine16bpp;
-static vout_render_line_t X11RenderPixelMaskLine24bpp;
-static vout_render_line_t X11RenderPixelMaskLine32bpp;
-/* ?? YUV types */
/*******************************************************************************
- * vout_X11AllocOutputMethod: allocate X11 video thread output method
+ * vout_SysCreate: allocate X11 video thread output method
*******************************************************************************
- * This function creates a X11 output method descriptor in the vout_thread_t
- * desriptor and initialize it.
- * Following configuration properties are used:
- * VIDEO_CFG_DISPLAY display used
- * VIDEO_CFG_TITLE window title
- * VIDEO_CFG_SHM_EXT try to use XShm extension
+ * This function allocate and initialize a X11 vout method.
*******************************************************************************/
-int vout_X11AllocOutputMethod( vout_thread_t *p_vout, video_cfg_t *p_cfg )
+int vout_SysCreate( vout_thread_t *p_vout, Display *p_display, Window root_window )
{
- /* Check configuration */
- if( X11CheckConfiguration(p_cfg) )
- {
- return( 1 );
- }
-
- /* Allocate descriptor */
- p_vout->p_x11 = (vout_x11_t *) malloc( sizeof( vout_x11_t ) );
- if( p_vout->p_x11 == NULL )
- {
- intf_ErrMsg("vout error 101-1: cannot allocate X11 method descriptor: %s\n",
- strerror(errno));
- return( 1 );
- }
-
- /* Initialize fields - string passed in configuration structure are copied
- * since they can be destroyed at any moment - remember that NULL is a valid
- * value for psz_display */
- p_vout->p_x11->psz_title = (char *) malloc( strlen(p_cfg->psz_title) + 1);
- if( p_vout->p_x11->psz_title == NULL )
- {
- free( p_vout->p_x11 );
- return( 1 );
- }
- strcpy( p_vout->p_x11->psz_title, p_cfg->psz_title );
- if( p_cfg->psz_display != NULL )
- {
- p_vout->p_x11->psz_display = (char *) malloc( strlen(p_cfg->psz_display) + 1);
- if( p_vout->p_x11->psz_display == NULL )
- {
- free( p_vout->p_x11->psz_title );
- free( p_vout->p_x11 );
- return( 1 );
- }
- strcpy( p_vout->p_x11->psz_display, p_cfg->psz_display );
- }
- else
+ p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
+ if( p_vout->p_sys != NULL )
{
- p_vout->p_x11->psz_display = NULL;
+ p_vout->p_sys->p_display = p_display;
+ p_vout->p_sys->root_window = root_window;
+ return( 0 );
}
- p_vout->p_x11->b_shm_ext = p_cfg->b_shm_ext;
- return( 0 );
-}
-/*******************************************************************************
- * vout_X11FreeOutputMethod: free X11 video thread output method
- *******************************************************************************
- * Free an X11 video thread output method allocated by
- * vout_X11AllocOutputMethod()
- *******************************************************************************/
-void vout_X11FreeOutputMethod( vout_thread_t *p_vout )
-{
- if( p_vout->p_x11->psz_display != NULL )
- {
- free( p_vout->p_x11->psz_display );
- }
- free( p_vout->p_x11->psz_title );
- free( p_vout->p_x11 );
+ return( 1 );
}
/*******************************************************************************
- * vout_X11CreateOutputMethod: create X11 video thread output method
+ * vout_SysInit: initialize X11 video thread output method
*******************************************************************************
- * This function opens a display and create a X11 window according to the user
- * configuration.
+ * This function create a X11 window according to the user configuration.
*******************************************************************************/
-int vout_X11CreateOutputMethod( vout_thread_t *p_vout )
+int vout_SysInit( vout_thread_t *p_vout )
{
- if( X11OpenDisplay( p_vout ) ) /* open display */
+ if( X11GetProperties( p_vout ) ) /* get display properties */
{
- free( p_vout->p_x11 );
- return( 1 );
+ return( 1 );
}
if( X11CreateWindow( p_vout ) ) /* create window */
{
- X11CloseDisplay( p_vout );
- free( p_vout->p_x11 );
return( 1 );
}
if( X11CreateImages( p_vout ) ) /* create images */
{
X11DestroyWindow( p_vout );
- X11CloseDisplay( p_vout );
- free( p_vout->p_x11 );
return( 1 );
}
- intf_DbgMsg("%p -> success, depth=%d bpp, XShm=%d\n",
- p_vout, p_vout->i_screen_depth, p_vout->p_x11->b_shm_ext);
+ intf_DbgMsg("%p -> success, depth=%d bpp, Shm=%d\n",
+ p_vout, p_vout->i_screen_depth, p_vout->p_sys->b_shm );
return( 0 );
}
/*******************************************************************************
- * vout_X11DestroyOutputMethod: destroy X11 video thread output method
- *******************************************************************************
- * Destroys an output method created by vout_X11CreateOutputMethod
+ * vout_SysEnd: terminate X11 video thread output method
*******************************************************************************
- * Messages type: vout, major code: 102
+ * Terminate an output method created by vout_X11CreateOutputMethod
*******************************************************************************/
-void vout_X11DestroyOutputMethod( vout_thread_t *p_vout )
+void vout_SysEnd( vout_thread_t *p_vout )
{
X11DestroyImages( p_vout );
X11DestroyWindow( p_vout );
- X11CloseDisplay( p_vout );
intf_DbgMsg("%p\n", p_vout );
}
/*******************************************************************************
- * vout_X11ManageOutputMethod: handle X11 events
+ * vout_SysDestroy: destroy X11 video thread output method
+ *******************************************************************************
+ * Terminate an output method created by vout_X11CreateOutputMethod
+ *******************************************************************************/
+void vout_SysDestroy( vout_thread_t *p_vout )
+{
+ free( p_vout->p_sys );
+}
+
+/*******************************************************************************
+ * vout_SysManage: handle X11 events
*******************************************************************************
* This function should be called regularly by video output thread. It manages
* X11 events and allows window resizing. It returns a negative value if
*******************************************************************************
* Messages type: vout, major code: 103
*******************************************************************************/
-int vout_X11ManageOutputMethod( vout_thread_t *p_vout )
+int vout_SysManage( vout_thread_t *p_vout )
{
- XEvent xevent; /* X11 event */
- boolean_t b_resized; /* window has been resized */
-
- /* Handle X11 events: ConfigureNotify events are parsed to know if the
- * output window's size changed, MapNotify and UnmapNotify to know if the
- * window is mapped (and if the display is usefull), and ClientMessages
- * to intercept window destruction requests */
- b_resized = 0;
- while( XCheckWindowEvent( p_vout->p_x11->p_display, p_vout->p_x11->window,
- StructureNotifyMask, &xevent ) == True )
- {
- /* ConfigureNotify event: prepare */
- if( (xevent.type == ConfigureNotify)
- && ((xevent.xconfigure.width != p_vout->i_width)
- || (xevent.xconfigure.height != p_vout->i_height)) )
- {
- /* Update dimensions */
- b_resized = 1;
- p_vout->i_width = xevent.xconfigure.width;
- p_vout->i_height = xevent.xconfigure.height;
- }
- /* MapNotify event: change window status and disable screen saver */
- else if( (xevent.type == MapNotify) && !p_vout->b_active )
- {
- XDisableScreenSaver( p_vout->p_x11->p_display );
- p_vout->b_active = 1;
- }
- /* UnmapNotify event: change window status and enable screen saver */
- else if( (xevent.type == UnmapNotify) && p_vout->b_active )
- {
- XEnableScreenSaver( p_vout->p_x11->p_display );
- p_vout->b_active = 0;
- }
- /* ClientMessage event - only WM_PROTOCOLS with WM_DELETE_WINDOW data
- * are handled - according to the man pages, the format is always 32
- * in this case */
- else if( (xevent.type == ClientMessage)
-/* && (xevent.xclient.message_type == p_vout->p_x11->wm_protocols)
- && (xevent.xclient.data.l[0] == p_vout->p_x11->wm_delete_window )*/ )
- {
- intf_DbgMsg("******* ClientMessage ******\n");
-
- /* ?? this never happens :( */
- return( -1 );
- }
-#ifdef DEBUG
- /* Other event */
- else
- {
- intf_DbgMsg("%p -> unhandled event type %d received\n", p_vout, xevent.type );
- }
-#endif
- }
+ boolean_t b_resized;
+ //??
+
+ /* ?? this function should not receive any usefull X11 messages, since they
+ * have tobe treated by the main interface window - check it. */
+ return 0; //??
+
/* If window has been resized, re-create images */
if( b_resized )
}
/*******************************************************************************
- * vout_X11DisplayOutput: displays previously rendered output
+ * vout_SysDisplay: displays previously rendered output
*******************************************************************************
* This function send the currently rendered image to X11 server, wait until
* it is displayed and switch the two rendering buffer, preparing next frame.
- *******************************************************************************
- * Messages type: vout, major code: 105
*******************************************************************************/
-void vout_X11DisplayOutput( vout_thread_t *p_vout )
+void vout_SysDisplay( vout_thread_t *p_vout )
{
- if( p_vout->p_x11->b_shm_ext) /* XShm is used */
+ if( p_vout->p_sys->b_shm) /* XShm is used */
{
/* Display rendered image using shared memory extension */
- XShmPutImage(p_vout->p_x11->p_display, p_vout->p_x11->window, p_vout->p_x11->gc,
- p_vout->p_x11->p_ximage[ p_vout->p_x11->i_buffer_index ],
+ XShmPutImage(p_vout->p_sys->p_display, p_vout->p_sys->window, p_vout->p_sys->gc,
+ p_vout->p_sys->p_ximage[ p_vout->p_sys->i_buffer_index ],
0, 0, 0, 0,
- p_vout->p_x11->p_ximage[ p_vout->p_x11->i_buffer_index ]->width,
- p_vout->p_x11->p_ximage[ p_vout->p_x11->i_buffer_index ]->height, True);
+ p_vout->p_sys->p_ximage[ p_vout->p_sys->i_buffer_index ]->width,
+ p_vout->p_sys->p_ximage[ p_vout->p_sys->i_buffer_index ]->height, True);
/* Send the order to the X server */
- XFlush(p_vout->p_x11->p_display);
+ XFlush(p_vout->p_sys->p_display);
/* ?? wait until effective display ? */
/* do XNextEvent(Display_Ptr, &xev);
}
else /* regular X11 capabilities are used */
{
- XPutImage(p_vout->p_x11->p_display, p_vout->p_x11->window, p_vout->p_x11->gc,
- p_vout->p_x11->p_ximage[ p_vout->p_x11->i_buffer_index ],
+ XPutImage(p_vout->p_sys->p_display, p_vout->p_sys->window, p_vout->p_sys->gc,
+ p_vout->p_sys->p_ximage[ p_vout->p_sys->i_buffer_index ],
0, 0, 0, 0,
- p_vout->p_x11->p_ximage[ p_vout->p_x11->i_buffer_index ]->width,
- p_vout->p_x11->p_ximage[ p_vout->p_x11->i_buffer_index ]->height);
+ p_vout->p_sys->p_ximage[ p_vout->p_sys->i_buffer_index ]->width,
+ p_vout->p_sys->p_ximage[ p_vout->p_sys->i_buffer_index ]->height);
+
/* Send the order to the X server */
- XFlush(p_vout->p_x11->p_display); /* ?? not needed ? */
+ XFlush(p_vout->p_sys->p_display); /* ?? not needed ? */
}
/* Swap buffers */
- p_vout->p_x11->i_buffer_index = ++p_vout->p_x11->i_buffer_index & 1;
+ p_vout->p_sys->i_buffer_index = ++p_vout->p_sys->i_buffer_index & 1;
}
/* following functions are local */
/*******************************************************************************
- * X11CheckConfiguration: check configuration.
+ * X11GetProperties: get properties of a given display
*******************************************************************************
- * Set default parameters where required. In DEBUG mode, check if configuration
- * is valid.
- *******************************************************************************
- * Messages type: vout, major code: 116
+ * Opens an X11 display and try to detect usable X extensions.
*******************************************************************************/
-static int X11CheckConfiguration( video_cfg_t *p_cfg )
+static int X11GetProperties( vout_thread_t *p_vout )
{
- /* Window dimensions */
- if( !( p_cfg->i_properties & VIDEO_CFG_WIDTH ) )
- {
- p_cfg->i_width = VOUT_WIDTH;
- }
- if( !( p_cfg->i_properties & VIDEO_CFG_HEIGHT ) )
- {
- p_cfg->i_height = VOUT_HEIGHT;
- }
-
- /* Display */
- if( !( p_cfg->i_properties & VIDEO_CFG_DISPLAY ) )
- {
- p_cfg->psz_display = NULL;
- }
-
- /* Window title */
- if( !( p_cfg->i_properties & VIDEO_CFG_TITLE ) )
- {
- p_cfg->psz_title = VOUT_TITLE;
- }
-
- /* Use of XShm extension */
- if( !( p_cfg->i_properties & VIDEO_CFG_SHM_EXT ) )
- {
- p_cfg->b_shm_ext = VOUT_SHM_EXT;
- }
-
- return( 0 );
-}
-
-/*******************************************************************************
- * X11OpenDisplay: open X11 display
- *******************************************************************************
- * Opens an X11 display and set up pictures rendering functions according to
- * screen depth.
- * Following configuration properties are used:
- * VIDEO_CFG_DISPLAY display used
- * VIDEO_CFG_SHM_EXT try to use XShm extension
- *******************************************************************************
- * Messages type: vout, major code: 106
- *******************************************************************************/
-static int X11OpenDisplay( vout_thread_t *p_vout )
-{
- char *psz_display;
-
- /* Open display, using display name provided or default one */
- psz_display = XDisplayName( p_vout->p_x11->psz_display );
- p_vout->p_x11->p_display = XOpenDisplay( psz_display );
- if( !p_vout->p_x11->p_display ) /* error */
- {
- intf_ErrMsg("vout error 106-1: can't open display %s\n", psz_display );
- return( 1 );
- }
-
- /* Check if XShm extension is wished and supported */
- /* ?? in old client, we checked if display was local or not - is it really
- * needed ? */
- if( p_vout->p_x11->b_shm_ext )
- {
- p_vout->p_x11->b_shm_ext = (XShmQueryExtension(p_vout->p_x11->p_display) == True);
- }
- else
- {
- p_vout->p_x11->b_shm_ext = 0;
- }
+ /* Check if extensions are supported */
+ p_vout->p_sys->b_shm = VOUT_XSHM && (XShmQueryExtension(p_vout->p_sys->p_display) == True);
/* Get the screen number and depth (bpp) - select functions depending
* of this value. i_bytes_per_pixel is required since on some hardware,
* depth as 15bpp are used, which can cause problems with later memory
* allocation. */
- p_vout->p_x11->i_screen = DefaultScreen( p_vout->p_x11->p_display );
- p_vout->i_screen_depth = DefaultDepth( p_vout->p_x11->p_display,
- p_vout->p_x11->i_screen );
+ p_vout->p_sys->i_screen = DefaultScreen( p_vout->p_sys->p_display );
+ p_vout->i_screen_depth = DefaultDepth( p_vout->p_sys->p_display,
+ p_vout->p_sys->i_screen );
switch( p_vout->i_screen_depth )
{
- case 8: /* 8 bpp (256 colors) */
- p_vout->i_bytes_per_pixel = 1;
- p_vout->RenderRGBBlank = X11RenderRGBBlank;
- p_vout->RenderPixelBlank = X11RenderPixelBlank8bpp;
- p_vout->RenderRGBLine = X11RenderRGBLine8bpp;
- p_vout->RenderPixelLine = X11RenderPixelLine8bpp;
- p_vout->RenderRGBMaskLine = X11RenderRGBMaskLine;
- p_vout->RenderPixelMaskLine = X11RenderPixelMaskLine8bpp;
- /*
- Process_Frame=Dither_Frame;
- Process_Top_Field=Dither_Top_Field;
- Process_Bottom_Field=Dither_Bottom_Field;
- Process_Top_Field420=Dither_Top_Field420;
- Process_Bottom_Field420=Dither_Bottom_Field420; ?? */
- break;
-
case 15: /* 15 bpp (16bpp with a missing green bit) */
p_vout->i_bytes_per_pixel = 2;
/*
?? */
- p_vout->RenderRGBBlank = X11RenderRGBBlank;
- p_vout->RenderPixelBlank = X11RenderPixelBlank16bpp;
- p_vout->RenderRGBLine = X11RenderRGBLine16bpp;
- p_vout->RenderPixelLine = X11RenderPixelLine16bpp;
- p_vout->RenderRGBMaskLine = X11RenderRGBMaskLine;
- p_vout->RenderPixelMaskLine = X11RenderPixelMaskLine16bpp;
- /* ?? probably a 16bpp with differenr convertion functions - just map
- * functions, then switch to 16bpp */
break;
case 16: /* 16 bpp (65536 colors) */
p_vout->i_bytes_per_pixel = 2;
- p_vout->RenderRGBBlank = X11RenderRGBBlank;
- p_vout->RenderPixelBlank = X11RenderPixelBlank16bpp;
- p_vout->RenderRGBLine = X11RenderRGBLine16bpp;
- p_vout->RenderPixelLine = X11RenderPixelLine16bpp;
- p_vout->RenderRGBMaskLine = X11RenderRGBMaskLine;
- p_vout->RenderPixelMaskLine = X11RenderPixelMaskLine16bpp;
/*
Process_Frame=Translate_Frame;
Process_Top_Field=Translate_Top_Field;
case 24: /* 24 bpp (millions of colors) */
p_vout->i_bytes_per_pixel = 3;
- p_vout->RenderRGBBlank = X11RenderRGBBlank;
- p_vout->RenderPixelBlank = X11RenderPixelBlank24bpp;
- p_vout->RenderRGBLine = X11RenderRGBLine24bpp;
- p_vout->RenderPixelLine = X11RenderPixelLine24bpp;
- p_vout->RenderRGBMaskLine = X11RenderRGBMaskLine;
- p_vout->RenderPixelMaskLine = X11RenderPixelMaskLine24bpp;
+
/*
Process_Frame=Translate_Frame;
Process_Top_Field=Translate_Top_Field;
case 32: /* 32 bpp (millions of colors) */
p_vout->i_bytes_per_pixel = 4;
- p_vout->RenderRGBBlank = X11RenderRGBBlank;
- p_vout->RenderPixelBlank = X11RenderPixelBlank32bpp;
- p_vout->RenderRGBLine = X11RenderRGBLine32bpp;
- p_vout->RenderPixelLine = X11RenderPixelLine32bpp;
- p_vout->RenderRGBMaskLine = X11RenderRGBMaskLine;
- p_vout->RenderPixelMaskLine = X11RenderPixelMaskLine32bpp;
/*
Process_Frame=Translate_Frame;
Process_Top_Field=Translate_Top_Field;
default: /* unsupported screen depth */
intf_ErrMsg("vout error 106-2: screen depth %i is not supported\n",
- p_vout->i_screen_depth);
- XCloseDisplay( p_vout->p_x11->p_display );
+ p_vout->i_screen_depth);
return( 1 );
break;
}
}
/*******************************************************************************
- * X11CreateWindow: create X11 window
+ * X11CreateWindow: create X11 vout window
*******************************************************************************
- * Create and set-up the output window.
- * Following configuration properties are used:
- * VIDEO_CFG_WIDTH window width
- * VIDEO_CFG_HEIGHT window height
- * VIDEO_CFG_TITLE window title
- *******************************************************************************
- * Messages type: vout, major code: 107
+ * The video output window will be created. Normally, this window is wether
+ * full screen or part of a parent window. Therefore, it does not need a
+ * title or other hints. Thery are still supplied in case the window would be
+ * spawned as a standalone one by the interface.
*******************************************************************************/
static int X11CreateWindow( vout_thread_t *p_vout )
{
- XSizeHints xsize_hints;
XSetWindowAttributes xwindow_attributes;
XGCValues xgcvalues;
XEvent xevent;
boolean_t b_expose;
- boolean_t b_configure_notify;
boolean_t b_map_notify;
- /* Prepare window manager hints and properties */
- xsize_hints.base_width = p_vout->i_width;
- xsize_hints.base_height = p_vout->i_height;
- xsize_hints.flags = PSize;
- p_vout->p_x11->wm_protocols = XInternAtom( p_vout->p_x11->p_display, "WM_PROTOCOLS", True );
- p_vout->p_x11->wm_delete_window = XInternAtom( p_vout->p_x11->p_display, "WM_DELETE_WINDOW", True );
- /* ?? add icons and placement hints ? */
-
/* Prepare window attributes */
xwindow_attributes.backing_store = Always; /* save the hidden part */
/* Create the window and set hints - the window must receive ConfigureNotify
* events, and, until it is displayed, Expose and MapNotify events. */
- p_vout->p_x11->window = XCreateSimpleWindow( p_vout->p_x11->p_display,
- DefaultRootWindow( p_vout->p_x11->p_display ),
- 0, 0,
- p_vout->i_width, p_vout->i_height,
- 0, 0, 0);
- XSelectInput( p_vout->p_x11->p_display, p_vout->p_x11->window,
+ p_vout->p_sys->window = XCreateSimpleWindow( p_vout->p_sys->p_display,
+ p_vout->p_sys->root_window,
+ 0, 0,
+ p_vout->i_width, p_vout->i_height,
+ 0, 0, 0);
+ XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window,
ExposureMask | StructureNotifyMask );
- XChangeWindowAttributes( p_vout->p_x11->p_display, p_vout->p_x11->window,
+ XChangeWindowAttributes( p_vout->p_sys->p_display, p_vout->p_sys->window,
CWBackingStore, &xwindow_attributes);
- /* Set window manager hints and properties: size hints, command, window's name,
- * and accepted protocols */
- XSetWMNormalHints( p_vout->p_x11->p_display, p_vout->p_x11->window, &xsize_hints );
- XSetCommand( p_vout->p_x11->p_display, p_vout->p_x11->window,
- p_program_data->ppsz_argv, p_program_data->i_argc );
- XStoreName( p_vout->p_x11->p_display, p_vout->p_x11->window, p_vout->p_x11->psz_title );
- if( (p_vout->p_x11->wm_protocols == None) /* use WM_DELETE_WINDOW */
- || (p_vout->p_x11->wm_delete_window == None)
- || !XSetWMProtocols( p_vout->p_x11->p_display, p_vout->p_x11->window,
- &p_vout->p_x11->wm_delete_window, 1 ) )
- {
- /* WM_DELETE_WINDOW is not supported by window manager */
- intf_Msg("vout: missing or bad window manager - please exit program kindly.\n");
- }
-
/* Creation of a graphic context that doesn't generate a GraphicsExpose event
when using functions like XCopyArea */
xgcvalues.graphics_exposures = False;
- p_vout->p_x11->gc = XCreateGC( p_vout->p_x11->p_display, p_vout->p_x11->window,
+ p_vout->p_sys->gc = XCreateGC( p_vout->p_sys->p_display, p_vout->p_sys->window,
GCGraphicsExposures, &xgcvalues);
- /* Create color system */
- /*?? if( CreateX11Colors( p_vout ) )
- {
- intf_ErrMsg("vout error 107-1: can't initialize color system\n");
- XCloseDisplay( p_vout->p_x11->p_display );
- return( - 1 );
- }*/
-
- /* Send orders to server, and wait until window is displayed - three events
+ /* Send orders to server, and wait until window is displayed - two events
* must be received: a MapNotify event, an Expose event allowing drawing in the
- * window, and a ConfigureNotify to get the window dimensions. Once those events
- * have been received, only ConfigureNotify events need to be received. */
+ * window */
b_expose = 0;
- b_configure_notify = 0;
b_map_notify = 0;
- XMapWindow( p_vout->p_x11->p_display, p_vout->p_x11->window);
+ XMapWindow( p_vout->p_sys->p_display, p_vout->p_sys->window);
do
{
- XNextEvent( p_vout->p_x11->p_display, &xevent);
+ XNextEvent( p_vout->p_sys->p_display, &xevent);
if( (xevent.type == Expose)
- && (xevent.xexpose.window == p_vout->p_x11->window) )
+ && (xevent.xexpose.window == p_vout->p_sys->window) )
{
b_expose = 1;
}
else if( (xevent.type == MapNotify)
- && (xevent.xmap.window == p_vout->p_x11->window) )
+ && (xevent.xmap.window == p_vout->p_sys->window) )
{
b_map_notify = 1;
}
- else if( (xevent.type == ConfigureNotify)
- && (xevent.xconfigure.window == p_vout->p_x11->window) )
- {
- b_configure_notify = 1;
- p_vout->i_width = xevent.xconfigure.width;
- p_vout->i_height = xevent.xconfigure.height;
- }
}
- while( !( b_expose && b_configure_notify && b_map_notify ) );
- XSelectInput( p_vout->p_x11->p_display, p_vout->p_x11->window, StructureNotifyMask );
+ while( !( b_expose && b_map_notify ) );
+ XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window, 0 );
/* At this stage, the window is openned, displayed, and ready to receive data */
p_vout->b_active = 1;
/* Create XImages using XShm extension - on failure, fall back to regular
* way (and destroy the first image if it was created successfully) */
- if( p_vout->p_x11->b_shm_ext )
+ if( p_vout->p_sys->b_shm )
{
/* Create first image */
- i_err = X11CreateShmImage( p_vout, &p_vout->p_x11->p_ximage[0],
- &p_vout->p_x11->shm_info[0] );
+ i_err = X11CreateShmImage( p_vout, &p_vout->p_sys->p_ximage[0],
+ &p_vout->p_sys->shm_info[0] );
if( !i_err ) /* first image has been created */
{
/* Create second image */
- if( X11CreateShmImage( p_vout, &p_vout->p_x11->p_ximage[1],
- &p_vout->p_x11->shm_info[1] ) )
+ if( X11CreateShmImage( p_vout, &p_vout->p_sys->p_ximage[1],
+ &p_vout->p_sys->shm_info[1] ) )
{ /* error creating the second image */
- X11DestroyShmImage( p_vout, p_vout->p_x11->p_ximage[0],
- &p_vout->p_x11->shm_info[0] );
+ X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[0],
+ &p_vout->p_sys->shm_info[0] );
i_err = 1;
}
}
if( i_err ) /* an error occured */
{
intf_Msg("vout: XShm extension desactivated\n" );
- p_vout->p_x11->b_shm_ext = 0;
+ p_vout->p_sys->b_shm = 0;
}
}
/* Create XImages without XShm extension */
- if( !p_vout->p_x11->b_shm_ext )
+ if( !p_vout->p_sys->b_shm )
{
- if( X11CreateImage( p_vout, &p_vout->p_x11->p_ximage[0] ) )
+ if( X11CreateImage( p_vout, &p_vout->p_sys->p_ximage[0] ) )
{
intf_Msg("vout error 108-1: can't create images\n");
- p_vout->p_x11->p_ximage[0] = NULL;
- p_vout->p_x11->p_ximage[1] = NULL;
+ p_vout->p_sys->p_ximage[0] = NULL;
+ p_vout->p_sys->p_ximage[1] = NULL;
return( -1 );
}
- if( X11CreateImage( p_vout, &p_vout->p_x11->p_ximage[1] ) )
+ if( X11CreateImage( p_vout, &p_vout->p_sys->p_ximage[1] ) )
{
intf_Msg("vout error 108-2: can't create images\n");
- X11DestroyImage( p_vout->p_x11->p_ximage[0] );
- p_vout->p_x11->p_ximage[0] = NULL;
- p_vout->p_x11->p_ximage[1] = NULL;
+ X11DestroyImage( p_vout->p_sys->p_ximage[0] );
+ p_vout->p_sys->p_ximage[0] = NULL;
+ p_vout->p_sys->p_ximage[1] = NULL;
return( -1 );
}
}
/* Set buffer index to 0 */
- p_vout->p_x11->i_buffer_index = 0;
+ p_vout->p_sys->i_buffer_index = 0;
return( 0 );
}
*******************************************************************************/
static void X11DestroyImages( vout_thread_t *p_vout )
{
- if( p_vout->p_x11->b_shm_ext ) /* Shm XImages... */
+ if( p_vout->p_sys->b_shm ) /* Shm XImages... */
{
- X11DestroyShmImage( p_vout, p_vout->p_x11->p_ximage[0],
- &p_vout->p_x11->shm_info[0] );
- X11DestroyShmImage( p_vout, p_vout->p_x11->p_ximage[1],
- &p_vout->p_x11->shm_info[1] );
+ X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[0],
+ &p_vout->p_sys->shm_info[0] );
+ X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[1],
+ &p_vout->p_sys->shm_info[1] );
}
else /* ...or regular XImages */
{
- X11DestroyImage( p_vout->p_x11->p_ximage[0] );
- X11DestroyImage( p_vout->p_x11->p_ximage[1] );
+ X11DestroyImage( p_vout->p_sys->p_ximage[0] );
+ X11DestroyImage( p_vout->p_sys->p_ximage[1] );
}
}
*******************************************************************************/
static void X11DestroyWindow( vout_thread_t *p_vout )
{
- XUnmapWindow( p_vout->p_x11->p_display, p_vout->p_x11->window );
-/* ?? DestroyX11Colors( p_vout ); */
- /* ?? no more valid: colormap */
-/* if( p_vout->p_x11->b_private_colormap )
- {
- XFreeColormap( p_vout->p_x11->p_display, p_vout->p_x11->private_colormap);
- } */
- XFreeGC( p_vout->p_x11->p_display, p_vout->p_x11->gc );
- XDestroyWindow( p_vout->p_x11->p_display, p_vout->p_x11->window );
-}
-
-/*******************************************************************************
- * X11CloseDisplay: close X11 display
- *******************************************************************************
- * Close an X11 display openned by vout_X11OpenDisplay().
- *******************************************************************************
- * Messages type: vout, major code: 111
- *******************************************************************************/
-static void X11CloseDisplay( vout_thread_t *p_vout )
-{
- XCloseDisplay( p_vout->p_x11->p_display ); /* close display */
+ intf_DbgMsg("vout window: 0x%x\n", p_vout->p_sys->window );
+ XUnmapWindow( p_vout->p_sys->p_display, p_vout->p_sys->window );
+ XFreeGC( p_vout->p_sys->p_display, p_vout->p_sys->gc );
+ XDestroyWindow( p_vout->p_sys->p_display, p_vout->p_sys->window );
}
/*******************************************************************************
}
/* Create XImage */
- *pp_ximage = XCreateImage( p_vout->p_x11->p_display,
- DefaultVisual(p_vout->p_x11->p_display, p_vout->p_x11->i_screen),
+ *pp_ximage = XCreateImage( p_vout->p_sys->p_display,
+ DefaultVisual(p_vout->p_sys->p_display, p_vout->p_sys->i_screen),
p_vout->i_screen_depth, ZPixmap, 0, pb_data,
p_vout->i_width, p_vout->i_height, i_quantum, 0);
if(! *pp_ximage ) /* error */
XShmSegmentInfo *p_shm_info)
{
/* Create XImage */
- *pp_ximage = XShmCreateImage( p_vout->p_x11->p_display,
- DefaultVisual(p_vout->p_x11->p_display, p_vout->p_x11->i_screen),
+ *pp_ximage = XShmCreateImage( p_vout->p_sys->p_display,
+ DefaultVisual(p_vout->p_sys->p_display, p_vout->p_sys->i_screen),
p_vout->i_screen_depth, ZPixmap, 0,
p_shm_info, p_vout->i_width, p_vout->i_height );
if(! *pp_ximage ) /* error */
/* Attach shared memory segment to X server (read only) */
p_shm_info->readOnly = True;
- if( XShmAttach( p_vout->p_x11->p_display, p_shm_info ) == False ) /* error */
+ if( XShmAttach( p_vout->p_sys->p_display, p_shm_info ) == False ) /* error */
{
intf_ErrMsg("vout error 113-4: can't attach shared memory to server\n");
shmdt( p_shm_info->shmaddr ); /* detach shared memory from process
/* ?? don't know what it is. Function XShmGetEventBase prototype is defined
* in mit-shm document, but does not appears in any header. */
- p_vout->p_x11->i_completion_type = XShmGetEventBase(p_vout->p_x11->p_display) + ShmCompletion;
+ p_vout->p_sys->i_completion_type = XShmGetEventBase(p_vout->p_sys->p_display) + ShmCompletion;
return( 0 );
}
return;
}
- XShmDetach( p_vout->p_x11->p_display, p_shm_info ); /* detach from server */
+ XShmDetach( p_vout->p_sys->p_display, p_shm_info ); /* detach from server */
XDestroyImage( p_ximage );
if( shmdt( p_shm_info->shmaddr ) ) /* detach shared memory from process */
{ /* also automatic freeing... */
/* following functions are local rendering functions */
-/*******************************************************************************
- * X11RenderRGBBlank: RGB blank picture rendering function
- *******************************************************************************
- * Render a blank picture. Opposed to other rendering function, this one is
- * picture-based and not line-based. Dimensions sent as parameters are effective
- * dimensions of the rectangle to draw.
- *******************************************************************************
- * Messages type: vout, major code: ???
- *******************************************************************************/
-static void X11RenderRGBBlank( vout_thread_t *p_vout, pixel_t pixel,
- int i_x, int i_y, int i_width, int i_height )
-{
- /* ?? convert rgb->pixel */
- /* ?? call p_vout->RenderPixelBlank */
-}
-
-/*******************************************************************************
- * X11RenderPixelBlank*: pixel blank picture rendering functions
- *******************************************************************************
- * Render a blank picture. Opposed to other rendering function, this one is
- * picture-based and not line-based. Dimensions sent as parameters are effective
- * dimensions of the rectangle to draw.
- *******************************************************************************
- * Messages type: vout, major code: 117
- *******************************************************************************/
-static void X11RenderPixelBlank8bpp( vout_thread_t *p_vout, pixel_t pixel,
- int i_x, int i_y, int i_width, int i_height )
-{
- int i_line; /* current line */
- int i_bytes_per_line; /* XImage bytes per line */
- byte_t * p_data; /* XImage data */
-
- i_bytes_per_line = p_vout->p_x11->p_ximage[ p_vout->p_x11->i_buffer_index ]->bytes_per_line;
- p_data = p_vout->p_x11->p_ximage[ p_vout->p_x11->i_buffer_index ]->data + i_bytes_per_line * i_y;
-
- for( i_line = i_y; i_line < i_y + i_height; i_line++, p_data += i_bytes_per_line )
- {
- memset( p_data + i_x, pixel, i_width - i_x );
- }
-}
-
-static void X11RenderPixelBlank16bpp( vout_thread_t *p_vout, pixel_t pixel,
- int i_x, int i_y, int i_width, int i_height )
-{
- int i_line; /* current line */
- int i_pixel; /* pixel offset */
- int i_bytes_per_line; /* XImage bytes per line */
- byte_t * p_data; /* XImage data */
-
- i_bytes_per_line = p_vout->p_x11->p_ximage[ p_vout->p_x11->i_buffer_index ]->bytes_per_line;
- p_data = p_vout->p_x11->p_ximage[ p_vout->p_x11->i_buffer_index ]->data + i_bytes_per_line * i_y;
-
- for( i_line = i_y; i_line < i_y + i_height; i_line++, p_data += i_bytes_per_line )
- {
- for( i_pixel = 0; i_pixel < i_width; i_pixel++ )
- {
- ((u16 *)p_data)[ i_x + i_pixel ] = pixel;
- }
- break;
- }
-}
-
-static void X11RenderPixelBlank24bpp( vout_thread_t *p_vout, pixel_t pixel,
- int i_x, int i_y, int i_width, int i_height )
-{
- int i_line; /* current line */
- int i_pixel; /* pixel offset */
- int i_bytes_per_line; /* XImage bytes per line */
- byte_t * p_data; /* XImage data */
-
- i_bytes_per_line = p_vout->p_x11->p_ximage[ p_vout->p_x11->i_buffer_index ]->bytes_per_line;
- p_data = p_vout->p_x11->p_ximage[ p_vout->p_x11->i_buffer_index ]->data + i_bytes_per_line * i_y;
-
- for( i_line = i_y; i_line < i_y + i_height; i_line++, p_data += i_bytes_per_line )
- {
- for( i_pixel = 0; i_pixel < i_width; i_pixel++ )
- {
- *(u32 *)(p_data + (i_x + i_pixel) * 3) |= pixel;
- }
- }
-}
-
-static void X11RenderPixelBlank32bpp( vout_thread_t *p_vout, pixel_t pixel,
- int i_x, int i_y, int i_width, int i_height )
-{
- int i_line; /* current line */
- int i_pixel; /* pixel offset */
- int i_bytes_per_line; /* XImage bytes per line */
- byte_t * p_data; /* XImage data */
-
- i_bytes_per_line = p_vout->p_x11->p_ximage[ p_vout->p_x11->i_buffer_index ]->bytes_per_line;
- p_data = p_vout->p_x11->p_ximage[ p_vout->p_x11->i_buffer_index ]->data + i_bytes_per_line * i_y;
-
- for( i_line = i_y; i_line < i_y + i_height; i_line++, p_data += i_bytes_per_line )
- {
- for( i_pixel = 0; i_pixel < i_width; i_pixel++ )
- {
- ((u32 *)p_data)[ i_x + i_pixel ] = pixel;
- }
- break;
- }
-}
-
-/*******************************************************************************
- * X11RenderRGBLine*: RGB picture rendering functions
- *******************************************************************************
- * Render a 24bpp RGB-encoded picture line.
- *******************************************************************************
- * Messages type: vout, major code: 118
- *******************************************************************************/
-static void X11RenderRGBLine8bpp( vout_thread_t *p_vout, picture_t *p_pic,
- int i_x, int i_y, int i_pic_x, int i_pic_y,
- int i_width, int i_line_width, int i_ratio )
-{
- /* ?? */
-}
-
-static void X11RenderRGBLine16bpp( vout_thread_t *p_vout, picture_t *p_pic,
- int i_x, int i_y, int i_pic_x, int i_pic_y,
- int i_width, int i_line_width, int i_ratio )
-{
- /* ?? */
-}
-
-static void X11RenderRGBLine24bpp( vout_thread_t *p_vout, picture_t *p_pic,
- int i_x, int i_y, int i_pic_x, int i_pic_y,
- int i_width, int i_line_width, int i_ratio )
-{
- /* ?? */
-}
-
-static void X11RenderRGBLine32bpp( vout_thread_t *p_vout, picture_t *p_pic,
- int i_x, int i_y, int i_pic_x, int i_pic_y,
- int i_width, int i_line_width, int i_ratio )
-{
- /* ?? */
-}
-
-/*******************************************************************************
- * X11RenderPixelLine*: pixel picture rendering functions
- *******************************************************************************
- * Render a pixel-encoded picture line.
- *******************************************************************************
- * Messages type: vout, major code: 119
- *******************************************************************************/
-static void X11RenderPixelLine8bpp( vout_thread_t *p_vout, picture_t *p_pic,
- int i_x, int i_y, int i_pic_x, int i_pic_y,
- int i_width, int i_line_width, int i_ratio )
-{
- /* ?? */
-}
-
-static void X11RenderPixelLine16bpp( vout_thread_t *p_vout, picture_t *p_pic,
- int i_x, int i_y, int i_pic_x, int i_pic_y,
- int i_width, int i_line_width, int i_ratio )
-{
- /* ?? */
-}
-
-static void X11RenderPixelLine24bpp( vout_thread_t *p_vout, picture_t *p_pic,
- int i_x, int i_y, int i_pic_x, int i_pic_y,
- int i_width, int i_line_width, int i_ratio )
-{
- /* ?? */
-}
-
-static void X11RenderPixelLine32bpp( vout_thread_t *p_vout, picture_t *p_pic,
- int i_x, int i_y, int i_pic_x, int i_pic_y,
- int i_width, int i_line_width, int i_ratio )
-{
- /* ?? */
-}
-
-/*******************************************************************************
- * X11RenderRGBMaskLine: mask picture rendering function
- *******************************************************************************
- * Render a 1bpp RGB mask-encoded picture line.
- *******************************************************************************
- * Messages type: vout, major code: 120
- *******************************************************************************/
-static void X11RenderRGBMaskLine( vout_thread_t *p_vout, picture_t *p_pic,
- int i_x, int i_y, int i_pic_x, int i_pic_y,
- int i_width, int i_line_width, int i_ratio )
-{
- /* ?? */
-}
-
-/*******************************************************************************
- * X11RenderPixelMaskLine: mask picture rendering functions
- *******************************************************************************
- * Render a 1bpp pixel mask-encoded picture line.
- *******************************************************************************
- * Messages type: vout, major code: 121
- *******************************************************************************/
-static void X11RenderPixelMaskLine8bpp( vout_thread_t *p_vout, picture_t *p_pic,
- int i_x, int i_y, int i_pic_x, int i_pic_y,
- int i_width, int i_line_width, int i_ratio )
-{
- /* ?? */
-}
-
-static void X11RenderPixelMaskLine16bpp( vout_thread_t *p_vout, picture_t *p_pic,
- int i_x, int i_y, int i_pic_x, int i_pic_y,
- int i_width, int i_line_width, int i_ratio )
-{
- /* ?? */
-}
-
-static void X11RenderPixelMaskLine24bpp( vout_thread_t *p_vout, picture_t *p_pic,
- int i_x, int i_y, int i_pic_x, int i_pic_y,
- int i_width, int i_line_width, int i_ratio )
-{
- /* ?? */
-}
-
-static void X11RenderPixelMaskLine32bpp( vout_thread_t *p_vout, picture_t *p_pic,
- int i_x, int i_y, int i_pic_x, int i_pic_y,
- int i_width, int i_line_width, int i_ratio )
-{
- /* ?? */
-}