src/interface/intf_msg.o \
src/interface/intf_cmd.o \
src/interface/intf_ctrl.o \
+ src/interface/intf_plst.o \
src/interface/intf_console.o
-INPUT = src/input/input_ps.o \
- src/input/input_ts.o \
- src/input/dvd_ifo.o \
- src/input/dvd_css.o \
- src/input/input_dvd.o \
- src/input/mpeg_system.o \
- src/input/input_ext-dec.o \
+INPUT = src/input/input_ext-dec.o \
src/input/input_ext-intf.o \
src/input/input_dec.o \
src/input/input_programs.o \
src/input/input_netlist.o \
src/input/input_clock.o \
- src/input/input.o
+ src/input/input.o \
+ src/input/mpeg_system.o
AUDIO_OUTPUT = src/audio_output/audio_output.o
src/misc/rsc_files.o \
src/misc/modules.o \
src/misc/netutils.o \
- src/misc/playlist.o \
src/misc/plugins.o
#
# Plugins
#
+PLUGIN_NULL = plugins/null/null.o
+
+PLUGIN_PS = plugins/mpeg/ps.o \
+ plugins/mpeg/input_ps.o
+
+PLUGIN_TS = plugins/mpeg/ts.o \
+ plugins/mpeg/input_ts.o
+
+PLUGIN_DVD = plugins/dvd/dvd.o \
+ plugins/dvd/input_dvd.o \
+ plugins/dvd/dvd_ifo.o \
+ plugins/dvd/dvd_css.o
+
PLUGIN_BEOS = plugins/beos/beos.o \
plugins/beos/aout_beos.o \
plugins/beos/intf_beos.o \
PLUGIN_DSP = plugins/dsp/dsp.o \
plugins/dsp/aout_dsp.o
-
PLUGIN_DUMMY = plugins/dummy/dummy.o \
plugins/dummy/aout_dummy.o \
plugins/dummy/intf_dummy.o \
plugins/sdl/vout_sdl.o \
plugins/sdl/aout_sdl.o
-PLUGIN_NULL = plugins/null/null.o
-
PLUGIN_GLIDE = plugins/glide/glide.o \
plugins/glide/intf_glide.o \
plugins/glide/vout_glide.o
find -type d | while read i ; \
do mkdir -p /tmp/vlc-@VLC_VERSION@/$$i ; \
done
- find debian -mindepth 1 -type d | grep -v CVS | while read i ; \
- do rmdir $$i ; \
- done
+ find debian -mindepth 1 -maxdepth 1 -type d | grep -v CVS | \
+ while read i ; do rm -rf /tmp/vlc-@VLC_VERSION@/$$i ; done
# CVS entries
find . -type f | grep CVS | while read i ; \
do cp $$i /tmp/vlc-@VLC_VERSION@/$$i ; \
lib/null.so: $(PLUGIN_NULL)
$(CC) -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
+lib/ps.so: $(PLUGIN_PS)
+ $(CC) -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
+
+lib/ts.so: $(PLUGIN_TS)
+ $(CC) -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
+
+lib/dvd.so: $(PLUGIN_DVD)
+ $(CC) -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
+
lib/dummy.so: $(PLUGIN_DUMMY)
$(CC) -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
lib/null.so: $(PLUGIN_NULL)
$(CC) $(PCFLAGS) -shared -o $@ $^
+lib/ps.so: $(PLUGIN_PS)
+ $(CC) $(PCFLAGS) -shared -o $@ $^
+
+lib/ts.so: $(PLUGIN_TS)
+ $(CC) $(PCFLAGS) -shared -o $@ $^
+
+lib/dvd.so: $(PLUGIN_DVD)
+ $(CC) $(PCFLAGS) -shared -o $@ $^
+
lib/dummy.so: $(PLUGIN_DUMMY)
$(CC) $(PCFLAGS) -shared -o $@ $^
rm -f conftest*
-PLUGINS=${PLUGINS}"yuv idct idctclassic motion ";
+PLUGINS=${PLUGINS}"ps ts dvd yuv idct idctclassic motion ";
ARCH=${host_cpu}
# Check whether --enable-ppro or --disable-ppro was given.
AC_EGREP_HEADER(dvd,linux/cdrom.h,AC_DEFINE(LINUX_DVD,1,DVD support for linux))
dnl default plugins
-PLUGINS=${PLUGINS}"yuv idct idctclassic motion ";
+PLUGINS=${PLUGINS}"ps ts dvd yuv idct idctclassic motion ";
ARCH=${host_cpu}
AC_ARG_ENABLE(ppro,
* Collection of useful common types and macros definitions
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: common.h,v 1.26 2001/01/18 17:40:06 massiot Exp $
+ * $Id: common.h,v 1.27 2001/02/08 04:43:27 sam Exp $
*
* Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr>
/* Misc */
struct macroblock_s;
+struct data_packet_s;
/*****************************************************************************
* Macros and inline functions
* Input thread configuration
*****************************************************************************/
+/* Environment variable containing the display method */
+#define INPUT_METHOD_VAR "vlc_input"
+
/* XXX?? */
#define INPUT_IDLE_SLEEP ((int)(0.100*CLOCK_FREQ))
* input.h: structures of the input not exported to other modules
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: input.h,v 1.14 2001/02/07 17:44:52 massiot Exp $
+ * $Id: input.h,v 1.26 2001/02/08 04:43:27 sam Exp $
*
* Authors:
*
#define PADDING_PACKET_SIZE 188 /* Size of the NULL packet inserted in case
* of data loss (this should be < 188). */
-/*****************************************************************************
- * input_capabilities_t
- *****************************************************************************
- * This structure gives pointers to the useful methods of the plugin
- *****************************************************************************/
-typedef struct input_capabilities_s
-{
- /* Plugin properties */
- int i_weight; /* for a given stream type, the plugin *
- * with higher weight will be used */
-
- /* Init/End */
- int (* pf_probe)( struct input_thread_s * );
- void (* pf_init)( struct input_thread_s * );
- void (* pf_end)( struct input_thread_s * );
-
- /* Read & Demultiplex */
- int (* pf_read)( struct input_thread_s *,
- struct data_packet_s * pp_packets[INPUT_READ_ONCE] );
- void (* pf_demux)( struct input_thread_s *,
- struct data_packet_s * );
-
- /* Packet management facilities */
- struct data_packet_s *(* pf_new_packet)( void *, size_t );
- struct pes_packet_s *(* pf_new_pes)( void * );
- void (* pf_delete_packet)( void *,
- struct data_packet_s * );
- void (* pf_delete_pes)( void *, struct pes_packet_s * );
-
- /* Stream control capabilities */
- int (* pf_rewind)( struct input_thread_s * );
- /* NULL if we don't support going *
- * backwards (it's gonna be fun) */
- int (* pf_seek)( struct input_thread_s *, off_t );
-} input_capabilities_t;
-
/*****************************************************************************
* Prototypes from input_ext-dec.c
*****************************************************************************/
void InitBitstream ( struct bit_stream_s *, struct decoder_fifo_s * );
void NextDataPacket ( struct bit_stream_s * );
+/*****************************************************************************
+ * Prototypes from input.c to open files
+ *****************************************************************************/
+void input_FileOpen ( struct input_thread_s * );
+void input_FileClose( struct input_thread_s * );
+
/*****************************************************************************
* Prototypes from input_programs.c
*****************************************************************************/
-int input_InitStream( struct input_thread_s *, size_t );
-void input_EndStream( struct input_thread_s * );
+int input_InitStream( struct input_thread_s *, size_t );
+void input_EndStream ( struct input_thread_s * );
struct pgrm_descriptor_s * input_FindProgram( struct input_thread_s *, u16 );
-struct pgrm_descriptor_s * input_AddProgram( struct input_thread_s *,
- u16, size_t );
+struct pgrm_descriptor_s * input_AddProgram ( struct input_thread_s *,
+ u16, size_t );
void input_DelProgram( struct input_thread_s *, struct pgrm_descriptor_s * );
void input_DumpStream( struct input_thread_s * );
struct es_descriptor_s * input_FindES( struct input_thread_s *, u16 );
-struct es_descriptor_s * input_AddES( struct input_thread_s *,
- struct pgrm_descriptor_s *, u16,
- size_t );
-void input_DelES( struct input_thread_s *, struct es_descriptor_s * );
-int input_SelectES( struct input_thread_s *, struct es_descriptor_s * );
+struct es_descriptor_s * input_AddES ( struct input_thread_s *,
+ struct pgrm_descriptor_s *, u16,
+ size_t );
+void input_DelES ( struct input_thread_s *, struct es_descriptor_s * );
+int input_SelectES ( struct input_thread_s *, struct es_descriptor_s * );
/*****************************************************************************
* Prototypes from input_dec.c
//decoder_capabilities_s * input_ProbeDecoder( void );
vlc_thread_t input_RunDecoder( struct decoder_capabilities_s *, void * );
void input_EndDecoder( struct input_thread_s *, struct es_descriptor_s * );
-void input_DecodePES( struct decoder_fifo_s *, struct pes_packet_s * );
+void input_DecodePES ( struct decoder_fifo_s *, struct pes_packet_s * );
/*****************************************************************************
* Prototypes from input_clock.c
*****************************************************************************/
void input_ClockNewRef( struct input_thread_s *,
struct pgrm_descriptor_s *, mtime_t, mtime_t );
+void input_EscapeDiscontinuity( struct input_thread_s *,
+ struct pgrm_descriptor_s * );
void input_ClockInit( struct pgrm_descriptor_s * );
void input_ClockManageRef( struct input_thread_s *,
struct pgrm_descriptor_s *, mtime_t );
data_packet_t * p_pad_data;
pes_packet_t * p_pes;
- if( (p_pad_data = p_input->p_plugin->pf_new_packet(
+ if( (p_pad_data = p_input->pf_new_packet(
p_input->p_method_data,
PADDING_PACKET_SIZE )) == NULL )
{
}
else
{
- if( (p_pes = p_input->p_plugin->pf_new_pes(
- p_input->p_method_data )) == NULL )
+ if( (p_pes = p_input->pf_new_pes( p_input->p_method_data )) == NULL )
{
intf_ErrMsg("Out of memory");
p_input->b_error = 1;
* control the pace of reading.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ext-intf.h,v 1.13 2001/02/07 17:44:52 massiot Exp $
+ * $Id: input_ext-intf.h,v 1.14 2001/02/08 04:43:27 sam Exp $
*
* Authors:
*
/* Thread properties and locks */
boolean_t b_die; /* 'die' flag */
boolean_t b_error;
+ boolean_t b_eof;
vlc_thread_t thread_id; /* id for thread functions */
int * pi_status; /* temporary status flag */
- struct input_config_s * p_config;
+ /* Input module */
+ struct module_s * p_input_module;
+
+ /* Init/End */
+ void (* pf_init)( struct input_thread_s * );
+ void (* pf_open)( struct input_thread_s * );
+ void (* pf_close)( struct input_thread_s * );
+ void (* pf_end)( struct input_thread_s * );
+
+ /* Read & Demultiplex */
+ int (* pf_read)( struct input_thread_s *,
+ struct data_packet_s * pp_packets[] );
+ void (* pf_demux)( struct input_thread_s *,
+ struct data_packet_s * );
+
+ /* Packet management facilities */
+ struct data_packet_s *(*pf_new_packet)( void *, size_t );
+ struct pes_packet_s *(* pf_new_pes)( void * );
+ void (* pf_delete_packet)( void *,
+ struct data_packet_s * );
+ void (* pf_delete_pes)( void *, struct pes_packet_s * );
+
+ /* Stream control capabilities */
+ int (* pf_rewind)( struct input_thread_s * );
+ /* NULL if we don't support going *
+ * backwards (it's gonna be fun) */
+ int (* pf_seek)( struct input_thread_s *, off_t );
- struct input_capabilities_s *
- pp_plugins[INPUT_MAX_PLUGINS];/* list of plugins */
- struct input_capabilities_s *
- p_plugin; /* selected plugin */
i_p_config_t i_p_config; /* plugin configuration */
+ char * p_source;
int i_handle; /* socket or file descriptor */
void * p_method_data; /* data of the packet manager */
/*****************************************************************************
* Prototypes
*****************************************************************************/
-struct input_thread_s * input_CreateThread( struct input_config_s *,
- int *pi_status );
+struct input_thread_s * input_CreateThread( int *pi_status );
void input_DestroyThread( struct input_thread_s *,
int *pi_status );
void input_Play( struct input_thread_s * );
--- /dev/null
+/*****************************************************************************
+ * intf_plst.h : Playlist functions
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+typedef struct playlist_item_s
+{
+ char* psz_name;
+ int i_type; /* unused yet */
+ int i_status; /* unused yet */
+} playlist_item_t;
+
+typedef struct playlist_s
+{
+ int i_index; /* current index */
+ int i_size; /* total size */
+
+ int i_mode; /* parse mode (random, forward, backward) */
+ int i_seed; /* seed used for random mode */
+
+ vlc_mutex_t change_lock;
+
+ playlist_item_t current;
+ playlist_item_t* p_item;
+} playlist_t;
+
+/* Used by playlist_Add */
+#define PLAYLIST_START 0
+#define PLAYLIST_END -1
+
+/* Playlist parsing mode */
+#define PLAYLIST_REPEAT_CURRENT 0 /* Keep playing current item */
+#define PLAYLIST_FORWARD 1 /* Parse playlist until end */
+#define PLAYLIST_BACKWARD -1 /* Parse backwards */
+#define PLAYLIST_FORWARD_LOOP 2 /* Parse playlist and loop */
+#define PLAYLIST_BACKWARD_LOOP -2 /* Parse backwards and loop */
+#define PLAYLIST_RANDOM 3 /* Shuffle play */
+#define PLAYLIST_REVERSE_RANDOM -3 /* Reverse shuffle play */
+
+playlist_t * playlist_Create ( void );
+void playlist_Init ( playlist_t * p_playlist );
+int playlist_Add ( playlist_t * p_playlist,
+ int i_pos, char * psz_item );
+void playlist_Next ( playlist_t * p_playlist );
+void playlist_Prev ( playlist_t * p_playlist );
+void playlist_Destroy ( playlist_t * p_playlist );
+
#define MODULE_CAPABILITY_NULL 0 /* The Module can't do anything */
#define MODULE_CAPABILITY_INTF 1 << 0 /* Interface */
-#define MODULE_CAPABILITY_INPUT 1 << 1 /* Input */
-#define MODULE_CAPABILITY_DECAPS 1 << 2 /* Decaps */
-#define MODULE_CAPABILITY_ADEC 1 << 3 /* Audio decoder */
-#define MODULE_CAPABILITY_VDEC 1 << 4 /* Video decoder */
-#define MODULE_CAPABILITY_MOTION 1 << 5 /* Video decoder */
-#define MODULE_CAPABILITY_IDCT 1 << 6 /* IDCT transformation */
-#define MODULE_CAPABILITY_AOUT 1 << 7 /* Audio output */
-#define MODULE_CAPABILITY_VOUT 1 << 8 /* Video output */
-#define MODULE_CAPABILITY_YUV 1 << 9 /* YUV colorspace conversion */
-#define MODULE_CAPABILITY_AFX 1 << 10 /* Audio effects */
-#define MODULE_CAPABILITY_VFX 1 << 11 /* Video effects */
+#define MODULE_CAPABILITY_ACCESS 1 << 1 /* Input */
+#define MODULE_CAPABILITY_INPUT 1 << 2 /* Input */
+#define MODULE_CAPABILITY_DECAPS 1 << 3 /* Decaps */
+#define MODULE_CAPABILITY_ADEC 1 << 4 /* Audio decoder */
+#define MODULE_CAPABILITY_VDEC 1 << 5 /* Video decoder */
+#define MODULE_CAPABILITY_MOTION 1 << 6 /* Video decoder */
+#define MODULE_CAPABILITY_IDCT 1 << 7 /* IDCT transformation */
+#define MODULE_CAPABILITY_AOUT 1 << 8 /* Audio output */
+#define MODULE_CAPABILITY_VOUT 1 << 9 /* Video output */
+#define MODULE_CAPABILITY_YUV 1 << 10 /* YUV colorspace conversion */
+#define MODULE_CAPABILITY_AFX 1 << 11 /* Audio effects */
+#define MODULE_CAPABILITY_VFX 1 << 12 /* Video effects */
/* FIXME: not yet used */
typedef struct probedata_s
union
{
+ /* Input plugin */
struct
{
- int ( * pf_open ) ( struct aout_thread_s * p_aout );
- int ( * pf_setformat ) ( struct aout_thread_s * p_aout );
- long ( * pf_getbufinfo ) ( struct aout_thread_s * p_aout,
- long l_buffer_info );
- void ( * pf_play ) ( struct aout_thread_s * p_aout,
- byte_t *buffer, int i_size );
- void ( * pf_close ) ( struct aout_thread_s * p_aout );
+ int ( * pf_init ) ( struct input_thread_s * );
+ void ( * pf_open ) ( struct input_thread_s * );
+ void ( * pf_close ) ( struct input_thread_s * );
+ void ( * pf_end ) ( struct input_thread_s * );
+
+ void ( * pf_read ) ( struct input_thread_s *,
+ struct data_packet_s *
+ pp_packets[] );
+ void ( * pf_demux )( struct input_thread_s *,
+ struct data_packet_s * );
+
+ struct data_packet_s * ( * pf_new_packet ) ( void *, size_t );
+ struct pes_packet_s * ( * pf_new_pes ) ( void * );
+ void ( * pf_delete_packet ) ( struct data_packet_s * );
+ void ( * pf_delete_pes ) ( struct pes_packet_s * );
+
+ int ( * pf_rewind ) ( struct input_thread_s * );
+ int ( * pf_seek ) ( struct input_thread_s *, off_t );
+ } input;
+
+ /* Audio output plugin */
+ struct
+ {
+ int ( * pf_open ) ( struct aout_thread_s * );
+ int ( * pf_setformat ) ( struct aout_thread_s * );
+ long ( * pf_getbufinfo ) ( struct aout_thread_s *, long );
+ void ( * pf_play ) ( struct aout_thread_s *, byte_t *, int );
+ void ( * pf_close ) ( struct aout_thread_s * );
} aout;
+ /* Motion compensation plugin */
struct
{
#define motion_functions( yuv ) \
#undef motion_functions
} motion;
+ /* IDCT plugin */
struct
{
- void ( * pf_init ) ( struct vdec_thread_s * p_vdec );
- void ( * pf_sparse_idct ) ( struct vdec_thread_s * p_vdec,
- dctelem_t * p_block,
- int i_sparse_pos );
- void ( * pf_idct ) ( struct vdec_thread_s * p_vdec,
- dctelem_t * p_block,
- int i_idontcare );
+ void ( * pf_init ) ( struct vdec_thread_s * );
+ void ( * pf_sparse_idct ) ( struct vdec_thread_s *,
+ dctelem_t *, int );
+ void ( * pf_idct ) ( struct vdec_thread_s *,
+ dctelem_t *, int );
void ( * pf_norm_scan ) ( u8 ppi_scan[2][64] );
} idct;
+ /* YUV transformation plugin */
struct
{
- int ( * pf_init ) ( struct vout_thread_s * p_vout );
- int ( * pf_reset ) ( struct vout_thread_s * p_vout );
- void ( * pf_end ) ( struct vout_thread_s * p_vout );
+ int ( * pf_init ) ( struct vout_thread_s * );
+ int ( * pf_reset ) ( struct vout_thread_s * );
+ void ( * pf_end ) ( struct vout_thread_s * );
} yuv;
} functions;
{
/* XXX: The order here has to be the same as above for the #defines */
function_list_t intf;
+ function_list_t access;
function_list_t input;
function_list_t decaps;
function_list_t adec;
* and TS system layers
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: mpeg_system.h,v 1.5 2001/01/10 19:22:11 massiot Exp $
+ * $Id: mpeg_system.h,v 1.1 2001/02/08 04:43:27 sam Exp $
*
* Authors:
*
+++ /dev/null
-/*****************************************************************************
- * playlist.h : Playlist functions
- *****************************************************************************
- * Copyright (C) 1999, 2000 VideoLAN
- *
- * Authors:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
-
-typedef struct playlist_s
-{
- int i_index;
- char** p_list;
-} playlist_t;
-
-playlist_t * playlist_Create ( void );
-void playlist_Init ( playlist_t * p_playlist, int i_optind );
-void playlist_Destroy ( playlist_t * p_playlist );
-
* css_table.h : Various tables needed by css unencryption
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: css_table.h,v 1.2 2001/02/08 01:34:41 stef Exp $
+ * $Id: css_table.h,v 1.1 2001/02/08 04:43:27 sam Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
--- /dev/null
+/*****************************************************************************
+ * dvd.c : DVD input module for vlc
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+#define MODULE_NAME dvd
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <stdlib.h> /* malloc(), free() */
+#include <string.h> /* strdup() */
+
+#include "config.h"
+#include "common.h" /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+
+#include "modules.h"
+#include "modules_inner.h"
+
+/*****************************************************************************
+ * Build configuration tree.
+ *****************************************************************************/
+MODULE_CONFIG_START
+ADD_WINDOW( "Configuration for DVD module" )
+ ADD_COMMENT( "foobar !" )
+MODULE_CONFIG_END
+
+/*****************************************************************************
+ * Capabilities defined in the other files.
+ *****************************************************************************/
+extern void input_getfunctions( function_list_t * p_function_list );
+
+/*****************************************************************************
+ * InitModule: get the module structure and configuration.
+ *****************************************************************************
+ * We have to fill psz_name, psz_longname and psz_version. These variables
+ * will be strdup()ed later by the main application because the module can
+ * be unloaded later to save memory, and we want to be able to access this
+ * data even after the module has been unloaded.
+ *****************************************************************************/
+int InitModule( module_t * p_module )
+{
+ p_module->psz_name = MODULE_STRING;
+ p_module->psz_longname = "DVD input module";
+ p_module->psz_version = VERSION;
+
+ p_module->i_capabilities = MODULE_CAPABILITY_NULL
+ | MODULE_CAPABILITY_INPUT;
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * ActivateModule: set the module to an usable state.
+ *****************************************************************************
+ * This function fills the capability functions and the configuration
+ * structure. Once ActivateModule() has been called, the i_usage can
+ * be set to 0 and calls to NeedModule() be made to increment it. To unload
+ * the module, one has to wait until i_usage == 0 and call DeactivateModule().
+ *****************************************************************************/
+int ActivateModule( module_t * p_module )
+{
+ p_module->p_functions = malloc( sizeof( module_functions_t ) );
+ if( p_module->p_functions == NULL )
+ {
+ return( -1 );
+ }
+
+ input_getfunctions( &p_module->p_functions->input );
+
+ p_module->p_config = p_config;
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * DeactivateModule: make sure the module can be unloaded.
+ *****************************************************************************
+ * This function must only be called when i_usage == 0. If it successfully
+ * returns, i_usage can be set to -1 and the module unloaded. Be careful to
+ * lock usage_lock during the whole process.
+ *****************************************************************************/
+int DeactivateModule( module_t * p_module )
+{
+ free( p_module->p_functions );
+
+ return( 0 );
+}
+
* dvd_css.c: Functions for DVD authentification and unscrambling
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_css.c,v 1.5 2001/02/08 01:34:41 stef Exp $
+ * $Id: dvd_css.c,v 1.1 2001/02/08 04:43:27 sam Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
* dvd_css.h: Structures for DVD authentification and unscrambling
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_css.h,v 1.5 2001/02/08 01:34:41 stef Exp $
+ * $Id: dvd_css.h,v 1.1 2001/02/08 04:43:27 sam Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
* dvd_ifo.c: Functions for ifo parsing
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_ifo.c,v 1.7 2001/02/08 01:34:41 stef Exp $
+ * $Id: dvd_ifo.c,v 1.1 2001/02/08 04:43:27 sam Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
* dvd_ifo.h: Structures for ifo parsing
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_ifo.h,v 1.7 2001/02/08 01:34:42 stef Exp $
+ * $Id: dvd_ifo.h,v 1.1 2001/02/08 04:43:27 sam Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
--- /dev/null
+/*****************************************************************************
+ * input_dvd.c: DVD reading
+ *****************************************************************************
+ * Copyright (C) 1998-2001 VideoLAN
+ * $Id: input_dvd.c,v 1.1 2001/02/08 04:43:27 sam Exp $
+ *
+ * Author: Stéphane Borel <stef@via.ecp.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netinet/in.h>
+
+#include <fcntl.h>
+#include <sys/types.h>
+
+#include <string.h>
+#include <errno.h>
+#include <malloc.h>
+
+#include <sys/ioctl.h>
+#ifdef HAVE_SYS_DVDIO_H
+# include <sys/dvdio.h>
+#endif
+#ifdef LINUX_DVD
+# include <linux/cdrom.h>
+#endif
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "tests.h"
+
+#include "intf_msg.h"
+
+#include "main.h"
+
+#include "stream_control.h"
+#include "input_ext-intf.h"
+#include "input_ext-dec.h"
+
+#include "input.h"
+#include "dvd_ifo.h"
+#include "dvd_css.h"
+#include "input_dvd.h"
+#include "mpeg_system.h"
+
+#include "debug.h"
+
+#include "modules.h"
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int DVDProbe ( probedata_t *p_data );
+static int DVDCheckCSS ( struct input_thread_s * );
+static int DVDRead ( struct input_thread_s *,
+ data_packet_t * p_packets[INPUT_READ_ONCE] );
+static void DVDInit ( struct input_thread_s * );
+static void DVDOpen ( struct input_thread_s * );
+static void DVDClose ( struct input_thread_s * );
+static void DVDEnd ( struct input_thread_s * );
+/* FIXME : DVDSeek should be on 64 bits ? Is it possible in input ? */
+static int DVDSeek ( struct input_thread_s *, off_t );
+static int DVDRewind ( struct input_thread_s * );
+static struct data_packet_s * NewPacket ( void *, size_t );
+static pes_packet_t * NewPES( void * p_garbage );
+static void DeletePacket( void *, struct data_packet_s * );
+static void DeletePES ( void *, struct pes_packet_s * );
+
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
+ *****************************************************************************/
+void input_getfunctions( function_list_t * p_function_list )
+{
+#define input p_function_list->functions.input
+ p_function_list->pf_probe = DVDProbe;
+ input.pf_init = DVDInit;
+ input.pf_open = DVDOpen;
+ input.pf_close = DVDClose;
+ input.pf_end = DVDEnd;
+ input.pf_read = DVDRead;
+ input.pf_demux = input_DemuxPS;
+ input.pf_new_packet = NewPacket;
+ input.pf_new_pes = NewPES;
+ input.pf_delete_packet = DeletePacket;
+ input.pf_delete_pes = DeletePES;
+ input.pf_rewind = NULL;
+ input.pf_seek = NULL;
+#undef input
+}
+
+/*
+ * Data reading functions
+ */
+
+/*****************************************************************************
+ * PSProbe: verifies that the stream is a PS stream
+ *****************************************************************************/
+static int DVDProbe( probedata_t *p_data )
+{
+ if( TestMethod( INPUT_METHOD_VAR, "dvd" ) )
+ {
+ return( 999 );
+ }
+
+ return 5;
+}
+
+/*****************************************************************************
+ * DVDCheckCSS: check the stream
+ *****************************************************************************/
+static int DVDCheckCSS( input_thread_t * p_input )
+{
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+ dvd_struct dvd;
+
+ dvd.type = DVD_STRUCT_COPYRIGHT;
+ dvd.copyright.layer_num = 0;
+
+ if( ioctl( p_input->i_handle, DVD_READ_STRUCT, &dvd ) < 0 )
+ {
+ intf_ErrMsg( "DVD ioctl error" );
+ return -1;
+ }
+
+ return dvd.copyright.cpst;
+#else
+ return 0;
+#endif
+}
+
+/*****************************************************************************
+ * DVDInit: initializes DVD structures
+ *****************************************************************************/
+static void DVDInit( input_thread_t * p_input )
+{
+ thread_dvd_data_t * p_method;
+ off64_t i_start;
+
+ if( (p_method = malloc( sizeof(thread_dvd_data_t) )) == NULL )
+ {
+ intf_ErrMsg( "Out of memory" );
+ p_input->b_error = 1;
+ return;
+ }
+
+ p_input->p_plugin_data = (void *)p_method;
+ p_input->p_method_data = NULL;
+
+ p_method->i_fd = p_input->i_handle;
+
+
+ lseek64( p_input->i_handle, 0, SEEK_SET );
+
+ /* Ifo initialisation */
+ p_method->ifo = IfoInit( p_input->i_handle );
+ IfoRead( &(p_method->ifo) );
+ intf_Msg( "Ifo: Initialized" );
+
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+ /* CSS authentication and keys */
+ if( ( p_method->b_encrypted = DVDCheckCSS( p_input ) ) )
+ {
+ int i;
+
+ p_method->css = CSSInit( p_input->i_handle );
+ p_method->css.i_title_nb = p_method->ifo.vmg.mat.i_tts_nb;
+ if( (p_method->css.p_title_key =
+ malloc( p_method->css.i_title_nb *
+ sizeof(p_method->css.p_title_key) ) ) == NULL )
+ {
+ intf_ErrMsg( "Out of memory" );
+ p_input->b_error = 1;
+ return;
+ }
+ for( i=0 ; i<p_method->css.i_title_nb ; i++ )
+ {
+ p_method->css.p_title_key[i].i =
+ p_method->ifo.p_vts[i].i_pos +
+ p_method->ifo.p_vts[i].mat.i_tt_vobs_ssector *DVD_LB_SIZE;
+ }
+ CSSGetKeys( &(p_method->css) );
+ intf_Msg( "CSS: Initialized" );
+ }
+#endif
+
+ i_start = p_method->ifo.p_vts[0].i_pos +
+ p_method->ifo.p_vts[0].mat.i_tt_vobs_ssector *DVD_LB_SIZE;
+
+ i_start = lseek64( p_input->i_handle, i_start, SEEK_SET );
+ intf_Msg( "VOB start at : %lld", (long long)i_start );
+
+#if 1
+ input_InitStream( p_input, sizeof( stream_ps_data_t ) );
+ input_AddProgram( p_input, 0, sizeof( stream_ps_data_t ) );
+
+ if( p_input->stream.b_seekable )
+ {
+ stream_ps_data_t * p_demux_data =
+ (stream_ps_data_t *)p_input->stream.pp_programs[0]->p_demux_data;
+
+ /* Pre-parse the stream to gather stream_descriptor_t. */
+ p_input->stream.pp_programs[0]->b_is_ok = 0;
+ p_demux_data->i_PSM_version = EMPTY_PSM_VERSION;
+
+ while( !p_input->b_die && !p_input->b_error
+ && !p_demux_data->b_has_PSM )
+ {
+ int i_result, i;
+ data_packet_t * pp_packets[INPUT_READ_ONCE];
+
+ i_result = DVDRead( p_input, pp_packets );
+ if( i_result == 1 )
+ {
+ /* EOF */
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.pp_programs[0]->b_is_ok = 1;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ break;
+ }
+ if( i_result == -1 )
+ {
+ p_input->b_error = 1;
+ break;
+ }
+
+ for( i = 0; i < INPUT_READ_ONCE && pp_packets[i] != NULL; i++ )
+ {
+ /* FIXME: use i_p_config_t */
+ input_ParsePS( p_input, pp_packets[i] );
+ DeletePacket( p_input->p_method_data, pp_packets[i] );
+ }
+
+ /* File too big. */
+ if( p_input->stream.i_tell > INPUT_PREPARSE_LENGTH )
+ {
+ break;
+ }
+ }
+ lseek64( p_input->i_handle, i_start, SEEK_SET );
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.i_tell = 0;
+ if( p_demux_data->b_has_PSM )
+ {
+ /* (The PSM decoder will care about spawning the decoders) */
+ p_input->stream.pp_programs[0]->b_is_ok = 1;
+ }
+#ifdef AUTO_SPAWN
+ else
+ {
+ /* (We have to do it ourselves) */
+ int i_es;
+
+ /* FIXME: we should do multiple passes in case an audio type
+ * is not present */
+ for( i_es = 0;
+ i_es < p_input->stream.pp_programs[0]->i_es_number;
+ i_es++ )
+ {
+#define p_es p_input->stream.pp_programs[0]->pp_es[i_es]
+ switch( p_es->i_type )
+ {
+ case MPEG1_VIDEO_ES:
+ case MPEG2_VIDEO_ES:
+ input_SelectES( p_input, p_es );
+ break;
+
+ case MPEG1_AUDIO_ES:
+ case MPEG2_AUDIO_ES:
+ if( main_GetIntVariable( INPUT_DVD_CHANNEL_VAR, 0 )
+ == (p_es->i_id & 0x1F) )
+ switch( main_GetIntVariable( INPUT_DVD_AUDIO_VAR, 0 ) )
+ {
+ case 0:
+ main_PutIntVariable( INPUT_DVD_AUDIO_VAR,
+ REQUESTED_MPEG );
+ case REQUESTED_MPEG:
+ input_SelectES( p_input, p_es );
+ }
+ break;
+
+ case AC3_AUDIO_ES:
+ if( main_GetIntVariable( INPUT_DVD_CHANNEL_VAR, 0 )
+ == ((p_es->i_id & 0xF00) >> 8) )
+ switch( main_GetIntVariable( INPUT_DVD_AUDIO_VAR, 0 ) )
+ {
+ case 0:
+ main_PutIntVariable( INPUT_DVD_AUDIO_VAR,
+ REQUESTED_AC3 );
+ case REQUESTED_AC3:
+ input_SelectES( p_input, p_es );
+ }
+ break;
+
+ case DVD_SPU_ES:
+ if( main_GetIntVariable( INPUT_DVD_SUBTITLE_VAR, -1 )
+ == ((p_es->i_id & 0x1F00) >> 8) )
+ {
+ input_SelectES( p_input, p_es );
+ }
+ break;
+
+ case LPCM_AUDIO_ES:
+ /* FIXME ! */
+ break;
+ }
+ }
+
+ }
+#endif
+#ifdef STATS
+ input_DumpStream( p_input );
+#endif
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ }
+ else
+ {
+#endif
+ /* The programs will be added when we read them. */
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.pp_programs[0]->b_is_ok = 0;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ }
+}
+
+/*****************************************************************************
+ * DVDOpen : open the dvd device
+ *****************************************************************************/
+static void DVDOpen( input_thread_t * p_input )
+{
+ intf_Msg( "input: opening DVD %s", p_input->p_source );
+
+ p_input->i_handle = open( p_input->p_source,
+ O_RDONLY | O_NONBLOCK | O_LARGEFILE );
+
+ if( p_input->i_handle == -1 )
+ {
+ intf_ErrMsg( "input error: cannot open device (%s)", strerror(errno) );
+ p_input->b_error = 1;
+ return;
+ }
+
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+
+ p_input->stream.b_pace_control = 1;
+ p_input->stream.b_seekable = 1;
+ p_input->stream.i_size = 0;
+ p_input->stream.i_tell = 0;
+
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+}
+
+/*****************************************************************************
+ * DVDClose : close a file descriptor
+ *****************************************************************************/
+static void DVDClose( input_thread_t * p_input )
+{
+ close( p_input->i_handle );
+
+ return;
+}
+
+/*****************************************************************************
+ * DVDEnd: frees unused data
+ *****************************************************************************/
+static void DVDEnd( input_thread_t * p_input )
+{
+ free( p_input->stream.p_demux_data );
+ free( p_input->p_plugin_data );
+}
+
+/*****************************************************************************
+ * SafeRead: reads a chunk of stream and correctly detects errors
+ *****************************************************************************/
+static __inline__ int SafeRead( input_thread_t * p_input, byte_t * p_buffer,
+ size_t i_len )
+{
+ // FIXME : aie aie ugly kludge for testing purposes :)
+ static byte_t p_tmp[2048];
+
+
+ thread_dvd_data_t * p_method;
+ int i_nb;
+ off64_t i_pos;
+
+ p_method = (thread_dvd_data_t *)p_input->p_plugin_data;
+ i_pos = lseek64( p_input->i_handle, 0, SEEK_CUR );
+ if( !p_method->b_encrypted )
+ {
+ i_nb = read( p_input->i_handle, p_buffer, i_len );
+ }
+ else
+ {
+ lseek64( p_input->i_handle, i_pos & ~0x7FF, SEEK_SET );
+ i_nb = read( p_input->i_handle, p_tmp, 0x800 );
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+ CSSDescrambleSector( p_method->css.p_title_key[0].key, p_tmp );
+#endif
+ memcpy( p_buffer, p_tmp + (i_pos & 0x7FF ), i_len );
+ }
+ switch( i_nb )
+ {
+ case 0:
+ /* End of File */
+ return( 1 );
+ case -1:
+ intf_ErrMsg( "DVD: Read failed (%s)", strerror(errno) );
+ return( -1 );
+ default:
+ break;
+ }
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.i_tell =
+ lseek64( p_input->i_handle, i_pos+i_len, SEEK_SET );
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ return( 0 );
+}
+
+/*****************************************************************************
+ * DVDRead: reads data packets
+ *****************************************************************************
+ * Returns -1 in case of error, 0 if everything went well, and 1 in case of
+ * EOF.
+ *****************************************************************************/
+static int DVDRead( input_thread_t * p_input,
+ data_packet_t * pp_packets[INPUT_READ_ONCE] )
+{
+ byte_t p_header[6];
+ data_packet_t * p_data;
+ size_t i_packet_size;
+ int i_packet, i_error;
+ thread_dvd_data_t * p_method;
+
+ p_method = (thread_dvd_data_t *)p_input->p_plugin_data;
+
+ memset( pp_packets, 0, INPUT_READ_ONCE * sizeof(data_packet_t *) );
+ for( i_packet = 0; i_packet < INPUT_READ_ONCE; i_packet++ )
+ {
+ /* Read what we believe to be a packet header. */
+ if( (i_error = SafeRead( p_input, p_header, 6 )) )
+ {
+ return( i_error );
+ }
+
+ if( (U32_AT(p_header) & 0xFFFFFF00) != 0x100L )
+ {
+ /* This is not the startcode of a packet. Read the stream
+ * until we find one. */
+ u32 i_startcode = U32_AT(p_header);
+ int i_nb;
+ byte_t i_dummy;
+
+ if( i_startcode )
+ {
+ /* It is common for MPEG-1 streams to pad with zeros
+ * (although it is forbidden by the recommendation), so
+ * don't bother everybody in this case. */
+ intf_WarnMsg( 1, "Garbage at input (%x)", i_startcode );
+ }
+
+ while( (i_startcode & 0xFFFFFF00) != 0x100L )
+ {
+ i_startcode <<= 8;
+ if( (i_nb = SafeRead( p_input, &i_dummy, 1 )) != 0 )
+ {
+ i_startcode |= i_dummy;
+ }
+ else
+ {
+ return( 1 );
+ }
+ }
+
+ /* Packet found. */
+ *(u32 *)p_header = U32_AT(&i_startcode);
+ if( (i_error = SafeRead( p_input, p_header + 4, 2 )) )
+ {
+ return( i_error );
+ }
+ }
+
+ if( U32_AT(p_header) != 0x1BA )
+ {
+ /* That's the case for all packets, except pack header. */
+ i_packet_size = U16_AT(&p_header[4]);
+ }
+ else
+ {
+ /* Pack header. */
+ if( (p_header[4] & 0xC0) == 0x40 )
+ {
+ /* MPEG-2 */
+ i_packet_size = 8;
+ }
+ else if( (p_header[4] & 0xF0) == 0x20 )
+ {
+ /* MPEG-1 */
+ i_packet_size = 6;
+ }
+ else
+ {
+ intf_ErrMsg( "Unable to determine stream type" );
+ return( -1 );
+ }
+ }
+
+ /* Fetch a packet of the appropriate size. */
+ if( (p_data = NewPacket( p_input, i_packet_size + 6 )) == NULL )
+ {
+ intf_ErrMsg( "Out of memory" );
+ return( -1 );
+ }
+
+ /* Copy the header we already read. */
+ memcpy( p_data->p_buffer, p_header, 6 );
+
+ /* Read the remaining of the packet. */
+ if( i_packet_size && (i_error =
+ SafeRead( p_input, p_data->p_buffer + 6, i_packet_size )) )
+ {
+ return( i_error );
+ }
+
+ /* In MPEG-2 pack headers we still have to read stuffing bytes. */
+ if( U32_AT(p_header) == 0x1BA )
+ {
+ if( i_packet_size == 8 && (p_data->p_buffer[13] & 0x7) != 0 )
+ {
+ /* MPEG-2 stuffing bytes */
+ byte_t p_garbage[8];
+ if( (i_error = SafeRead( p_input, p_garbage,
+ p_data->p_buffer[13] & 0x7)) )
+ {
+ return( i_error );
+ }
+ }
+ }
+
+ /* Give the packet to the other input stages. */
+ pp_packets[i_packet] = p_data;
+ }
+
+ return( 0 );
+}
+
+
+/*****************************************************************************
+ * DVDRewind : reads a stream backward
+ *****************************************************************************/
+static int DVDRewind( input_thread_t * p_input )
+{
+ return( -1 );
+}
+
+/*****************************************************************************
+ * DVDSeek : Goes to a given position on the stream ; this one is used by the
+ * input and translate chronological position from input to logical postion
+ * on the device
+ *****************************************************************************/
+static int DVDSeek( input_thread_t * p_input, off_t i_off )
+{
+ return( -1 );
+}
+
+/*
+ * Packet management utilities
+ */
+
+/*****************************************************************************
+ * NewPacket: allocates a data packet
+ *****************************************************************************/
+static struct data_packet_s * NewPacket( void * p_garbage,
+ size_t i_size )
+{
+ data_packet_t * p_data;
+
+ /* Safety check */
+ if( i_size > INPUT_MAX_PACKET_SIZE )
+ {
+ intf_ErrMsg( "Packet too big (%d)", i_size );
+ return NULL;
+ }
+
+ if( (p_data = (data_packet_t *)malloc( sizeof(data_packet_t) )) == NULL )
+ {
+ intf_DbgMsg( "Out of memory" );
+ return NULL;
+ }
+
+ if( (p_data->p_buffer = (byte_t *)malloc( i_size )) == NULL )
+ {
+ intf_DbgMsg( "Out of memory" );
+ free( p_data );
+ return NULL;
+ }
+
+ /* Initialize data */
+ p_data->p_next = NULL;
+ p_data->b_discard_payload = 0;
+
+ p_data->p_payload_start = p_data->p_buffer;
+ p_data->p_payload_end = p_data->p_buffer + i_size;
+
+ return( p_data );
+}
+
+/*****************************************************************************
+ * NewPES: allocates a pes packet
+ *****************************************************************************/
+static pes_packet_t * NewPES( void * p_garbage )
+{
+ pes_packet_t * p_pes;
+
+ if( (p_pes = (pes_packet_t *)malloc( sizeof(pes_packet_t) )) == NULL )
+ {
+ intf_DbgMsg( "Out of memory" );
+ return NULL;
+ }
+
+ p_pes->b_messed_up = p_pes->b_data_alignment = p_pes->b_discontinuity =
+ p_pes->i_pts = p_pes->i_dts = 0;
+ p_pes->i_pes_size = 0;
+ p_pes->p_first = NULL;
+
+ return( p_pes );
+}
+
+/*****************************************************************************
+ * DeletePacket: deletes a data packet
+ *****************************************************************************/
+static void DeletePacket( void * p_garbage,
+ data_packet_t * p_data )
+{
+ ASSERT(p_data);
+ ASSERT(p_data->p_buffer);
+ free( p_data->p_buffer );
+ free( p_data );
+}
+
+/*****************************************************************************
+ * DeletePES: deletes a PES packet and associated data packets
+ *****************************************************************************/
+static void DeletePES( void * p_garbage, pes_packet_t * p_pes )
+{
+ data_packet_t * p_data;
+ data_packet_t * p_next;
+
+ p_data = p_pes->p_first;
+
+ while( p_data != NULL )
+ {
+ p_next = p_data->p_next;
+ free( p_data->p_buffer );
+ free( p_data );
+ p_data = p_next;
+ }
+
+ free( p_pes );
+}
+
--- /dev/null
+/*****************************************************************************
+ * input_dvd.h: thread structure of the DVD plugin
+ *****************************************************************************
+ * Copyright (C) 1999-2001 VideoLAN
+ *
+ * Author: Stéphane Borel <stef@via.ecp.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#define DVD_LB_SIZE 2048
+
+/*****************************************************************************
+ * thread_dvd_data_t: extension of input_thread_t for DVD specificity
+ *****************************************************************************/
+typedef struct thread_dvd_data_s
+{
+ int i_fd; // File descriptor of device
+ boolean_t b_encrypted; // CSS encryption
+ int i_read_once; // NB of bytes read by DVDRead
+ int i_title; // Current Title
+ /* Scrambling Information */
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+ struct css_s css;
+#endif
+ /* Structure that contains all information of the DVD */
+ struct ifo_s ifo;
+} thread_dvd_data_t;
+
+/*****************************************************************************
+ * Prototypes in dvd_ifo.c
+ *****************************************************************************/
+struct ifo_s IfoInit( int );
+void IfoRead( struct ifo_s * );
+void IfoEnd( ifo_t * );
+
+/*****************************************************************************
+ * Prototypes in dvd_css.c
+ *****************************************************************************/
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+int CSSTest ( int );
+struct css_s CSSInit ( int );
+int CSSGetKeys ( struct css_s * );
+int CSSDescrambleSector( u8 * , u8 * );
+
+#endif
* input_ps.c: PS demux and packet management
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: input_ps.c,v 1.22 2001/02/07 15:32:26 massiot Exp $
+ * $Id: input_ps.c,v 1.1 2001/02/08 04:43:27 sam Exp $
*
* Authors:
*
#include "common.h"
#include "threads.h"
#include "mtime.h"
+#include "tests.h"
#include "intf_msg.h"
#include "debug.h"
+#include "modules.h"
+
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static int PSProbe ( struct input_thread_s * );
+static int PSProbe ( probedata_t * );
static int PSRead ( struct input_thread_s *,
data_packet_t * p_packets[INPUT_READ_ONCE] );
static void PSInit ( struct input_thread_s * );
static void PSEnd ( struct input_thread_s * );
+static struct pes_packet_s * NewPES ( void * p_garbage );
static struct data_packet_s * NewPacket ( void *, size_t );
static void DeletePacket( void *, struct data_packet_s * );
static void DeletePES ( void *, struct pes_packet_s * );
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
+ *****************************************************************************/
+void input_getfunctions( function_list_t * p_function_list )
+{
+#define input p_function_list->functions.input
+ p_function_list->pf_probe = PSProbe;
+ input.pf_init = PSInit;
+ input.pf_open = input_FileOpen;
+ input.pf_close = input_FileClose;
+ input.pf_end = PSEnd;
+ input.pf_read = PSRead;
+ input.pf_demux = input_DemuxPS;
+ input.pf_new_packet = NewPacket;
+ input.pf_new_pes = NewPES;
+ input.pf_delete_packet = DeletePacket;
+ input.pf_delete_pes = DeletePES;
+ input.pf_rewind = NULL;
+ input.pf_seek = NULL;
+#undef input
+}
+
/*
* Data reading functions
*/
/*****************************************************************************
* PSProbe: verifies that the stream is a PS stream
*****************************************************************************/
-static int PSProbe( input_thread_t * p_input )
+static int PSProbe( probedata_t *p_data )
{
- /* verify that the first three bytes are 0x000001, or unscramble and
- * re-do. */
- return 1;
+ if( TestMethod( INPUT_METHOD_VAR, "ps" ) )
+ {
+ return( 999 );
+ }
+
+ return 10;
}
/*****************************************************************************
case MPEG1_AUDIO_ES:
case MPEG2_AUDIO_ES:
- if( main_GetIntVariable( INPUT_DVD_CHANNEL_VAR, 0 )
+ if( main_GetIntVariable( INPUT_DVD_AUDIO_VAR, 0 )
+ == REQUESTED_MPEG
+ && main_GetIntVariable( INPUT_DVD_CHANNEL_VAR, 0 )
== (p_es->i_id & 0x1F) )
- switch( main_GetIntVariable( INPUT_DVD_AUDIO_VAR, 0 ) )
{
- case 0:
- main_PutIntVariable( INPUT_DVD_AUDIO_VAR,
- REQUESTED_MPEG );
- case REQUESTED_MPEG:
input_SelectES( p_input, p_es );
}
break;
case AC3_AUDIO_ES:
- if( main_GetIntVariable( INPUT_DVD_CHANNEL_VAR, 0 )
+ if( main_GetIntVariable( INPUT_DVD_AUDIO_VAR, 0 )
+ == REQUESTED_AC3
+ && main_GetIntVariable( INPUT_DVD_CHANNEL_VAR, 0 )
== ((p_es->i_id & 0xF00) >> 8) )
- switch( main_GetIntVariable( INPUT_DVD_AUDIO_VAR, 0 ) )
{
- case 0:
- main_PutIntVariable( INPUT_DVD_AUDIO_VAR,
- REQUESTED_AC3 );
- case REQUESTED_AC3:
input_SelectES( p_input, p_es );
}
break;
free( p_pes );
}
-/*****************************************************************************
- * PSKludge: fakes a PS plugin (FIXME)
- *****************************************************************************/
-input_capabilities_t * PSKludge( void )
-{
- input_capabilities_t * p_plugin;
-
- p_plugin = (input_capabilities_t *)malloc( sizeof(input_capabilities_t) );
- p_plugin->pf_probe = PSProbe;
- p_plugin->pf_init = PSInit;
- p_plugin->pf_end = PSEnd;
- p_plugin->pf_read = PSRead;
- p_plugin->pf_demux = input_DemuxPS; /* FIXME: use i_p_config_t ! */
- p_plugin->pf_new_packet = NewPacket;
- p_plugin->pf_new_pes = NewPES;
- p_plugin->pf_delete_packet = DeletePacket;
- p_plugin->pf_delete_pes = DeletePES;
- p_plugin->pf_rewind = NULL;
- p_plugin->pf_seek = NULL;
-
- return( p_plugin );
-}
+
* input_ps.h: thread structure of the PS plugin
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ps.h,v 1.2 2000/12/21 15:01:08 massiot Exp $
+ * $Id: input_ps.h,v 1.1 2001/02/08 04:43:27 sam Exp $
*
* Authors:
*
* input_ts.c: TS demux and netlist management
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: input_ts.c,v 1.3 2001/01/05 18:46:44 massiot Exp $
+ * $Id: input_ts.c,v 1.1 2001/02/08 04:43:27 sam Exp $
*
* Authors:
*
#include "common.h"
#include "threads.h"
#include "mtime.h"
+#include "tests.h"
+#include "modules.h"
#include "intf_msg.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static int TSProbe ( struct input_thread_s * );
+static int TSProbe ( probedata_t * );
static int TSRead ( struct input_thread_s *,
data_packet_t * p_packets[INPUT_READ_ONCE] );
static void TSInit ( struct input_thread_s * );
static void TSEnd ( struct input_thread_s * );
+/*****************************************************************************
+ * Functions exported as capabilities. They are declared as static so that
+ * we don't pollute the namespace too much.
+ *****************************************************************************/
+void input_getfunctions( function_list_t * p_function_list )
+{
+#define input p_function_list->functions.input
+ p_function_list->pf_probe = TSProbe;
+ input.pf_init = TSInit;
+ input.pf_open = input_FileOpen;
+ input.pf_close = input_FileClose;
+ input.pf_end = TSEnd;
+ input.pf_read = TSRead;
+ input.pf_demux = input_DemuxTS;
+ input.pf_new_packet = input_NetlistNewPacket;
+ input.pf_new_pes = input_NetlistNewPES;
+ input.pf_delete_packet = input_NetlistDeletePacket;
+ input.pf_delete_pes = input_NetlistDeletePES;
+ input.pf_rewind = NULL;
+ input.pf_seek = NULL;
+#undef input
+}
+
/*****************************************************************************
* TSProbe: verifies that the stream is a TS stream
*****************************************************************************/
-static int TSProbe( input_thread_t * p_input )
+static int TSProbe( probedata_t * p_data )
{
+ if( TestMethod( INPUT_METHOD_VAR, "ts" ) )
+ {
+ return( 999 );
+ }
+
/* verify that the first byte is 0x47 */
return 1;
}
return -1;
}
-/*****************************************************************************
- * TSKludge: fakes a TS plugin (FIXME)
- *****************************************************************************/
-input_capabilities_t * TSKludge( void )
-{
- input_capabilities_t * p_plugin;
-
- p_plugin = (input_capabilities_t *)malloc( sizeof(input_capabilities_t) );
- p_plugin->pf_probe = TSProbe;
- p_plugin->pf_init = TSInit;
- p_plugin->pf_end = TSEnd;
- p_plugin->pf_read = TSRead;
- p_plugin->pf_demux = input_DemuxTS; /* FIXME: use i_p_config_t ! */
- p_plugin->pf_new_packet = input_NetlistNewPacket;
- p_plugin->pf_new_pes = input_NetlistNewPES;
- p_plugin->pf_delete_packet = input_NetlistDeletePacket;
- p_plugin->pf_delete_pes = input_NetlistDeletePES;
- p_plugin->pf_rewind = NULL;
- p_plugin->pf_seek = NULL;
-
- return( p_plugin );
-}
-
--- /dev/null
+/*****************************************************************************
+ * ps.c : Program Stream input module for vlc
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+#define MODULE_NAME ps
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <stdlib.h> /* malloc(), free() */
+#include <string.h> /* strdup() */
+
+#include "config.h"
+#include "common.h" /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+
+#include "modules.h"
+#include "modules_inner.h"
+
+/*****************************************************************************
+ * Build configuration tree.
+ *****************************************************************************/
+MODULE_CONFIG_START
+ADD_WINDOW( "Configuration for PS module" )
+ ADD_COMMENT( "foobar !" )
+MODULE_CONFIG_END
+
+/*****************************************************************************
+ * Capabilities defined in the other files.
+ *****************************************************************************/
+extern void input_getfunctions( function_list_t * p_function_list );
+
+/*****************************************************************************
+ * InitModule: get the module structure and configuration.
+ *****************************************************************************
+ * We have to fill psz_name, psz_longname and psz_version. These variables
+ * will be strdup()ed later by the main application because the module can
+ * be unloaded later to save memory, and we want to be able to access this
+ * data even after the module has been unloaded.
+ *****************************************************************************/
+int InitModule( module_t * p_module )
+{
+ p_module->psz_name = MODULE_STRING;
+ p_module->psz_longname = "ISO 13818-1 MPEG Program Stream input module";
+ p_module->psz_version = VERSION;
+
+ p_module->i_capabilities = MODULE_CAPABILITY_NULL
+ | MODULE_CAPABILITY_INPUT;
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * ActivateModule: set the module to an usable state.
+ *****************************************************************************
+ * This function fills the capability functions and the configuration
+ * structure. Once ActivateModule() has been called, the i_usage can
+ * be set to 0 and calls to NeedModule() be made to increment it. To unload
+ * the module, one has to wait until i_usage == 0 and call DeactivateModule().
+ *****************************************************************************/
+int ActivateModule( module_t * p_module )
+{
+ p_module->p_functions = malloc( sizeof( module_functions_t ) );
+ if( p_module->p_functions == NULL )
+ {
+ return( -1 );
+ }
+
+ input_getfunctions( &p_module->p_functions->input );
+
+ p_module->p_config = p_config;
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * DeactivateModule: make sure the module can be unloaded.
+ *****************************************************************************
+ * This function must only be called when i_usage == 0. If it successfully
+ * returns, i_usage can be set to -1 and the module unloaded. Be careful to
+ * lock usage_lock during the whole process.
+ *****************************************************************************/
+int DeactivateModule( module_t * p_module )
+{
+ free( p_module->p_functions );
+
+ return( 0 );
+}
+
--- /dev/null
+/*****************************************************************************
+ * ts.c : Transport Stream input module for vlc
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+#define MODULE_NAME ts
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <stdlib.h> /* malloc(), free() */
+#include <string.h> /* strdup() */
+
+#include "config.h"
+#include "common.h" /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+
+#include "modules.h"
+#include "modules_inner.h"
+
+/*****************************************************************************
+ * Build configuration tree.
+ *****************************************************************************/
+MODULE_CONFIG_START
+ADD_WINDOW( "Configuration for TS module" )
+ ADD_COMMENT( "foobar !" )
+MODULE_CONFIG_END
+
+/*****************************************************************************
+ * Capabilities defined in the other files.
+ *****************************************************************************/
+extern void input_getfunctions( function_list_t * p_function_list );
+
+/*****************************************************************************
+ * InitModule: get the module structure and configuration.
+ *****************************************************************************
+ * We have to fill psz_name, psz_longname and psz_version. These variables
+ * will be strdup()ed later by the main application because the module can
+ * be unloaded later to save memory, and we want to be able to access this
+ * data even after the module has been unloaded.
+ *****************************************************************************/
+int InitModule( module_t * p_module )
+{
+ p_module->psz_name = MODULE_STRING;
+ p_module->psz_longname = "ISO 13818-1 MPEG Transport Stream input module";
+ p_module->psz_version = VERSION;
+
+ p_module->i_capabilities = MODULE_CAPABILITY_NULL
+ | MODULE_CAPABILITY_INPUT;
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * ActivateModule: set the module to an usable state.
+ *****************************************************************************
+ * This function fills the capability functions and the configuration
+ * structure. Once ActivateModule() has been called, the i_usage can
+ * be set to 0 and calls to NeedModule() be made to increment it. To unload
+ * the module, one has to wait until i_usage == 0 and call DeactivateModule().
+ *****************************************************************************/
+int ActivateModule( module_t * p_module )
+{
+ p_module->p_functions = malloc( sizeof( module_functions_t ) );
+ if( p_module->p_functions == NULL )
+ {
+ return( -1 );
+ }
+
+ input_getfunctions( &p_module->p_functions->input );
+
+ p_module->p_config = p_config;
+
+ return( 0 );
+}
+
+/*****************************************************************************
+ * DeactivateModule: make sure the module can be unloaded.
+ *****************************************************************************
+ * This function must only be called when i_usage == 0. If it successfully
+ * returns, i_usage can be set to -1 and the module unloaded. Be careful to
+ * lock usage_lock during the whole process.
+ *****************************************************************************/
+int DeactivateModule( module_t * p_module )
+{
+ free( p_module->p_functions );
+
+ return( 0 );
+}
+
return( 999 );
}
- return( 50 );
+ return( 40 );
}
/*****************************************************************************
* intf_sdl.c: SDL interface plugin
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: intf_sdl.c,v 1.29 2001/02/08 01:06:11 reno Exp $
+ * $Id: intf_sdl.c,v 1.30 2001/02/08 04:43:27 sam Exp $
*
* Authors:
*
input_Forward( p_intf->p_input, i_rate );
break;
- case SDLK_s:
+ case SDLK_z:
i_rate = p_intf->p_input->stream.control.i_rate*2;
if ( i_rate <= MAXIMAL_RATE )
{
* decoders.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: input.c,v 1.74 2001/02/07 17:44:52 massiot Exp $
+ * $Id: input.c,v 1.75 2001/02/08 04:43:27 sam Exp $
*
* Authors:
*
#include "common.h"
#include "threads.h"
#include "mtime.h"
+#include "modules.h"
#include "intf_msg.h"
+#include "intf_plst.h"
#include "stream_control.h"
#include "input_ext-intf.h"
#include "input_ext-dec.h"
#include "input.h"
+#include "interface.h"
+
+#include "main.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static void RunThread ( input_thread_t *p_input );
-static void InitThread ( input_thread_t *p_input );
+static void InitLoop ( input_thread_t *p_input );
+static void StopLoop ( input_thread_t *p_input );
static void ErrorThread ( input_thread_t *p_input );
static void EndThread ( input_thread_t *p_input );
-static void NetworkOpen ( input_thread_t *p_input );
-static void FileOpen ( input_thread_t *p_input );
-static void DvdOpen ( input_thread_t *p_input );
/*****************************************************************************
* input_CreateThread: creates a new input thread
* If pi_status is NULL, then the function will block until the thread is ready.
* If not, it will be updated using one of the THREAD_* constants.
*****************************************************************************/
-input_thread_t *input_CreateThread ( input_config_t * p_config, int *pi_status )
+input_thread_t *input_CreateThread ( int *pi_status )
{
input_thread_t * p_input; /* thread descriptor */
int i_status; /* thread status */
{
intf_ErrMsg( "input error: can't allocate input thread (%s)",
strerror(errno) );
- free( p_config );
return( NULL );
}
/* I have never understood that stuff --Meuuh */
p_input->pi_status = (pi_status != NULL) ? pi_status : &i_status;
*p_input->pi_status = THREAD_CREATE;
- p_input->p_config = p_config;
/* Initialize stream description */
p_input->stream.i_es_number = 0;
p_input->stream.control.b_mute = 0;
p_input->stream.control.b_bw = 0;
+ /* Initialize default settings for spawned decoders */
+ p_input->p_default_aout = p_main->p_aout;
+ p_input->p_default_vout = p_main->p_intf->p_vout;
+
/* Create thread and set locks. */
vlc_mutex_init( &p_input->stream.stream_lock );
vlc_mutex_init( &p_input->stream.control.control_lock );
intf_ErrMsg( "input error: can't create input thread (%s)",
strerror(errno) );
free( p_input );
- free( p_config );
return( NULL );
}
{
msleep( THREAD_SLEEP );
} while( (i_status != THREAD_READY) && (i_status != THREAD_ERROR)
- && (i_status != THREAD_FATAL) );
+ && (i_status != THREAD_FATAL) && (i_status != THREAD_OVER) );
if( i_status != THREAD_READY )
{
return( NULL );
data_packet_t * pp_packets[INPUT_READ_ONCE];
int i_error, i;
- InitThread( p_input );
+ *p_input->pi_status = THREAD_READY;
while( !p_input->b_die && !p_input->b_error )
{
-#ifdef STATS
- p_input->c_loops++;
-#endif
+ InitLoop( p_input );
- vlc_mutex_lock( &p_input->stream.control.control_lock );
- if( p_input->stream.control.i_status == BACKWARD_S
- && p_input->p_plugin->pf_rewind != NULL )
+ if( p_input->b_die || p_input->b_error )
{
- p_input->p_plugin->pf_rewind( p_input );
- /* FIXME: probably don't do it every loop, but when ? */
+ break;
}
- vlc_mutex_unlock( &p_input->stream.control.control_lock );
- i_error = p_input->p_plugin->pf_read( p_input, pp_packets );
-
- /* Demultiplex read packets. */
- for( i = 0; i < INPUT_READ_ONCE && pp_packets[i] != NULL; i++ )
+ while( !p_input->b_die && !p_input->b_error && !p_input->b_eof )
{
- p_input->p_plugin->pf_demux( p_input, pp_packets[i] );
- }
- if( i_error )
- {
- if( i_error == 1 )
+#ifdef STATS
+ p_input->c_loops++;
+#endif
+
+ vlc_mutex_lock( &p_input->stream.control.control_lock );
+ if( p_input->stream.control.i_status == BACKWARD_S
+ && p_input->pf_rewind != NULL )
+ {
+ p_input->pf_rewind( p_input );
+ /* FIXME: probably don't do it every loop, but when ? */
+ }
+ vlc_mutex_unlock( &p_input->stream.control.control_lock );
+
+ i_error = p_input->pf_read( p_input, pp_packets );
+
+ /* Demultiplex read packets. */
+ for( i = 0; i < INPUT_READ_ONCE && pp_packets[i] != NULL; i++ )
{
- /* End of file */
- intf_WarnMsg( 1, "End of file reached" );
- /* FIXME: don't treat that as an error */
+ p_input->pf_demux( p_input, pp_packets[i] );
+ }
+
+ if( i_error )
+ {
+ if( i_error == 1 )
+ {
+ /* End of file */
+ intf_WarnMsg( 1, "End of file reached" );
+ /* FIXME: don't treat that as an error */
+ p_input->b_eof = 1;
+ }
+ else
+ {
+ p_input->b_error = 1;
+ }
}
- p_input->b_error = 1;
}
+
+ /* Free all ES and destroy all decoder threads */
+ input_EndStream( p_input );
+
+ StopLoop( p_input );
}
if( p_input->b_error )
}
/*****************************************************************************
- * InitThread: init the input thread
+ * InitLoop: init the input loop
*****************************************************************************/
-input_capabilities_t * PSKludge( void );
-input_capabilities_t * DVDKludge( void );
-static void InitThread( input_thread_t * p_input )
+static void InitLoop( input_thread_t * p_input )
{
- /* Initialize default settings for spawned decoders */
- p_input->p_default_aout = p_input->p_config->p_default_aout;
- p_input->p_default_vout = p_input->p_config->p_default_vout;
+ playlist_Next( p_main->p_playlist );
+
+ if( p_main->p_playlist->i_index == -1 )
+ {
+ /* FIXME: wait for user to add stuff to playlist ? */
+ /* FIXME II: we shouldn't set b_error but rather b_die */
+ intf_Msg( "playlist: end" );
+ p_input->b_error = 1;
+ return;
+ }
+
+ p_input->p_source = p_main->p_playlist->current.psz_name;
#ifdef STATS
/* Initialize statistics */
p_input->c_packets_trashed = 0;
#endif
- /* Use the appropriate input method */
- switch( p_input->p_config->i_method )
+ p_input->p_input_module = module_Need( p_main->p_module_bank,
+ MODULE_CAPABILITY_INPUT, NULL );
+
+ if( p_input->p_input_module == NULL )
{
- case INPUT_METHOD_FILE: /* file methods */
- FileOpen( p_input );
- /* Probe plugin (FIXME: load plugins before & write this) */
- p_input->p_plugin = PSKludge();
- break;
- case INPUT_METHOD_DVD: /* DVD method */
- DvdOpen( p_input );
- /* DVD plugin */
- p_input->p_plugin = DVDKludge();
- break;
- case INPUT_METHOD_VLAN_BCAST: /* vlan network method */
-/* if( !p_main->b_vlans )
- {
- intf_ErrMsg("input error: vlans are not activated");
- free( p_input );
- return( NULL );
- } */ /* la-lala */
- /* ... pass through */
- case INPUT_METHOD_UCAST: /* network methods */
- case INPUT_METHOD_MCAST:
- case INPUT_METHOD_BCAST:
- NetworkOpen( p_input );
- break;
-#ifdef DEBUG
- default:
- intf_ErrMsg( "input error: unknow method 0x%.4x",
- p_input->p_config->i_method );
- free( p_input->p_config );
+ intf_ErrMsg( "input error: no suitable input module" );
p_input->b_error = 1;
- break;
-#endif
+ return;
}
- free( p_input->p_config );
+#define f p_input->p_input_module->p_functions->input.functions.input
+ p_input->pf_init = f.pf_init;
+ p_input->pf_open = f.pf_open;
+ p_input->pf_close = f.pf_close;
+ p_input->pf_end = f.pf_end;
+ p_input->pf_read = f.pf_read;
+ p_input->pf_demux = f.pf_demux;
+ p_input->pf_new_packet = f.pf_new_packet;
+ p_input->pf_new_pes = f.pf_new_pes;
+ p_input->pf_delete_packet = f.pf_delete_packet;
+ p_input->pf_delete_pes = f.pf_delete_pes;
+ p_input->pf_rewind = f.pf_rewind;
+ p_input->pf_seek = f.pf_seek;
+#undef f
+
+ p_input->b_eof = 0;
+ p_input->pf_open( p_input );
- if( !p_input->b_error )
+ if( p_input->b_error )
{
- p_input->p_plugin->pf_init( p_input );
+ module_Unneed( p_main->p_module_bank, p_input->p_input_module );
+ return;
}
- *p_input->pi_status = THREAD_READY;
+ p_input->pf_init( p_input );
+
+ return;
+}
+
+/*****************************************************************************
+ * StopLoop: stop the input loop
+ *****************************************************************************/
+static void StopLoop( input_thread_t * p_input )
+{
+#ifdef STATS
+ {
+ struct tms cpu_usage;
+ times( &cpu_usage );
+
+ intf_Msg("input stats: cpu usage (user: %d, system: %d)",
+ cpu_usage.tms_utime, cpu_usage.tms_stime);
+ }
+#endif
+
+ /* Free demultiplexer's data */
+ p_input->pf_end( p_input );
+
+ /* Release modules */
+ module_Unneed( p_main->p_module_bank, p_input->p_input_module );
}
/*****************************************************************************
pi_status = p_input->pi_status;
*pi_status = THREAD_END;
-#ifdef STATS
- {
- struct tms cpu_usage;
- times( &cpu_usage );
-
- intf_Msg("input stats: cpu usage (user: %d, system: %d)",
- cpu_usage.tms_utime, cpu_usage.tms_stime);
- }
-#endif
-
- /* Free all ES and destroy all decoder threads */
- input_EndStream( p_input );
-
- /* Free demultiplexer's data */
- p_input->p_plugin->pf_end( p_input );
- free( p_input->p_plugin );
-
/* Destroy Mutex locks */
vlc_mutex_destroy( &p_input->stream.control.control_lock );
vlc_mutex_destroy( &p_input->stream.stream_lock );
}
/*****************************************************************************
- * NetworkOpen : open a network socket descriptor
+ * input_FileOpen : open a file descriptor
*****************************************************************************/
-static void NetworkOpen( input_thread_t * p_input )
-{
- /* straight copy & paste of input_network.c of input-I */
-
- /* We cannot rewind nor lseek() */
- p_input->stream.b_seekable = 0;
- /* We cannot control the pace */
- p_input->stream.b_pace_control = 0;
-}
-
-/*****************************************************************************
- * FileOpen : open a file descriptor
- *****************************************************************************/
-static void FileOpen( input_thread_t * p_input )
+void input_FileOpen( input_thread_t * p_input )
{
struct stat stat_info;
-#define p_config p_input->p_config
-
- if( stat( p_config->p_source, &stat_info ) == (-1) )
+ if( stat( p_input->p_source, &stat_info ) == (-1) )
{
intf_ErrMsg( "input error: cannot stat() file `%s' (%s)",
- p_config->p_source, strerror(errno));
+ p_input->p_source, strerror(errno));
p_input->b_error = 1;
return;
}
{
vlc_mutex_unlock( &p_input->stream.stream_lock );
intf_ErrMsg( "input error: unknown file type for `%s'",
- p_config->p_source );
+ p_input->p_source );
p_input->b_error = 1;
return;
}
p_input->stream.i_tell = 0;
vlc_mutex_unlock( &p_input->stream.stream_lock );
- intf_Msg( "input: opening file %s", p_config->p_source );
- if( (p_input->i_handle = open( p_config->p_source,
+ intf_Msg( "input: opening file %s", p_input->p_source );
+ if( (p_input->i_handle = open( p_input->p_source,
/*O_NONBLOCK | O_LARGEFILE*/0 )) == (-1) )
{
intf_ErrMsg( "input error: cannot open file (%s)", strerror(errno) );
return;
}
-#undef p_config
}
/*****************************************************************************
- * DvdOpen : open the dvd device
+ * input_FileClose : close a file descriptor
*****************************************************************************/
-static void DvdOpen( input_thread_t * p_input )
+void input_FileClose( input_thread_t * p_input )
{
- intf_Msg( "input: opening DVD %s", p_input->p_config->p_source );
- if( (p_input->i_handle = open( p_input->p_config->p_source,
- O_RDONLY| O_NONBLOCK |O_LARGEFILE )) == (-1) )
- {
- intf_ErrMsg( "input error: cannot open device (%s)", strerror(errno) );
- p_input->b_error = 1;
- return;
- }
-
- vlc_mutex_lock( &p_input->stream.stream_lock );
+ close( p_input->i_handle );
- p_input->stream.b_pace_control = 1;
- p_input->stream.b_seekable = 1;
- p_input->stream.i_size = 0;
- p_input->stream.i_tell = 0;
-
- vlc_mutex_unlock( &p_input->stream.stream_lock );
+ return;
}
+
* input_programs.c: es_descriptor_t, pgrm_descriptor_t management
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_programs.c,v 1.28 2001/02/07 15:32:26 massiot Exp $
+ * $Id: input_programs.c,v 1.29 2001/02/08 04:43:28 sam Exp $
*
* Authors:
*
p_config->p_decoder_fifo->i_start = p_config->p_decoder_fifo->i_end = 0;
p_config->p_decoder_fifo->b_die = p_config->p_decoder_fifo->b_error = 0;
p_config->p_decoder_fifo->p_packets_mgt = p_input->p_method_data;
- p_config->p_decoder_fifo->pf_delete_pes =
- p_input->p_plugin->pf_delete_pes;
+ p_config->p_decoder_fifo->pf_delete_pes = p_input->pf_delete_pes;
p_es->p_decoder_fifo = p_config->p_decoder_fifo;
p_config->pf_init_bit_stream = InitBitstream;
* mpeg_system.c: TS, PS and PES management
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: mpeg_system.c,v 1.31 2001/02/08 01:34:42 stef Exp $
+ * $Id: mpeg_system.c,v 1.32 2001/02/08 04:43:28 sam Exp $
*
* Authors:
*
!= PES_HEADER_SIZE )
{
intf_WarnMsg( 3, "PES packet too short to have a header" );
- p_input->p_plugin->pf_delete_pes( p_input->p_method_data, p_pes );
+ p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
}
{
/* packet_start_code_prefix != 0x000001 */
intf_ErrMsg( "PES packet doesn't start with 0x000001 : data loss" );
- p_input->p_plugin->pf_delete_pes( p_input->p_method_data, p_pes );
+ p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
}
else
{
intf_WarnMsg( 3,
"PES packet too short to have a MPEG-2 header" );
- p_input->p_plugin->pf_delete_pes( p_input->p_method_data,
- p_pes );
+ p_input->pf_delete_pes( p_input->p_method_data,
+ p_pes );
p_pes = NULL;
return;
}
{
intf_WarnMsg( 3,
"PES packet too short to have a MPEG-2 header" );
- p_input->p_plugin->pf_delete_pes(
- p_input->p_method_data,
- p_pes );
+ p_input->pf_delete_pes( p_input->p_method_data,
+ p_pes );
p_pes = NULL;
return;
}
{
intf_WarnMsg( 3,
"PES packet too short to have a MPEG-2 header" );
- p_input->p_plugin->pf_delete_pes(
- p_input->p_method_data,
- p_pes );
+ p_input->pf_delete_pes( p_input->p_method_data,
+ p_pes );
p_pes = NULL;
return;
}
{
intf_WarnMsg( 3,
"PES packet too short to have a MPEG-1 header" );
- p_input->p_plugin->pf_delete_pes( p_input->p_method_data, p_pes );
+ p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
}
if( i_pes_header_size == 22 )
{
intf_ErrMsg( "Too much MPEG-1 stuffing" );
- p_input->p_plugin->pf_delete_pes( p_input->p_method_data, p_pes );
+ p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
}
{
intf_WarnMsg( 3,
"PES packet too short to have a MPEG-1 header" );
- p_input->p_plugin->pf_delete_pes( p_input->p_method_data, p_pes );
+ p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
}
{
intf_WarnMsg( 3,
"PES packet too short to have a MPEG-1 header" );
- p_input->p_plugin->pf_delete_pes(
- p_input->p_method_data, p_pes );
+ p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
}
{
intf_WarnMsg( 3,
"PES packet too short to have a MPEG-1 header" );
- p_input->p_plugin->pf_delete_pes(
- p_input->p_method_data, p_pes );
+ p_input->pf_delete_pes( p_input->p_method_data,
+ p_pes );
p_pes = NULL;
return;
}
if( (p_data = p_data->p_next) == NULL )
{
intf_ErrMsg( "PES header bigger than payload" );
- p_input->p_plugin->pf_delete_pes( p_input->p_method_data,
- p_pes );
+ p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
}
if( i_payload_size < i_pes_header_size )
{
intf_ErrMsg( "PES header bigger than payload" );
- p_input->p_plugin->pf_delete_pes( p_input->p_method_data, p_pes );
+ p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
}
{
intf_ErrMsg("No fifo to receive PES %p (who wrote this damn code ?)",
p_pes);
- p_input->p_plugin->pf_delete_pes( p_input->p_method_data, p_pes );
+ p_input->pf_delete_pes( p_input->p_method_data, p_pes );
}
p_pes = NULL;
}
if( !b_unit_start && p_pes == NULL )
{
/* Random access... */
- p_input->p_plugin->pf_delete_packet( p_input->p_method_data, p_data );
+ p_input->pf_delete_packet( p_input->p_method_data, p_data );
}
else
{
* packet. This is also here that we can synchronize with the
* stream if we lost packets or if the decoder has just
* started. */
- if( (p_pes = p_input->p_plugin->pf_new_pes( p_input->p_method_data ) ) == NULL )
+ if( (p_pes = p_input->pf_new_pes( p_input->p_method_data ) ) == NULL )
{
intf_ErrMsg("Out of memory");
p_input->b_error = 1;
/* Trash the packet if it has no payload or if it isn't selected */
if( b_trash )
{
- p_input->p_plugin->pf_delete_packet( p_input->p_method_data, p_data );
+ p_input->pf_delete_packet( p_input->p_method_data, p_data );
#ifdef STATS
p_input->c_packets_trashed++;
#endif
/* Trash the packet if it has no payload or if it isn't selected */
if( b_trash )
{
- p_input->p_plugin->pf_delete_packet( p_input, p_data );
+ p_input->pf_delete_packet( p_input, p_data );
#ifdef STATS
p_input->c_packets_trashed++;
#endif
#include "mtime.h"
#include "plugins.h"
#include "modules.h"
-#include "playlist.h"
#include "stream_control.h"
#include "input_ext-intf.h"
#include "interface.h"
#include "intf_cmd.h"
#include "intf_console.h"
+#include "intf_plst.h"
#include "keystrokes.h"
#include "video.h"
free( p_intf );
return( NULL );
}
+
if( p_intf->p_sys_create( p_intf ) )
{
intf_ErrMsg("intf error: cannot create interface");
*****************************************************************************/
void intf_Run( intf_thread_t *p_intf )
{
- char * psz_server = main_GetPszVariable( INPUT_SERVER_VAR, NULL );
- input_config_t * p_input_config;
-
/* Flush messages before spawning input */
intf_FlushMsg();
- /* If a server was specified */
- if( psz_server )
- {
- if( (p_input_config =
- (input_config_t *)malloc( sizeof(input_config_t) )) == NULL )
- {
- intf_ErrMsg( "intf error: cannot create input_config_t" );
- }
- else
- {
- p_input_config->i_method = INPUT_METHOD_UCAST;
- p_input_config->p_source = psz_server;
- p_input_config->p_default_aout = p_main->p_aout;
- p_input_config->p_default_vout = p_intf->p_vout;
-
- p_intf->p_input = input_CreateThread( p_input_config, NULL );
- }
- }
- /* DVD mode */
- else if( p_main->b_dvd )
- {
- if( (p_input_config =
- (input_config_t *)malloc( sizeof(input_config_t) )) == NULL )
- {
- intf_ErrMsg( "intf error: cannot create input_config_t" );
- }
- else
- {
- p_input_config->i_method = INPUT_METHOD_DVD;
- p_input_config->p_source = main_GetPszVariable( INPUT_DVD_DEVICE_VAR, INPUT_DVD_DEVICE_DEFAULT );
- p_input_config->p_default_aout = p_main->p_aout;
- p_input_config->p_default_vout = p_intf->p_vout;
- p_intf->p_input = input_CreateThread( p_input_config, NULL );
- }
- }
- /* Or if a file was specified */
- else if( p_main->p_playlist->p_list != NULL )
- {
- if( (p_input_config =
- (input_config_t *)malloc( sizeof(input_config_t) )) == NULL )
- {
- intf_ErrMsg( "intf error: cannot create input_config_t" );
- }
- else
- {
- p_input_config->i_method = INPUT_METHOD_FILE;
- p_input_config->p_source = p_main->p_playlist->p_list[0]; /* FIXME ??? */
- p_input_config->p_default_aout = p_main->p_aout;
- p_input_config->p_default_vout = p_intf->p_vout;
-
- p_intf->p_input = input_CreateThread( p_input_config, NULL );
- }
- }
- /* Execute the initialization script - if a positive number is returned,
- * the script could be executed but failed */
- else if( intf_ExecScript( main_GetPszVariable( INTF_INIT_SCRIPT_VAR, INTF_INIT_SCRIPT_DEFAULT ) ) > 0 )
- {
- intf_ErrMsg( "intf error: errors occured during startup script" );
- }
+ p_intf->p_input = input_CreateThread( NULL );
/* Main loop */
while(!p_intf->b_die && (p_intf->p_input != NULL) )
p_file = fopen( psz_filename, "r" );
if( p_file == NULL )
{
- intf_ErrMsg( "intf error: cannot open %s (%s)",
+ intf_DbgMsg( "intf warning: cannot open %s (%s)",
psz_filename, strerror(errno) );
return( 1 );
}
--- /dev/null
+/*****************************************************************************
+ * intf_plst.c : Playlist management functions
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+#include "defs.h"
+
+#include "config.h"
+
+#include <stdlib.h> /* free(), strtol() */
+#include <stdio.h> /* sprintf() */
+#include <string.h> /* strerror() */
+#include <errno.h> /* ENOMEM */
+
+#include "common.h"
+#include "threads.h"
+
+#include "intf_msg.h"
+#include "intf_plst.h"
+
+#include "main.h"
+
+static void NextItem( playlist_t * p_playlist );
+
+playlist_t * playlist_Create ( void )
+{
+ playlist_t *p_playlist;
+
+ /* Allocate structure */
+ p_playlist = malloc( sizeof( playlist_t ) );
+ if( !p_playlist )
+ {
+ intf_ErrMsg("playlist error: %s", strerror( ENOMEM ) );
+ return( NULL );
+ }
+
+ return( p_playlist );
+}
+
+void playlist_Init ( playlist_t * p_playlist )
+{
+ vlc_mutex_init( &p_playlist->change_lock );
+
+ p_playlist->i_index = -1; /* -1 means we are not playing anything yet */
+ p_playlist->i_size = 0;
+
+ p_playlist->i_mode = PLAYLIST_FORWARD;
+ p_playlist->i_seed = 0;
+
+ /* There is no current item */
+ p_playlist->current.i_type = 0;
+ p_playlist->current.i_status = 0;
+ p_playlist->current.psz_name = NULL;
+
+ /* The playlist is empty */
+ p_playlist->p_item = NULL;
+
+ intf_Msg("playlist: playlist created");
+}
+
+int playlist_Add( playlist_t * p_playlist, int i_pos, char * psz_item )
+{
+ int i_index;
+ playlist_item_t * p_item;
+
+ vlc_mutex_lock( &p_playlist->change_lock );
+
+ if( i_pos == PLAYLIST_END )
+ {
+ i_pos = p_playlist->i_size;
+ }
+ else if( i_pos > p_playlist->i_size )
+ {
+ intf_ErrMsg( "playlist error: inserting item beyond playlist size" );
+ vlc_mutex_unlock( &p_playlist->change_lock );
+ return( -1 );
+ }
+
+ /* Increment playlist size */
+ p_playlist->i_size++;
+ p_playlist->p_item = realloc( p_playlist->p_item,
+ p_playlist->i_size * sizeof( playlist_item_t ) );
+
+ /* Move second place of the playlist to make room for new item */
+ for( i_index = p_playlist->i_size - 1; i_index > i_pos; i_index-- )
+ {
+ p_playlist->p_item[ i_index ] = p_playlist->p_item[ i_index - 1 ];
+ }
+
+ /* Insert the new item */
+ p_item = &p_playlist->p_item[ i_pos ];
+
+ p_item->i_type = 0;
+ p_item->i_status = 0;
+ p_item->psz_name = strdup( psz_item );
+
+ intf_Msg( "playlist: added %s", psz_item );
+
+ vlc_mutex_unlock( &p_playlist->change_lock );
+
+ return( 0 );
+}
+
+void playlist_Next( playlist_t * p_playlist )
+{
+ vlc_mutex_lock( &p_playlist->change_lock );
+
+ NextItem( p_playlist );
+
+ vlc_mutex_unlock( &p_playlist->change_lock );
+}
+
+void playlist_Prev( playlist_t * p_playlist )
+{
+ vlc_mutex_lock( &p_playlist->change_lock );
+ p_playlist->i_mode = -p_playlist->i_mode;
+
+ NextItem( p_playlist );
+
+ p_playlist->i_mode = -p_playlist->i_mode;
+ vlc_mutex_unlock( &p_playlist->change_lock );
+}
+
+int playlist_Delete( playlist_t * p_playlist, int i_pos )
+{
+ int i_index;
+ char * psz_name;
+
+ vlc_mutex_lock( &p_playlist->change_lock );
+
+ if( !p_playlist->i_size || i_pos >= p_playlist->i_size )
+ {
+ intf_ErrMsg( "playlist error: deleting item beyond playlist size" );
+ vlc_mutex_unlock( &p_playlist->change_lock );
+ return( -1 );
+ }
+
+ /* Store the location of the item's name */
+ psz_name = p_playlist->p_item[ i_pos ].psz_name;
+
+ /* Fill the room by moving the next items */
+ for( i_index = i_pos; i_index < p_playlist->i_size - 1; i_index++ )
+ {
+ p_playlist->p_item[ i_index ] = p_playlist->p_item[ i_index + 1 ];
+ }
+
+ /* Decrement playlist size */
+ p_playlist->i_size--;
+ p_playlist->p_item = realloc( p_playlist->p_item,
+ p_playlist->i_size * sizeof( playlist_item_t ) );
+
+ intf_Msg( "playlist: removed %s", psz_name );
+
+ /* Delete the item */
+ free( psz_name );
+
+ vlc_mutex_unlock( &p_playlist->change_lock );
+
+ return( 0 );
+}
+
+void playlist_Destroy( playlist_t * p_playlist )
+{
+ int i_index;
+
+ for( i_index = p_playlist->i_size - 1; p_playlist->i_size; i_index-- )
+ {
+ playlist_Delete( p_playlist, i_index );
+ }
+
+ vlc_mutex_destroy( &p_playlist->change_lock );
+
+ if( p_playlist->current.psz_name != NULL )
+ {
+ free( p_playlist->current.psz_name );
+ }
+
+ free( p_playlist );
+
+ intf_Msg("playlist: playlist destroyed");
+}
+
+static void NextItem( playlist_t * p_playlist )
+{
+ if( !p_playlist->i_size )
+ {
+ p_playlist->i_index = -1;
+ }
+ else
+ {
+ switch( p_playlist->i_mode )
+ {
+ case PLAYLIST_FORWARD:
+ p_playlist->i_index++;
+ if( p_playlist->i_index > p_playlist->i_size - 1 )
+ {
+ p_playlist->i_index = -1;
+ }
+ break;
+
+ case PLAYLIST_FORWARD_LOOP:
+ p_playlist->i_index++;
+ if( p_playlist->i_index > p_playlist->i_size - 1 )
+ {
+ p_playlist->i_index = 0;
+ }
+ break;
+
+ case PLAYLIST_BACKWARD:
+ p_playlist->i_index--;
+ if( p_playlist->i_index < 0 )
+ {
+ p_playlist->i_index = -1;
+ }
+ break;
+
+ case PLAYLIST_BACKWARD_LOOP:
+ p_playlist->i_index--;
+ if( p_playlist->i_index < 0 )
+ {
+ p_playlist->i_index = p_playlist->i_size - 1;
+ }
+ break;
+
+ case PLAYLIST_REPEAT_CURRENT:
+ /* Just repeat what we were doing */
+ if( p_playlist->i_index < 0
+ || p_playlist->i_index > p_playlist->i_size - 1 )
+ {
+ p_playlist->i_index = 0;
+ }
+ break;
+
+ case PLAYLIST_RANDOM:
+ /* FIXME: TODO ! */
+ p_playlist->i_index++;
+ if( p_playlist->i_index > p_playlist->i_size - 1 )
+ {
+ p_playlist->i_index = 0;
+ }
+ break;
+ }
+
+ /* Duplicate the playlist entry */
+ if( p_playlist->i_index != -1 )
+ {
+ if( p_playlist->current.psz_name != NULL )
+ {
+ free( p_playlist->current.psz_name );
+ }
+ p_playlist->current = p_playlist->p_item[ p_playlist->i_index ];
+ p_playlist->current.psz_name
+ = strdup( p_playlist->current.psz_name );
+ }
+ }
+}
+
#include "tests.h" /* TestCPU() */
#include "plugins.h"
#include "modules.h"
-#include "playlist.h"
#include "stream_control.h"
#include "input_ext-intf.h"
#include "intf_msg.h"
+#include "intf_plst.h"
#include "interface.h"
#include "audio_output.h"
#define OPT_SERVER 171
#define OPT_PORT 172
#define OPT_BROADCAST 173
-#define OPT_DVD 174
#define OPT_AOUT 180
#define OPT_VOUT 181
#define OPT_MOTION 182
#define OPT_IDCT 183
#define OPT_YUV 184
+#define OPT_INPUT 185
#define OPT_SYNCHRO 190
#define OPT_WARNING 191
{ "dvdsubtitle", 1, 0, 's' },
/* Input options */
+ { "input", 1, 0, OPT_INPUT },
{ "vlans", 0, 0, OPT_VLANS },
{ "server", 1, 0, OPT_SERVER },
{ "port", 1, 0, OPT_PORT },
{ "broadcast", 0, 0, OPT_BROADCAST },
- { "dvd", 0, 0, OPT_DVD },
/* Synchro options */
{ "synchro", 1, 0, OPT_SYNCHRO },
return( errno );
}
+ intf_MsgImm( COPYRIGHT_MESSAGE );
+
/*
- * Read configuration
+ * Initialize playlist and get commandline files
*/
- if( GetConfiguration( i_argc, ppsz_argv, ppsz_env ) ) /* parse cmd line */
+ p_main->p_playlist = playlist_Create( );
+ if( !p_main->p_playlist )
{
+ intf_ErrMsg( "playlist error: playlist initialization failed" );
intf_MsgDestroy();
return( errno );
}
+ playlist_Init( p_main->p_playlist );
/*
- * Initialize playlist and get commandline files
+ * Read configuration
*/
- p_main->p_playlist = playlist_Create( );
- if( !p_main->p_playlist )
+ if( GetConfiguration( i_argc, ppsz_argv, ppsz_env ) ) /* parse cmd line */
{
- intf_ErrMsg( "playlist error: playlist initialization failed" );
intf_MsgDestroy();
return( errno );
}
- playlist_Init( p_main->p_playlist, optind );
/*
* Initialize plugin bank
p_main->b_audio = 1;
p_main->b_video = 1;
p_main->b_vlans = 0;
- p_main->b_dvd = 0;
}
/*****************************************************************************
p_main->ppsz_env = ppsz_env;
SetDefaultConfiguration();
- intf_MsgImm( COPYRIGHT_MESSAGE );
-
/* Get the executable name (similar to the basename command) */
p_main->psz_arg0 = p_pointer = ppsz_argv[ 0 ];
while( *p_pointer )
break;
/* Input options */
+ case OPT_INPUT: /* --input */
+ main_PutPszVariable( INPUT_METHOD_VAR, optarg );
+ break;
case OPT_VLANS: /* --vlans */
p_main->b_vlans = 1;
break;
case OPT_BROADCAST: /* --broadcast */
main_PutIntVariable( INPUT_BROADCAST_VAR, 1 );
break;
- case OPT_DVD: /* --dvd */
- p_main->b_dvd = 1;
- break;
/* Synchro options */
case OPT_SYNCHRO:
}
#endif
- /* Parse command line parameters - no check is made for these options */
+ /* We assume that the remaining parameters are filenames */
for( i_opt = optind; i_opt < i_argc; i_opt++ )
{
- putenv( ppsz_argv[ i_opt ] );
+ playlist_Add( p_main->p_playlist, PLAYLIST_END, ppsz_argv[ i_opt ] );
}
+
return( 0 );
}
static void Usage( int i_fashion )
{
/* Usage */
- intf_Msg( "Usage: %s [options] [parameters] [file]...",
- p_main->psz_arg0 );
+ intf_MsgImm( "Usage: %s [options] [parameters] [file]...",
+ p_main->psz_arg0 );
if( i_fashion == USAGE )
{
- intf_Msg( "Try `%s --help' for more information.",
- p_main->psz_arg0 );
+ intf_MsgImm( "Try `%s --help' for more information.",
+ p_main->psz_arg0 );
return;
}
/* Options */
- intf_Msg( "\nOptions:"
- "\n --noaudio \tdisable audio"
- "\n --aout <module> \taudio output method"
- "\n --stereo, --mono \tstereo/mono audio"
- "\n"
- "\n --novideo \tdisable video"
- "\n --vout <module> \tvideo output method"
- "\n --display <display> \tdisplay string"
- "\n --width <w>, --height <h> \tdisplay dimensions"
- "\n -g, --grayscale \tgrayscale output"
- "\n --color \tcolor output"
- "\n --motion <module> \tmotion compensation method"
- "\n --idct <module> \tIDCT method"
- "\n --yuv <module> \tYUV method"
- "\n --synchro <type> \tforce synchro algorithm"
- "\n"
- "\n --dvd \tDVD mode"
- "\n -a, --dvdaudio <type> \tchoose DVD audio type"
- "\n -c, --dvdchannel <channel> \tchoose DVD audio channel"
- "\n -s, --dvdsubtitle <channel> \tchoose DVD subtitle channel"
- "\n"
- "\n --vlans \tenable vlans"
- "\n --server <host> \tvideo server address"
- "\n --port <port> \tvideo server port"
- "\n --broadcast \tlisten to a broadcast"
- "\n"
- "\n --warning <level> \tdisplay warning messages"
- "\n"
- "\n -h, --help \tprint help and exit"
- "\n -H, --longhelp \tprint long help and exit"
- "\n -v, --version \toutput version information and exit" );
+ intf_MsgImm( "\nOptions:"
+ "\n --noaudio \tdisable audio"
+ "\n --aout <module> \taudio output method"
+ "\n --stereo, --mono \tstereo/mono audio"
+ "\n"
+ "\n --novideo \tdisable video"
+ "\n --vout <module> \tvideo output method"
+ "\n --display <display> \tdisplay string"
+ "\n --width <w>, --height <h> \tdisplay dimensions"
+ "\n -g, --grayscale \tgrayscale output"
+ "\n --fullscreen \tfullscreen output"
+ "\n --overlay \taccelerated display"
+ "\n --color \tcolor output"
+ "\n --motion <module> \tmotion compensation method"
+ "\n --idct <module> \tIDCT method"
+ "\n --yuv <module> \tYUV method"
+ "\n --synchro <type> \tforce synchro algorithm"
+ "\n"
+ "\n -a, --dvdaudio <type> \tchoose DVD audio type"
+ "\n -c, --dvdchannel <channel> \tchoose DVD audio channel"
+ "\n -s, --dvdsubtitle <channel> \tchoose DVD subtitle channel"
+ "\n"
+ "\n --input \tinput method"
+ "\n --vlans \tenable vlans"
+ "\n --server <host> \tvideo server address"
+ "\n --port <port> \tvideo server port"
+ "\n --broadcast \tlisten to a broadcast"
+ "\n"
+ "\n --warning <level> \tdisplay warning messages"
+ "\n"
+ "\n -h, --help \tprint help and exit"
+ "\n -H, --longhelp \tprint long help and exit"
+ "\n -v, --version \toutput version information and exit" );
if( i_fashion == SHORT_HELP )
return;
/* Interface parameters */
- intf_Msg( "\nInterface parameters:\n"
- "\n " INTF_INIT_SCRIPT_VAR "=<filename> \tinitialization script"
- "\n " INTF_CHANNELS_VAR "=<filename> \tchannels list"
- "\n " INTF_WARNING_VAR "=<level> \twarning level" );
+ intf_MsgImm( "\nInterface parameters:\n"
+ "\n " INTF_INIT_SCRIPT_VAR "=<filename> \tinitialization script"
+ "\n " INTF_CHANNELS_VAR "=<filename> \tchannels list"
+ "\n " INTF_WARNING_VAR "=<level> \twarning level" );
/* Audio parameters */
- intf_Msg( "\nAudio parameters:"
- "\n " AOUT_METHOD_VAR "=<method name> \taudio method"
- "\n " AOUT_DSP_VAR "=<filename> \tdsp device path"
- "\n " AOUT_STEREO_VAR "={1|0} \tstereo or mono output"
- "\n " AOUT_RATE_VAR "=<rate> \toutput rate" );
+ intf_MsgImm( "\nAudio parameters:"
+ "\n " AOUT_METHOD_VAR "=<method name> \taudio method"
+ "\n " AOUT_DSP_VAR "=<filename> \tdsp device path"
+ "\n " AOUT_STEREO_VAR "={1|0} \tstereo or mono output"
+ "\n " AOUT_RATE_VAR "=<rate> \toutput rate" );
/* Video parameters */
- intf_Msg( "\nVideo parameters:"
- "\n " VOUT_METHOD_VAR "=<method name> \tdisplay method"
- "\n " VOUT_DISPLAY_VAR "=<display name> \tdisplay used"
- "\n " VOUT_WIDTH_VAR "=<width> \tdisplay width"
- "\n " VOUT_HEIGHT_VAR "=<height> \tdislay height"
- "\n " VOUT_FB_DEV_VAR "=<filename> \tframebuffer device path"
- "\n " VOUT_GRAYSCALE_VAR "={1|0} \tgrayscale or color output"
- "\n " VOUT_FULLSCREEN_VAR "={1|0} \tfullscreen"
- "\n " VOUT_OVERLAY_VAR "={1|0} \toverlay"
- "\n " MOTION_METHOD_VAR "=<method name> \tmotion compensation method"
- "\n " IDCT_METHOD_VAR "=<method name> \tIDCT method"
- "\n " YUV_METHOD_VAR "=<method name> \tYUV method"
- "\n " VPAR_SYNCHRO_VAR "={I|I+|IP|IP+|IPB} \tsynchro algorithm"
- );
+ intf_MsgImm( "\nVideo parameters:"
+ "\n " VOUT_METHOD_VAR "=<method name> \tdisplay method"
+ "\n " VOUT_DISPLAY_VAR "=<display name> \tdisplay used"
+ "\n " VOUT_WIDTH_VAR "=<width> \tdisplay width"
+ "\n " VOUT_HEIGHT_VAR "=<height> \tdislay height"
+ "\n " VOUT_FB_DEV_VAR "=<filename> \tframebuffer device path"
+ "\n " VOUT_GRAYSCALE_VAR "={1|0} \tgrayscale or color output"
+ "\n " VOUT_FULLSCREEN_VAR "={1|0} \tfullscreen"
+ "\n " VOUT_OVERLAY_VAR "={1|0} \toverlay"
+ "\n " MOTION_METHOD_VAR "=<method name> \tmotion compensation method"
+ "\n " IDCT_METHOD_VAR "=<method name> \tIDCT method"
+ "\n " YUV_METHOD_VAR "=<method name> \tYUV method"
+ "\n " VPAR_SYNCHRO_VAR "={I|I+|IP|IP+|IPB} \tsynchro algorithm" );
/* DVD parameters */
- intf_Msg( "\nDVD parameters:"
- "\n " INPUT_DVD_DEVICE_VAR "=<device> \tDVD device"
- "\n " INPUT_DVD_AUDIO_VAR "={ac3|lpcm|mpeg|off} \taudio type"
- "\n " INPUT_DVD_CHANNEL_VAR "=[0-15] \taudio channel"
- "\n " INPUT_DVD_SUBTITLE_VAR "=[0-31] \tsubtitle channel" );
+ intf_MsgImm( "\nDVD parameters:"
+ "\n " INPUT_DVD_DEVICE_VAR "=<device> \tDVD device"
+ "\n " INPUT_DVD_AUDIO_VAR "={ac3|lpcm|mpeg|off} \taudio type"
+ "\n " INPUT_DVD_CHANNEL_VAR "=[0-15] \taudio channel"
+ "\n " INPUT_DVD_SUBTITLE_VAR "=[0-31] \tsubtitle channel" );
/* Input parameters */
- intf_Msg( "\nInput parameters:\n"
- "\n " INPUT_SERVER_VAR "=<hostname> \tvideo server"
- "\n " INPUT_PORT_VAR "=<port> \tvideo server port"
- "\n " INPUT_IFACE_VAR "=<interface> \tnetwork interface"
- "\n " INPUT_BROADCAST_VAR "={1|0} \tbroadcast mode"
- "\n " INPUT_VLAN_SERVER_VAR "=<hostname> \tvlan server"
- "\n " INPUT_VLAN_PORT_VAR "=<port> \tvlan server port"
- );
+ intf_MsgImm( "\nInput parameters:\n"
+ "\n " INPUT_SERVER_VAR "=<hostname> \tvideo server"
+ "\n " INPUT_PORT_VAR "=<port> \tvideo server port"
+ "\n " INPUT_IFACE_VAR "=<interface> \tnetwork interface"
+ "\n " INPUT_BROADCAST_VAR "={1|0} \tbroadcast mode"
+ "\n " INPUT_VLAN_SERVER_VAR "=<hostname> \tvlan server"
+ "\n " INPUT_VLAN_PORT_VAR "=<port> \tvlan server port" );
}
*****************************************************************************/
static void Version( void )
{
- intf_Msg( VERSION_MESSAGE
- "This program comes with NO WARRANTY, to the extent permitted by law.\n"
- "You may redistribute it under the terms of the GNU General Public License;\n"
- "see the file named COPYING for details.\n"
- "Written by the VideoLAN team at Ecole Centrale, Paris." );
-
+ intf_MsgImm( VERSION_MESSAGE
+ "This program comes with NO WARRANTY, to the extent permitted by law.\n"
+ "You may redistribute it under the terms of the GNU General Public License;\n"
+ "see the file named COPYING for details.\n"
+ "Written by the VideoLAN team at Ecole Centrale, Paris." );
}
/*****************************************************************************
/* We release the global lock */
vlc_mutex_unlock( &p_bank->lock );
- intf_Msg( "module: locking module `%s'", p_bestmodule->psz_name );
+ intf_WarnMsg( 1, "module: locking module `%s'", p_bestmodule->psz_name );
/* Don't forget that the module is still locked if bestmodule != NULL */
return( p_bestmodule );
* so there is no need to check the return value. */
UnlockModule( p_module );
- intf_Msg( "module: unlocking module `%s'", p_module->psz_name );
+ intf_WarnMsg( 1, "module: unlocking module `%s'", p_module->psz_name );
/* We release the global lock */
vlc_mutex_unlock( &p_bank->lock );
if( module_load( psz_filename, &handle ) )
{
/* The dynamic module couldn't be opened */
- intf_DbgMsg( "module warning: cannot open %s (%s)",
+ intf_ErrMsg( "module warning: cannot open %s (%s)",
psz_filename, module_error() );
return( -1 );
}
p_bank->first = p_module;
/* Immediate message so that a slow module doesn't make the user wait */
- intf_MsgImm( "module: dynamic module `%s', %s",
- p_module->psz_name, p_module->psz_longname );
+ intf_WarnMsgImm( 1, "module: dynamic module `%s', %s",
+ p_module->psz_name, p_module->psz_longname );
return( 0 );
}
if( !p_symbol )
{
/* We couldn't load the symbol */
- intf_DbgMsg( "module warning: cannot find symbol %s in module %s (%s)",
- psz_name, p_module->psz_filename, module_error() );
+ intf_WarnMsg( 1, "module warning: "
+ "cannot find symbol %s in module %s (%s)",
+ psz_name, p_module->psz_filename, module_error() );
return( -1 );
}
+++ /dev/null
-/*****************************************************************************
- * playlist.c : Playlist management functions
- *****************************************************************************
- * Copyright (C) 1999, 2000 VideoLAN
- *
- * Authors:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
-#include "defs.h"
-
-#include "config.h"
-
-#include <stdlib.h> /* free(), strtol() */
-#include <stdio.h> /* sprintf() */
-#include <string.h> /* strerror() */
-#include <errno.h> /* ENOMEM */
-
-#include "common.h"
-
-#include "intf_msg.h"
-#include "playlist.h"
-
-#include "main.h"
-
-/* Local prototypes */
-//int TestPlugin ( plugin_id_t *p_plugin_id, char * psz_name );
-//int AllocatePlugin ( plugin_id_t plugin_id, plugin_bank_t * p_bank );
-
-playlist_t * playlist_Create ( void )
-{
- playlist_t *p_playlist;
-
- /* Allocate structure */
- p_playlist = malloc( sizeof( playlist_t ) );
- if( !p_playlist )
- {
- intf_ErrMsg("playlist error: %s", strerror( ENOMEM ) );
- return( NULL );
- }
-
- p_playlist->i_index = 0;
- p_playlist->p_list = NULL;
-
- intf_Msg("playlist: playlist created");
- return( p_playlist );
-}
-
-void playlist_Init( playlist_t * p_playlist, int i_optind )
-{
- int i_list_index = 0;
- int i_index;
- int i_argc = p_main->i_argc;
-
- if( i_optind < i_argc )
- {
- i_list_index = i_argc - i_optind;
-
- p_playlist->p_list = malloc( i_list_index * sizeof( int ) );
-
- for( i_index = 0 ; i_argc - i_index > i_optind ; i_index++ )
- {
- if( strncmp( p_main->ppsz_argv[ i_argc - i_index - 1], "-", 1 ) )
- {
- p_playlist->p_list[ i_index ] =
- p_main->ppsz_argv[ i_argc - i_index - 1];
- }
- else
- {
- p_playlist->p_list[ i_index ] = "/dev/stdin";
- }
- }
- }
- else
- {
- /* if no file was asked, get stream from the network */
- p_playlist->p_list = NULL;
- }
-
- p_main->p_playlist->i_index = i_list_index;
-}
-
-void playlist_Destroy( playlist_t * p_playlist )
-{
- free( p_playlist );
-}
-
-/*
- * Following functions are local
- */
-