From: Sam Hocevar Date: Thu, 8 Feb 2001 04:43:28 +0000 (+0000) Subject: This commit is a bit early, but it'll save Stef, Henri and me much X-Git-Tag: 0.2.70~168 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=0935df9e58f1671cf54a6774e3ff54bcf58940ab;p=vlc This commit is a bit early, but it'll save Stef, Henri and me much time later, when we don't have to backport modifications to input_*.c What's new : - playlist works again (still the old wrong way like Meuuh doesn't like, but this is going to change within a few hours) - input_ps, input_ts and input_dvd are now plugins, located in plugins/mpeg/ and plugins/dvd/ What's broken : - audio output might be broken on some streams ; have to investigate What has changed : - fast/slow keys are now A/Z instead of A/S since S was already linked to the scale/noscale toggle. - `--dvd' doesn't work anymore, for the moment try to use : vlc --input dvd /dev/dvd - module bank is now less verbose ; use `--warn 1' to turn back verbosity on --- diff --git a/Makefile.in b/Makefile.in index f5ca24304a..fc3a29eb11 100644 --- a/Makefile.in +++ b/Makefile.in @@ -179,21 +179,17 @@ INTERFACE = src/interface/main.o \ 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 @@ -238,7 +234,6 @@ MISC = src/misc/mtime.o \ src/misc/rsc_files.o \ src/misc/modules.o \ src/misc/netutils.o \ - src/misc/playlist.o \ src/misc/plugins.o @@ -276,6 +271,19 @@ endif # # 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 \ @@ -284,7 +292,6 @@ PLUGIN_BEOS = plugins/beos/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 \ @@ -306,8 +313,6 @@ PLUGIN_SDL = plugins/sdl/sdl.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 @@ -446,9 +451,8 @@ snapshot: 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 ; \ @@ -605,6 +609,15 @@ ifeq ($(SYS),beos) 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_ @@ -638,6 +651,15 @@ else 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 $@ $^ diff --git a/configure b/configure index f6dd78a7ec..bf95e10c8f 100755 --- a/configure +++ b/configure @@ -3409,7 +3409,7 @@ fi 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. diff --git a/configure.in b/configure.in index 9fb8225d07..8a71adda6e 100644 --- a/configure.in +++ b/configure.in @@ -107,7 +107,7 @@ AC_CHECK_HEADERS(linux/cdrom.h) 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, diff --git a/include/common.h b/include/common.h index 453aa65e10..b7bfe86fc5 100644 --- a/include/common.h +++ b/include/common.h @@ -3,7 +3,7 @@ * 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 * Vincent Seguin @@ -130,6 +130,7 @@ typedef struct video_parser_s * p_video_parser_t; /* Misc */ struct macroblock_s; +struct data_packet_s; /***************************************************************************** * Macros and inline functions diff --git a/include/config.h.in b/include/config.h.in index 67cb8976a4..d1da688834 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -157,6 +157,9 @@ * 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)) diff --git a/src/input/input.h b/include/input.h similarity index 66% rename from src/input/input.h rename to include/input.h index 409c8e8dfb..9646996944 100644 --- a/src/input/input.h +++ b/include/input.h @@ -2,7 +2,7 @@ * 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: * @@ -33,64 +33,34 @@ #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 @@ -98,13 +68,15 @@ int input_SelectES( struct input_thread_s *, struct es_descriptor_s * ); //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 ); @@ -120,7 +92,7 @@ static __inline__ void input_NullPacket( input_thread_t * p_input, 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 ) { @@ -141,8 +113,7 @@ static __inline__ void input_NullPacket( input_thread_t * p_input, } 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; diff --git a/include/input_ext-intf.h b/include/input_ext-intf.h index 0393e0ade9..7a8d856668 100644 --- a/include/input_ext-intf.h +++ b/include/input_ext-intf.h @@ -4,7 +4,7 @@ * 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: * @@ -209,16 +209,40 @@ typedef struct input_thread_s /* 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 */ @@ -273,8 +297,7 @@ typedef struct input_config_s /***************************************************************************** * 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 * ); diff --git a/src/input/input_netlist.h b/include/input_netlist.h similarity index 100% rename from src/input/input_netlist.h rename to include/input_netlist.h diff --git a/include/intf_plst.h b/include/intf_plst.h new file mode 100644 index 0000000000..9b950c58c2 --- /dev/null +++ b/include/intf_plst.h @@ -0,0 +1,64 @@ +/***************************************************************************** + * 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 ); + diff --git a/include/modules.h b/include/modules.h index 09b4b78320..b3b3f44848 100644 --- a/include/modules.h +++ b/include/modules.h @@ -36,17 +36,18 @@ typedef void * module_handle_t; #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 @@ -64,17 +65,40 @@ typedef struct function_list_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 ) \ @@ -90,23 +114,23 @@ typedef struct function_list_s #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; @@ -117,6 +141,7 @@ typedef struct module_functions_s { /* 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; diff --git a/src/input/mpeg_system.h b/include/mpeg_system.h similarity index 98% rename from src/input/mpeg_system.h rename to include/mpeg_system.h index b653635856..42d415da3a 100644 --- a/src/input/mpeg_system.h +++ b/include/mpeg_system.h @@ -3,7 +3,7 @@ * 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: * diff --git a/include/playlist.h b/include/playlist.h deleted file mode 100644 index 9556fe18f2..0000000000 --- a/include/playlist.h +++ /dev/null @@ -1,32 +0,0 @@ -/***************************************************************************** - * 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 ); - diff --git a/src/input/css_table.h b/plugins/dvd/css_table.h similarity index 99% rename from src/input/css_table.h rename to plugins/dvd/css_table.h index 47779ed403..fcde1c59e6 100644 --- a/src/input/css_table.h +++ b/plugins/dvd/css_table.h @@ -2,7 +2,7 @@ * 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 * diff --git a/plugins/dvd/dvd.c b/plugins/dvd/dvd.c new file mode 100644 index 0000000000..80b4edad9f --- /dev/null +++ b/plugins/dvd/dvd.c @@ -0,0 +1,110 @@ +/***************************************************************************** + * 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 /* malloc(), free() */ +#include /* 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 ); +} + diff --git a/src/input/dvd_css.c b/plugins/dvd/dvd_css.c similarity index 99% rename from src/input/dvd_css.c rename to plugins/dvd/dvd_css.c index d8738dcf7c..6ebc6b315e 100644 --- a/src/input/dvd_css.c +++ b/plugins/dvd/dvd_css.c @@ -2,7 +2,7 @@ * 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 * diff --git a/src/input/dvd_css.h b/plugins/dvd/dvd_css.h similarity index 97% rename from src/input/dvd_css.h rename to plugins/dvd/dvd_css.h index 43f7471439..351874e93f 100644 --- a/src/input/dvd_css.h +++ b/plugins/dvd/dvd_css.h @@ -2,7 +2,7 @@ * 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 * diff --git a/src/input/dvd_ifo.c b/plugins/dvd/dvd_ifo.c similarity index 99% rename from src/input/dvd_ifo.c rename to plugins/dvd/dvd_ifo.c index 7ed4e9e44a..b4c4834c7a 100644 --- a/src/input/dvd_ifo.c +++ b/plugins/dvd/dvd_ifo.c @@ -2,7 +2,7 @@ * 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 * diff --git a/src/input/dvd_ifo.h b/plugins/dvd/dvd_ifo.h similarity index 99% rename from src/input/dvd_ifo.h rename to plugins/dvd/dvd_ifo.h index 12295a5e1f..926559a7ab 100644 --- a/src/input/dvd_ifo.h +++ b/plugins/dvd/dvd_ifo.h @@ -2,7 +2,7 @@ * 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 * diff --git a/plugins/dvd/input_dvd.c b/plugins/dvd/input_dvd.c new file mode 100644 index 0000000000..337275dd6e --- /dev/null +++ b/plugins/dvd/input_dvd.c @@ -0,0 +1,683 @@ +/***************************************************************************** + * 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 + * + * 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 +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#ifdef HAVE_SYS_DVDIO_H +# include +#endif +#ifdef LINUX_DVD +# include +#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 ; icss.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 ); +} + diff --git a/plugins/dvd/input_dvd.h b/plugins/dvd/input_dvd.h new file mode 100644 index 0000000000..3f15d7f48f --- /dev/null +++ b/plugins/dvd/input_dvd.h @@ -0,0 +1,61 @@ +/***************************************************************************** + * input_dvd.h: thread structure of the DVD plugin + ***************************************************************************** + * Copyright (C) 1999-2001 VideoLAN + * + * Author: Stéphane Borel + * + * 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 diff --git a/src/input/input_ps.c b/plugins/mpeg/input_ps.c similarity index 90% rename from src/input/input_ps.c rename to plugins/mpeg/input_ps.c index 3d708033e8..76232664d9 100644 --- a/src/input/input_ps.c +++ b/plugins/mpeg/input_ps.c @@ -2,7 +2,7 @@ * 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: * @@ -34,6 +34,7 @@ #include "common.h" #include "threads.h" #include "mtime.h" +#include "tests.h" #include "intf_msg.h" @@ -50,18 +51,44 @@ #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 */ @@ -69,11 +96,14 @@ static void DeletePES ( void *, struct pes_packet_s * ); /***************************************************************************** * 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; } /***************************************************************************** @@ -180,27 +210,21 @@ static void PSInit( input_thread_t * p_input ) 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; @@ -495,25 +519,4 @@ static void DeletePES( void * p_garbage, pes_packet_t * p_pes ) 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 ); -} + diff --git a/src/input/input_ps.h b/plugins/mpeg/input_ps.h similarity index 95% rename from src/input/input_ps.h rename to plugins/mpeg/input_ps.h index 7497d6d206..c4f1fcb7be 100644 --- a/src/input/input_ps.h +++ b/plugins/mpeg/input_ps.h @@ -2,7 +2,7 @@ * 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: * diff --git a/src/input/input_ts.c b/plugins/mpeg/input_ts.c similarity index 75% rename from src/input/input_ts.c rename to plugins/mpeg/input_ts.c index c32dd953f4..26aa41c690 100644 --- a/src/input/input_ts.c +++ b/plugins/mpeg/input_ts.c @@ -2,7 +2,7 @@ * 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: * @@ -34,6 +34,8 @@ #include "common.h" #include "threads.h" #include "mtime.h" +#include "tests.h" +#include "modules.h" #include "intf_msg.h" @@ -49,17 +51,45 @@ /***************************************************************************** * 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; } @@ -92,26 +122,3 @@ static int TSRead( input_thread_t * p_input, 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 ); -} - diff --git a/plugins/mpeg/ps.c b/plugins/mpeg/ps.c new file mode 100644 index 0000000000..4b83f0759c --- /dev/null +++ b/plugins/mpeg/ps.c @@ -0,0 +1,110 @@ +/***************************************************************************** + * 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 /* malloc(), free() */ +#include /* 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 ); +} + diff --git a/plugins/mpeg/ts.c b/plugins/mpeg/ts.c new file mode 100644 index 0000000000..baa12a21e6 --- /dev/null +++ b/plugins/mpeg/ts.c @@ -0,0 +1,110 @@ +/***************************************************************************** + * 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 /* malloc(), free() */ +#include /* 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 ); +} + diff --git a/plugins/sdl/aout_sdl.c b/plugins/sdl/aout_sdl.c index ac3d98cd6d..330ef918e1 100644 --- a/plugins/sdl/aout_sdl.c +++ b/plugins/sdl/aout_sdl.c @@ -136,7 +136,7 @@ static int aout_Probe( probedata_t *p_data ) return( 999 ); } - return( 50 ); + return( 40 ); } /***************************************************************************** diff --git a/plugins/sdl/intf_sdl.c b/plugins/sdl/intf_sdl.c index 26a66a81c5..77555023f6 100644 --- a/plugins/sdl/intf_sdl.c +++ b/plugins/sdl/intf_sdl.c @@ -2,7 +2,7 @@ * 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: * @@ -154,7 +154,7 @@ void intf_SDLManage( intf_thread_t *p_intf ) 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 ) { diff --git a/src/input/input.c b/src/input/input.c index cfca95f8de..37dfc8e002 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -4,7 +4,7 @@ * 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: * @@ -44,25 +44,28 @@ #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 @@ -72,7 +75,7 @@ static void DvdOpen ( input_thread_t *p_input ); * 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 */ @@ -83,7 +86,6 @@ input_thread_t *input_CreateThread ( input_config_t * p_config, int *pi_status ) { intf_ErrMsg( "input error: can't allocate input thread (%s)", strerror(errno) ); - free( p_config ); return( NULL ); } @@ -93,7 +95,6 @@ input_thread_t *input_CreateThread ( input_config_t * p_config, int *pi_status ) /* 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; @@ -108,6 +109,10 @@ input_thread_t *input_CreateThread ( input_config_t * p_config, int *pi_status ) 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 ); @@ -117,7 +122,6 @@ input_thread_t *input_CreateThread ( input_config_t * p_config, int *pi_status ) intf_ErrMsg( "input error: can't create input thread (%s)", strerror(errno) ); free( p_input ); - free( p_config ); return( NULL ); } @@ -128,7 +132,7 @@ input_thread_t *input_CreateThread ( input_config_t * p_config, int *pi_status ) { 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 ); @@ -174,41 +178,61 @@ static void RunThread( input_thread_t *p_input ) 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 ) @@ -221,15 +245,22 @@ static void RunThread( input_thread_t *p_input ) } /***************************************************************************** - * 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 */ @@ -240,50 +271,65 @@ static void InitThread( input_thread_t * p_input ) 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 ); } /***************************************************************************** @@ -311,23 +357,6 @@ static void EndThread( input_thread_t * p_input ) 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 ); @@ -340,31 +369,16 @@ static void EndThread( input_thread_t * p_input ) } /***************************************************************************** - * 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; } @@ -389,7 +403,7 @@ static void FileOpen( input_thread_t * p_input ) { 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; } @@ -397,8 +411,8 @@ static void FileOpen( input_thread_t * p_input ) 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) ); @@ -406,29 +420,15 @@ static void FileOpen( input_thread_t * p_input ) 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; } + diff --git a/src/input/input_programs.c b/src/input/input_programs.c index 59a3a95f0c..631e426ede 100644 --- a/src/input/input_programs.c +++ b/src/input/input_programs.c @@ -2,7 +2,7 @@ * 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: * @@ -449,8 +449,7 @@ static int InitDecConfig( input_thread_t * p_input, es_descriptor_t * p_es, 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; diff --git a/src/input/mpeg_system.c b/src/input/mpeg_system.c index 0c2ad92297..a669f16eb0 100644 --- a/src/input/mpeg_system.c +++ b/src/input/mpeg_system.c @@ -2,7 +2,7 @@ * 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: * @@ -134,7 +134,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) != 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; } @@ -148,7 +148,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) { /* 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 @@ -194,8 +194,8 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) { 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; } @@ -211,9 +211,8 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) { 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; } @@ -228,9 +227,8 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) { 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; } @@ -260,7 +258,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) { 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; } @@ -268,7 +266,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) 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; } @@ -284,7 +282,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) { 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; } @@ -304,8 +302,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) { 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; } @@ -322,8 +319,8 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) { 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; } @@ -363,8 +360,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) 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; } @@ -375,7 +371,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) 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; } @@ -391,7 +387,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es ) { 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; } @@ -431,7 +427,7 @@ void input_GatherPES( input_thread_t * p_input, data_packet_t * p_data, 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 { @@ -442,7 +438,7 @@ void input_GatherPES( input_thread_t * p_input, data_packet_t * p_data, * 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; @@ -859,7 +855,7 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data ) /* 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 @@ -1051,7 +1047,7 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data ) /* 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 diff --git a/src/interface/interface.c b/src/interface/interface.c index 0861ca2e81..29881bc641 100644 --- a/src/interface/interface.c +++ b/src/interface/interface.c @@ -38,7 +38,6 @@ #include "mtime.h" #include "plugins.h" #include "modules.h" -#include "playlist.h" #include "stream_control.h" #include "input_ext-intf.h" @@ -49,6 +48,7 @@ #include "interface.h" #include "intf_cmd.h" #include "intf_console.h" +#include "intf_plst.h" #include "keystrokes.h" #include "video.h" @@ -159,6 +159,7 @@ intf_thread_t* intf_Create( void ) free( p_intf ); return( NULL ); } + if( p_intf->p_sys_create( p_intf ) ) { intf_ErrMsg("intf error: cannot create interface"); @@ -178,71 +179,10 @@ intf_thread_t* intf_Create( void ) *****************************************************************************/ 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) ) @@ -583,7 +523,7 @@ static int LoadChannels( intf_thread_t *p_intf, char *psz_filename ) 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 ); } diff --git a/src/interface/intf_plst.c b/src/interface/intf_plst.c new file mode 100644 index 0000000000..b2f147278d --- /dev/null +++ b/src/interface/intf_plst.c @@ -0,0 +1,273 @@ +/***************************************************************************** + * 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 /* free(), strtol() */ +#include /* sprintf() */ +#include /* strerror() */ +#include /* 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 ); + } + } +} + diff --git a/src/interface/main.c b/src/interface/main.c index f53e80ac12..58046a6270 100644 --- a/src/interface/main.c +++ b/src/interface/main.c @@ -46,11 +46,11 @@ #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" @@ -84,13 +84,13 @@ #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 @@ -137,11 +137,11 @@ static const struct option longopts[] = { "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 }, @@ -231,26 +231,28 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) 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 @@ -478,7 +480,6 @@ static void SetDefaultConfiguration( void ) p_main->b_audio = 1; p_main->b_video = 1; p_main->b_vlans = 0; - p_main->b_dvd = 0; } /***************************************************************************** @@ -501,8 +502,6 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) 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 ) @@ -609,6 +608,9 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) break; /* Input options */ + case OPT_INPUT: /* --input */ + main_PutPszVariable( INPUT_METHOD_VAR, optarg ); + break; case OPT_VLANS: /* --vlans */ p_main->b_vlans = 1; break; @@ -621,9 +623,6 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) 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: @@ -646,11 +645,12 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) } #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 ); } @@ -662,97 +662,97 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) 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 \taudio output method" - "\n --stereo, --mono \tstereo/mono audio" - "\n" - "\n --novideo \tdisable video" - "\n --vout \tvideo output method" - "\n --display \tdisplay string" - "\n --width , --height \tdisplay dimensions" - "\n -g, --grayscale \tgrayscale output" - "\n --color \tcolor output" - "\n --motion \tmotion compensation method" - "\n --idct \tIDCT method" - "\n --yuv \tYUV method" - "\n --synchro \tforce synchro algorithm" - "\n" - "\n --dvd \tDVD mode" - "\n -a, --dvdaudio \tchoose DVD audio type" - "\n -c, --dvdchannel \tchoose DVD audio channel" - "\n -s, --dvdsubtitle \tchoose DVD subtitle channel" - "\n" - "\n --vlans \tenable vlans" - "\n --server \tvideo server address" - "\n --port \tvideo server port" - "\n --broadcast \tlisten to a broadcast" - "\n" - "\n --warning \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 \taudio output method" + "\n --stereo, --mono \tstereo/mono audio" + "\n" + "\n --novideo \tdisable video" + "\n --vout \tvideo output method" + "\n --display \tdisplay string" + "\n --width , --height \tdisplay dimensions" + "\n -g, --grayscale \tgrayscale output" + "\n --fullscreen \tfullscreen output" + "\n --overlay \taccelerated display" + "\n --color \tcolor output" + "\n --motion \tmotion compensation method" + "\n --idct \tIDCT method" + "\n --yuv \tYUV method" + "\n --synchro \tforce synchro algorithm" + "\n" + "\n -a, --dvdaudio \tchoose DVD audio type" + "\n -c, --dvdchannel \tchoose DVD audio channel" + "\n -s, --dvdsubtitle \tchoose DVD subtitle channel" + "\n" + "\n --input \tinput method" + "\n --vlans \tenable vlans" + "\n --server \tvideo server address" + "\n --port \tvideo server port" + "\n --broadcast \tlisten to a broadcast" + "\n" + "\n --warning \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 "= \tinitialization script" - "\n " INTF_CHANNELS_VAR "= \tchannels list" - "\n " INTF_WARNING_VAR "= \twarning level" ); + intf_MsgImm( "\nInterface parameters:\n" + "\n " INTF_INIT_SCRIPT_VAR "= \tinitialization script" + "\n " INTF_CHANNELS_VAR "= \tchannels list" + "\n " INTF_WARNING_VAR "= \twarning level" ); /* Audio parameters */ - intf_Msg( "\nAudio parameters:" - "\n " AOUT_METHOD_VAR "= \taudio method" - "\n " AOUT_DSP_VAR "= \tdsp device path" - "\n " AOUT_STEREO_VAR "={1|0} \tstereo or mono output" - "\n " AOUT_RATE_VAR "= \toutput rate" ); + intf_MsgImm( "\nAudio parameters:" + "\n " AOUT_METHOD_VAR "= \taudio method" + "\n " AOUT_DSP_VAR "= \tdsp device path" + "\n " AOUT_STEREO_VAR "={1|0} \tstereo or mono output" + "\n " AOUT_RATE_VAR "= \toutput rate" ); /* Video parameters */ - intf_Msg( "\nVideo parameters:" - "\n " VOUT_METHOD_VAR "= \tdisplay method" - "\n " VOUT_DISPLAY_VAR "= \tdisplay used" - "\n " VOUT_WIDTH_VAR "= \tdisplay width" - "\n " VOUT_HEIGHT_VAR "= \tdislay height" - "\n " VOUT_FB_DEV_VAR "= \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 "= \tmotion compensation method" - "\n " IDCT_METHOD_VAR "= \tIDCT method" - "\n " YUV_METHOD_VAR "= \tYUV method" - "\n " VPAR_SYNCHRO_VAR "={I|I+|IP|IP+|IPB} \tsynchro algorithm" - ); + intf_MsgImm( "\nVideo parameters:" + "\n " VOUT_METHOD_VAR "= \tdisplay method" + "\n " VOUT_DISPLAY_VAR "= \tdisplay used" + "\n " VOUT_WIDTH_VAR "= \tdisplay width" + "\n " VOUT_HEIGHT_VAR "= \tdislay height" + "\n " VOUT_FB_DEV_VAR "= \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 "= \tmotion compensation method" + "\n " IDCT_METHOD_VAR "= \tIDCT method" + "\n " YUV_METHOD_VAR "= \tYUV method" + "\n " VPAR_SYNCHRO_VAR "={I|I+|IP|IP+|IPB} \tsynchro algorithm" ); /* DVD parameters */ - intf_Msg( "\nDVD parameters:" - "\n " INPUT_DVD_DEVICE_VAR "= \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 "= \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 "= \tvideo server" - "\n " INPUT_PORT_VAR "= \tvideo server port" - "\n " INPUT_IFACE_VAR "= \tnetwork interface" - "\n " INPUT_BROADCAST_VAR "={1|0} \tbroadcast mode" - "\n " INPUT_VLAN_SERVER_VAR "= \tvlan server" - "\n " INPUT_VLAN_PORT_VAR "= \tvlan server port" - ); + intf_MsgImm( "\nInput parameters:\n" + "\n " INPUT_SERVER_VAR "= \tvideo server" + "\n " INPUT_PORT_VAR "= \tvideo server port" + "\n " INPUT_IFACE_VAR "= \tnetwork interface" + "\n " INPUT_BROADCAST_VAR "={1|0} \tbroadcast mode" + "\n " INPUT_VLAN_SERVER_VAR "= \tvlan server" + "\n " INPUT_VLAN_PORT_VAR "= \tvlan server port" ); } @@ -763,12 +763,11 @@ static void Usage( int i_fashion ) *****************************************************************************/ 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." ); } /***************************************************************************** diff --git a/src/misc/modules.c b/src/misc/modules.c index d92ef80da8..475ecd3feb 100644 --- a/src/misc/modules.c +++ b/src/misc/modules.c @@ -308,7 +308,7 @@ module_t * module_Need( module_bank_t *p_bank, /* 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 ); @@ -329,7 +329,7 @@ void module_Unneed( module_bank_t * p_bank, module_t * p_module ) * 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 ); @@ -357,7 +357,7 @@ static int AllocateDynModule( module_bank_t * p_bank, char * psz_filename ) 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 ); } @@ -452,8 +452,8 @@ static int AllocateDynModule( module_bank_t * p_bank, char * psz_filename ) 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 ); } @@ -677,8 +677,9 @@ static int CallSymbol( module_t * p_module, char * psz_name ) 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 ); } diff --git a/src/misc/playlist.c b/src/misc/playlist.c deleted file mode 100644 index f729406b71..0000000000 --- a/src/misc/playlist.c +++ /dev/null @@ -1,103 +0,0 @@ -/***************************************************************************** - * 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 /* free(), strtol() */ -#include /* sprintf() */ -#include /* strerror() */ -#include /* 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 - */ -