From: Sam Hocevar Date: Wed, 14 Jun 2000 23:55:41 +0000 (+0000) Subject: . input fichier en ligne de commande (le reste a du p�ter, c'est pas X-Git-Tag: 0.1.99e~28 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;ds=sidebyside;h=acbd88f26257a29b7225bd0a8dcd83287b09f4dc;p=vlc . input fichier en ligne de commande (le reste a du p�ter, c'est pas possible autrement) --- diff --git a/AUTHORS b/AUTHORS index 9d624e020f..1bd31b4166 100644 --- a/AUTHORS +++ b/AUTHORS @@ -20,3 +20,5 @@ Renaud Dartus Henri Fallon + Contributors include Aaron Holtzman for his ac3dec decoder, and the + LiViD team for a few lines of code we borrowed here and there. diff --git a/Makefile.in b/Makefile.in index 22991ccc39..11bb129597 100644 --- a/Makefile.in +++ b/Makefile.in @@ -281,14 +281,15 @@ clean: rm -f $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ) $(PLUGIN_OBJ) distclean: clean - rm -f **/*.o **/*.so **/*~ *.log + rm -f */*/*.o plugins/*/*.so **/*~ *.log rm -f Makefile include/defs.h include/config.h rm -f config.status config.cache config.log - rm -f vlc gmon.out core + rm -f vlc gvlc gmon.out core rm -rf .dep install: $(INSTALL) vlc $(prefix)/bin + $(INSTALL) gvlc $(prefix)/bin mkdir -p $(prefix)/lib/videolan/vlc $(INSTALL) $(PLUGIN_OBJ) $(prefix)/lib/videolan/vlc $(INSTALL) share/*.psf $(prefix)/share/videolan/vlc diff --git a/debian/vlc.1 b/debian/vlc.1 index 98022372bd..68febdbcf5 100644 --- a/debian/vlc.1 +++ b/debian/vlc.1 @@ -19,8 +19,9 @@ vlc \- The VideoLAN Client .SH SYNOPSIS .B vlc -.RI [ options ] -.RI [ parameters ] +.RI [ OPTIONS ] +.RI [ PARAMETERS ] +.RI [ FILE ]... .SH DESCRIPTION This manual page documents briefly the .B vlc @@ -58,6 +59,19 @@ Grayscale output. .B \-\-color Color output. .TP +.B \-a, \-\-dvdaudio [ ac3 | lpcm | mpeg | off ] +Choose the audio channel type. Most DVDs have AC3 audio channels, but +you can also have Linear PCM or MPEG layer 2 sound. Also, one might decide +not to activate the audio channel. +.TP +.B \-c, \-\-dvdchannel [ 0\-15 ] +Select the audio channel. Most DVDs only have one or two audio channels, +but some of them have a great number of available languages. Note that the +audio channel will also depend on the channel type. +.TP +.B \-s, \-\-dvdsubtitle [ 0\-31 ] +Select the subtitle channel, if there is one in the stream. +.TP .B \-\-novlans Disable VLANs support. .TP @@ -94,6 +108,11 @@ also accepts a lot of parameters to customize its behaviour. vlc_fb_dev= framebuffer device path vlc_grayscale={1|0} grayscale or color output .TP +.B DVD parameters: + vlc_dvd_audio={ac3|lpcm|mpeg|off} audio type + vlc_dvd_channel=[0-15] audio channel + vlc_dvd_subtitle=[0-31] subtitle channel +.TP .B Input parameters: vlc_server= video server vlc_server_port= video server port diff --git a/include/config.h.in b/include/config.h.in index 77f9fbc356..fc7bba9cc2 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -227,6 +227,10 @@ * mark it to be presented */ #define INPUT_PTS_DELAY (2*CLOCK_FREQ) +#define INPUT_DVD_AUDIO_VAR "vlc_dvd_audio" +#define INPUT_DVD_CHANNEL_VAR "vlc_dvd_channel" +#define INPUT_DVD_SUBTITLE_VAR "vlc_dvd_subtitle" + /***************************************************************************** * Audio configuration *****************************************************************************/ diff --git a/include/input.h b/include/input.h index f511d7e22a..488b34153e 100644 --- a/include/input.h +++ b/include/input.h @@ -328,8 +328,8 @@ typedef struct input_thread_s /* Input method description */ int i_method; /* input method */ int i_handle; /* file/socket descriptor */ - char * psz_source; /* source */ - int i_port; /* port number */ + char * p_source; /* source */ + int i_port; /* port number */ int i_vlan; /* id for vlan method */ input_open_t * p_Open; /* opener of the method */ input_read_t * p_Read; /* reading function */ @@ -371,7 +371,7 @@ typedef struct input_thread_s /***************************************************************************** * Prototypes *****************************************************************************/ -input_thread_t *input_CreateThread ( int i_method, char *psz_source, int i_port, +input_thread_t *input_CreateThread ( int i_method, void *p_source, int i_port, int i_vlan, p_vout_thread_t p_vout, p_aout_thread_t p_aout, int *pi_status ); void input_DestroyThread ( input_thread_t *p_input, int *pi_status ); diff --git a/include/interface.h b/include/interface.h index 5a8a4356c2..296806d388 100644 --- a/include/interface.h +++ b/include/interface.h @@ -64,6 +64,10 @@ typedef struct intf_thread_s /* XXX: Channels array - new API */ //p_intf_channel_t * p_channel[INTF_MAX_CHANNELS];/* channel descriptions */ + /* file list - quick hack */ + char **p_playlist; + int i_list_index; + /* Channels array - NULL if not used */ p_intf_channel_t p_channel; /* description of channels */ diff --git a/src/input/input.c b/src/input/input.c index 54b982d1cf..e91d321511 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -108,7 +108,7 @@ static __inline__ void input_DemuxPSI( 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 ( int i_method, char *psz_source, int i_port, int i_vlan, +input_thread_t *input_CreateThread ( int i_method, void *p_source, int i_port, int i_vlan, p_vout_thread_t p_vout, p_aout_thread_t p_aout, int *pi_status ) { input_thread_t * p_input; /* thread descriptor */ @@ -132,7 +132,7 @@ input_thread_t *input_CreateThread ( int i_method, char *psz_source, int i_port, /* Initialize input method description */ p_input->i_method = i_method; - p_input->psz_source = psz_source; + p_input->p_source = p_source; p_input->i_port = i_port; p_input->i_vlan = i_vlan; switch( i_method ) @@ -208,7 +208,7 @@ input_thread_t *input_CreateThread ( int i_method, char *psz_source, int i_port, } intf_DbgMsg("configuration: method=%d, source=%s, port=%d, vlan=%d\n", - i_method, psz_source, i_port, i_vlan ); + i_method, p_source, i_port, i_vlan ); /* Let the appropriate method open the socket. */ if( p_input->p_Open( p_input ) ) diff --git a/src/input/input_file.c b/src/input/input_file.c index 9ab36f187b..8803bc501a 100644 --- a/src/input/input_file.c +++ b/src/input/input_file.c @@ -35,13 +35,14 @@ #include /* malloc, read ... */ #include - #include "config.h" #include "common.h" #include "threads.h" #include "mtime.h" #include "intf_msg.h" +#include "main.h" + #include "input.h" #include "input_file.h" @@ -53,13 +54,23 @@ #define TS_PACKET_SIZE 188 #define TS_IN_UDP 7 +#define MAX_AUDIO_CHANNEL 15 +#define MAX_SUBTITLES_CHANNEL 31 +#define NO_SUBTITLES 255 + +#define REQUESTED_AC3 0 +#define REQUESTED_MPEG 1 +#define REQUESTED_LPCM 2 +#define REQUESTED_NOAUDIO 255 + #define PS_BUFFER_SIZE 16384 #define NO_PES 0 #define AUDIO_PES 1 #define VIDEO_PES 2 #define AC3_PES 3 #define SUBTITLE_PES 4 -#define PRIVATE_PES 5 +#define LPCM_PES 5 +#define PRIVATE_PES 6 #define UNKNOWN_PES 12 #define PCR_PID 0x20 /* 0x20 == first video stream @@ -98,12 +109,23 @@ typedef struct options_s unsigned int pcr_pid; u8 i_file_type; int in; + char **playlist; + int i_list_index; } options_t; typedef struct s_ps { unsigned int pat_counter; unsigned int pmt_counter; + + /* + * These 3 parameters are passed + * as command line arguments + */ + unsigned int audio_channel; + unsigned int subtitles_channel; + unsigned int audio_type; + /* * 16 audio mpeg streams * 16 audio AV3 streams @@ -149,7 +171,7 @@ typedef struct input_file_s /* local prototypes */ void ps_fill( input_file_t * p_if, boolean_t wait ); -ssize_t safe_read(int fd, unsigned char *buf, int count); +ssize_t safe_read(options_t *p_options, unsigned char *buf, int count); void input_DiskThread( input_file_t * p_if ); int init_synchro( input_file_t * p_if ); @@ -255,21 +277,63 @@ static void adjust( input_file_t * p_if, file_ts_packet *ts ) vlc_mutex_unlock(&p_own_pcr->lock); } -/****************************************************************************** +/***************************************************************************** + * file_next : Opens the next available file + *****************************************************************************/ + +int file_next( options_t *options ) +{ + /* the check for index == 0 should be done _before_ */ + options->i_list_index--; + + if( options->in != -1 ) + { + close( options->in ); + } + + if( !strcmp( options->playlist[options->i_list_index], "-" ) ) + { + /* read stdin */ + return ( options->in = 0 ); + } + else + { + /* read the actual file */ + fprintf( stderr, "Playing file %s\n", + options->playlist[options->i_list_index] ); + return ( options->in = open( options->playlist[options->i_list_index], + O_RDONLY | O_NDELAY ) ); + } +} + +/***************************************************************************** * safe_read : Buffered reading method - ******************************************************************************/ + *****************************************************************************/ -ssize_t safe_read(int fd, unsigned char *buf, int count) +ssize_t safe_read( options_t *options, unsigned char *buf, int count ) { int ret, cnt=0; - - while(cnt < count) + + while( cnt < count ) { - ret = read(fd, buf+cnt, count-cnt); - if(ret < 0) + ret = read( options->in, buf + cnt, count - cnt ); + + if( ret < 0 ) return ret; - if(ret == 0) - break; + + if( ret == 0 ) + { + /* zero means end of file */ + if( options->i_list_index ) + { + file_next( options ); + } + else + { + break; + } + } + cnt += ret; } @@ -308,49 +372,52 @@ int keep_pcr(int pcr_pid, file_ts_packet *ts) int get_pid (ps_t *p_ps) { int i, tofind, delta; + char* type; switch( p_ps->pes_type ) { case VIDEO_PES: - delta = 0x20; + delta = 0x20; /* 0x20 - 0x2f */ + type = "MPEG video"; tofind = p_ps->pes_id; break; case AUDIO_PES: - delta = 0x40; + delta = 0x40; /* 0x40 - 0x5f */ + type = "MPEG audio"; tofind = p_ps->pes_id; break; - case SUBTITLE_PES: - delta = 0x60; + /* XXX: 0x64 is for the PMT, so don't take it !!! */ + case AC3_PES: + delta = 0x80; /* 0x80 - 0x8f */ + type = "MPEG private (AC3 audio)"; tofind = p_ps->private_id; break; - case AC3_PES: - delta = 0x80; + case LPCM_PES: + delta = 0x90; /* 0x90 - 0x9f */ + type = "MPEG private (LPCM audio)"; + tofind = p_ps->private_id; + break; + case SUBTITLE_PES: + delta = 0xa0; /* 0xa0 - 0xbf */ + type = "MPEG private (DVD subtitle)"; tofind = p_ps->private_id; break; - default: + default: return(-1); - } - - /* look in the table if we can find one */ - for ( i=delta; i < delta + 0x20; i++ ) - { - if ( p_ps->association_table[i] == tofind ) - return (i); - if( !p_ps->association_table[i] ) - break; } - /* we must allocate a new entry */ - if (i == delta + 0x20) - return(-1); - - p_ps->association_table[i] = tofind; - p_ps->media_counter[i] = 0; + i = delta + (tofind & 0x1f); + + if( p_ps->association_table[i] == 0) + { + intf_Msg( "Found %s stream at 0x%.2x, allocating PID 0x%.2x\n", + type, tofind, i ); + p_ps->association_table[i] = 1; + } - intf_Msg( "input: allocated new PID 0x%.2x to stream ID 0x%.2x\n", i, tofind ); - return ( i ); + } /****************************************************************************** @@ -528,34 +595,60 @@ void write_pmt(ps_t *ps, unsigned char *ts) ts[17] = 0x02; /* stream type = video */ ts[18] = 0xe0; ts[19] = 0x20; ts[20] = 0xf0; ts[21] = 0x09; /* es info length */ + /* useless info */ ts[22] = 0x07; ts[23] = 0x04; ts[24] = 0x08; ts[25] = 0x80; ts[26] = 0x24; ts[27] = 0x02; ts[28] = 0x11; ts[29] = 0x01; ts[30] = 0xfe; - /* Audio PID */ - ts[31] = 0x88; /* stream type = audio */ /* FIXME : was 0x04 */ - ts[32] = 0xe0; ts[33] = 0x40; - ts[34] = 0xf0; ts[35] = 0x00; /* es info length */ - - /* reserved PID */ -#if 0 - ts[36] = 0x82; /* stream type = private */ - ts[37] = 0xe0; ts[38] = 0x60; /* subtitles */ -#else - ts[36] = 0x81; /* stream type = private */ - ts[37] = 0xe0; ts[38] = 0x80; /* ac3 audio */ -#endif - ts[39] = 0xf0; ts[40] = 0x0f; /* es info length */ - /* useless info */ - ts[41] = 0x90; ts[42] = 0x01; ts[43] = 0x85; ts[44] = 0x89; ts[45] = 0x04; - ts[46] = 0x54; ts[47] = 0x53; ts[48] = 0x49; ts[49] = 0x00; ts[50] = 0x0f; - ts[51] = 0x04; ts[52] = 0x00; ts[53] = 0x00; ts[54] = 0x00; ts[55] = 0x10; + switch ( ps->audio_type ) + { + case 12 : + case REQUESTED_AC3 : + /* ac3 */ + ts[31] = 0x81; /* stream type = audio */ + ts[32] = 0xe0; ts[33] = 0x80 + ps->audio_channel; + ts[34] = 0xf0; ts[35] = 0x00; /* es info length */ + break; - /* CRC */ - ts[56] = 0x96; ts[57] = 0x70; ts[58] = 0x0b; ts[59] = 0x7c; /* for video pts */ - //ts[56] = 0xa1; ts[57] = 0x7c; ts[58] = 0xd8; ts[59] = 0xaa; /* for audio pts */ + case REQUESTED_MPEG : + /* mpeg */ + ts[31] = 0x04; /* stream type = audio */ + ts[32] = 0xe0; ts[33] = 0x40 + ps->audio_channel; + ts[34] = 0xf0; ts[35] = 0x00; /* es info length */ + break; + + case REQUESTED_LPCM : + /* LPCM audio */ + ts[31] = 0x81; + ts[32] = 0xe0; ts[33] = 0xa0 + ps->audio_channel; + ts[34] = 0xf0; ts[35] = 0x00; /* es info length */ + break; + + default : + /* No audio */ + ts[31] = 0x00; + ts[35] = 0x00; /* es info length */ + } + + /* Subtitles */ + if( ps->subtitles_channel == NO_SUBTITLES ) + { + ts[36] = 0x00; + ts[37] = 0x00; ts[38] = 0x00; + ts[39] = 0xf0; ts[40] = 0x00; /* es info length */ + } + else + { + ts[36] = 0x82; + ts[37] = 0xe0; ts[38] = 0xa0 + ( ps->subtitles_channel ); + ts[39] = 0xf0; ts[40] = 0x00; /* es info length */ + } + + /* CRC FIXME: not calculated yet*/ + ts[41] = 0x96; ts[42] = 0x70; ts[43] = 0x0b; ts[44] = 0x7c; - for (i=60 ; i < 188 ; i++) ts[i]=0xFF; /* facultatif ? */ + /* stuffing bytes */ + for (i=45 ; i < 188 ; i++) ts[i]=0xff; /* facultatif ? */ ps->sent_ts++; } @@ -584,6 +677,10 @@ void ps_thread( input_file_t * p_if ) vlc_cond_init( &p_in_data->notfull ); vlc_cond_init( &p_in_data->notempty ); + p_ps->audio_type = main_GetIntVariable( INPUT_DVD_AUDIO_VAR, REQUESTED_AC3 ); + p_ps->audio_channel = main_GetIntVariable( INPUT_DVD_CHANNEL_VAR, 0 ); + p_ps->subtitles_channel = main_GetIntVariable( INPUT_DVD_SUBTITLE_VAR, 0 ); + p_ps->pes_type = NO_PES; p_ps->pes_id = 0; p_ps->private_id = 0; @@ -608,7 +705,8 @@ void ps_thread( input_file_t * p_if ) /* Fill the fifo until it is full */ ps_fill( p_if, 0 ); /* Launch the thread which fills the fifo */ - vlc_thread_create( &p_if->disk_thread, "disk thread", (vlc_thread_func_t)input_DiskThread, p_if ); + vlc_thread_create( &p_if->disk_thread, "disk thread", + (vlc_thread_func_t)input_DiskThread, p_if ); /* Init the synchronization XXX add error detection !!! */ init_synchro( p_if ); } @@ -617,12 +715,12 @@ void ps_thread( input_file_t * p_if ) * ps_read : ps reading method ******************************************************************************/ -ssize_t ps_read (int fd, ps_t * p_ps, void *ts) +ssize_t ps_read( options_t *p_options, ps_t * p_ps, void *ts ) { int pid, readbytes = 0; int datasize; p_ps->ts_written = 0; - + while(p_ps->ts_to_write) { @@ -632,7 +730,7 @@ ssize_t ps_read (int fd, ps_t * p_ps, void *ts) /* copy the remaining bits at the beginning of the PS buffer */ memmove ( p_ps->ps_buffer, p_ps->ps_data, datasize); /* read some bytes */ - readbytes = safe_read(fd, p_ps->ps_buffer + datasize, PS_BUFFER_SIZE - datasize); + readbytes = safe_read( p_options, p_ps->ps_buffer + datasize, PS_BUFFER_SIZE - datasize); if(readbytes == 0) { @@ -652,17 +750,17 @@ ssize_t ps_read (int fd, ps_t * p_ps, void *ts) return -1; } - p_ps->pes_type = NO_PES; - p_ps->offset = 0; + p_ps->pes_type = NO_PES; + p_ps->offset = 0; p_ps->pes_size = (p_ps->ps_data[4] << 8) + p_ps->ps_data[5] + 6; - p_ps->has_pts = p_ps->ps_data[7] & 0xc0; + p_ps->has_pts = p_ps->ps_data[7] & 0xc0; } /* if the actual data we have in pes_data is not a PES, then * we read the next one. */ if( (p_ps->pes_type == NO_PES) && !p_ps->to_skip ) { - p_ps->pes_id = p_ps->ps_data[3]; + p_ps->pes_id = p_ps->ps_data[3]; if (p_ps->pes_id == 0xbd) { @@ -752,14 +850,14 @@ ssize_t ps_read (int fd, ps_t * p_ps, void *ts) else p_ps->pes_type = NO_PES; } - + if (p_ps->ts_to_write) { switch(p_ps->pes_type) { case VIDEO_PES: case AUDIO_PES: - case SUBTITLE_PES: +case SUBTITLE_PES: case AC3_PES: pid = get_pid (p_ps); write_media_ts(p_ps, ts, pid); @@ -787,7 +885,6 @@ void ps_fill( input_file_t * p_if, boolean_t wait ) { in_data_t * p_in_data = &p_if->in_data; ps_t * p_ps = &p_if->ps; - int fd = p_if->options.in; int i, how_many; int pcr_flag; file_ts_packet *ts; @@ -824,7 +921,7 @@ void ps_fill( input_file_t * p_if, boolean_t wait ) /* read a whole UDP packet from the file */ p_ps->ts_to_write = how_many; - if(ps_read(fd, p_ps, ts = (file_ts_packet *)(p_in_data->buf + p_in_data->end)) != how_many) + if(ps_read(&p_if->options, p_ps, ts = (file_ts_packet *)(p_in_data->buf + p_in_data->end)) != how_many) { msleep( 50000 ); /* XXX we need an INPUT_IDLE */ intf_ErrMsg( "input error: read() error\n" ); @@ -904,7 +1001,7 @@ int init_synchro( input_file_t * p_if ) } /***************************************************************************** - * input_FileOpen : open a file descriptor + * input_DiskThread : main thread *****************************************************************************/ void input_DiskThread( input_file_t * p_if ) @@ -920,14 +1017,18 @@ int input_FileOpen( input_thread_t *p_input ) { options_t * p_options = &input_file.options; - p_options->in = open( p_input->psz_source, O_RDONLY ); - if( p_options->in < 0 ) + p_options->in = -1; + + p_options->playlist = (char **)p_input->p_source; + p_options->i_list_index = p_input->i_port; + + if( file_next( p_options ) < 0 ) { - intf_ErrMsg( "input error: cannot open the file %s", p_input->psz_source ); + intf_ErrMsg( "input error: cannot open the file %s", p_input->p_source ); } input_file.b_die = 0; - read( p_options->in, &p_options->i_file_type, 1 ); + safe_read( p_options, &p_options->i_file_type, 1 ); switch( p_options->i_file_type ) { @@ -944,7 +1045,7 @@ int input_FileOpen( input_thread_t *p_input ) } - return( 0 ); +return( 0 ); } /***************************************************************************** @@ -997,7 +1098,7 @@ int input_FileRead( input_thread_t *p_input, const struct iovec *p_vector, vlc_cond_signal(&p_in_data->notfull); vlc_mutex_unlock(&p_in_data->lock); - return( 188*howmany ); + return( 188*howmany ); } /***************************************************************************** diff --git a/src/input/input_network.c b/src/input/input_network.c index 343b9c2fac..9be288c9f2 100644 --- a/src/input/input_network.c +++ b/src/input/input_network.c @@ -186,12 +186,12 @@ int input_NetworkOpen( input_thread_t *p_input ) */ /* Use default host if not specified */ - if( p_input->psz_source == NULL ) + if( p_input->p_source == NULL ) { - p_input->psz_source = main_GetPszVariable( INPUT_SERVER_VAR, INPUT_SERVER_DEFAULT ); + p_input->p_source = main_GetPszVariable( INPUT_SERVER_VAR, INPUT_SERVER_DEFAULT ); } - if( BuildInetAddr( &sa_in, p_input->psz_source, htons(0) ) == (-1) ) + if( BuildInetAddr( &sa_in, p_input->p_source, htons(0) ) == (-1) ) { close( p_input->i_handle ); return( -1 ); diff --git a/src/interface/interface.c b/src/interface/interface.c index c9ebb191fc..f1cfc0780d 100644 --- a/src/interface/interface.c +++ b/src/interface/interface.c @@ -157,9 +157,13 @@ intf_thread_t* intf_Create( void ) *****************************************************************************/ void intf_Run( intf_thread_t *p_intf ) { + if( p_intf->p_playlist ) + { + p_intf->p_input = input_CreateThread( INPUT_METHOD_TS_FILE, (void *)p_intf->p_playlist, p_intf->i_list_index, 0, p_main->p_intf->p_vout, p_main->p_aout, NULL ); + } /* Execute the initialization script - if a positive number is returned, * the script could be executed but failed */ - if( intf_ExecScript( main_GetPszVariable( INTF_INIT_SCRIPT_VAR, INTF_INIT_SCRIPT_DEFAULT ) ) > 0 ) + else if( intf_ExecScript( main_GetPszVariable( INTF_INIT_SCRIPT_VAR, INTF_INIT_SCRIPT_DEFAULT ) ) > 0 ) { intf_ErrMsg("warning: error(s) during startup script\n"); } diff --git a/src/interface/intf_ctrl.c b/src/interface/intf_ctrl.c index aaf00b9f7c..327a93779d 100644 --- a/src/interface/intf_ctrl.c +++ b/src/interface/intf_ctrl.c @@ -459,10 +459,12 @@ static int SpawnInput( int i_argc, intf_arg_t *p_argv ) { int i_arg; int i_method = 0; /* method parameter */ - char * psz_source = NULL; /* source parameter */ + char * p_source = NULL; /* source parameter */ int i_port = 0; /* port parameter */ int i_vlan = 0; /* vlan parameter */ + fprintf( stderr, "spawn input\n" ); + /* Parse parameters - see command list above */ for ( i_arg = 1; i_arg < i_argc; i_arg++ ) { @@ -474,7 +476,7 @@ static int SpawnInput( int i_argc, intf_arg_t *p_argv ) case 1: /* filename, hostname, ip */ case 2: case 3: - psz_source = p_argv[i_arg].psz_str; + p_source = p_argv[i_arg].psz_str; break; case 4: /* port */ i_port = p_argv[i_arg].i_num; @@ -491,7 +493,7 @@ static int SpawnInput( int i_argc, intf_arg_t *p_argv ) input_DestroyThread( p_main->p_intf->p_input, NULL ); } - p_main->p_intf->p_input = input_CreateThread( i_method, psz_source, i_port, i_vlan, + p_main->p_intf->p_input = input_CreateThread( i_method, p_source, i_port, i_vlan, p_main->p_intf->p_vout, p_main->p_aout, NULL ); return( INTF_NO_ERROR ); diff --git a/src/interface/main.c b/src/interface/main.c index 018dc54072..6265f8057e 100644 --- a/src/interface/main.c +++ b/src/interface/main.c @@ -41,6 +41,7 @@ #include "mtime.h" #include "plugins.h" #include "input_vlan.h" +#include "input_file.h" #include "intf_msg.h" #include "interface.h" @@ -106,6 +107,11 @@ static const struct option longopts[] = { "grayscale", 0, 0, 'g' }, { "color", 0, 0, OPT_COLOR }, + /* DVD options */ + { "dvdaudio", 1, 0, 'a' }, + { "dvdchannel", 1, 0, 'c' }, + { "dvdsubtitle", 1, 0, 's' }, + /* Input options */ { "novlans", 0, 0, OPT_NOVLANS }, { "server", 1, 0, OPT_SERVER }, @@ -115,7 +121,7 @@ static const struct option longopts[] = }; /* Short options */ -static const char *psz_shortopts = "hHvg"; +static const char *psz_shortopts = "hHvga:s:c:"; /***************************************************************************** * Global variable program_data - this is the one and only, see main.h @@ -149,6 +155,9 @@ static int TestMMX ( void ); int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) { main_t main_data; /* root of all data - see main.h */ + char **p_playlist; + int i_list_index; + p_main = &main_data; /* set up the global variable */ /* @@ -180,6 +189,29 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) intf_MsgDestroy(); return( errno ); } + + /* get command line files */ + i_list_index = 0; + + if( optind < i_argc ) + { + int i_index = 0; + p_playlist = malloc( (i_list_index = i_argc - optind) + * sizeof(int) ); + + while( i_argc - i_index > optind ) + { + p_playlist[ i_index ] = ppsz_argv[ i_argc - i_index - 1]; + i_index++; + } + } + else + { + p_playlist = malloc( sizeof(int) ); + p_playlist[ 0 ] = "-"; + i_list_index = 1; + } + intf_MsgImm( COPYRIGHT_MESSAGE "\n" ); /* print welcome message */ /* @@ -212,7 +244,11 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) main_data.p_intf = intf_Create(); if( main_data.p_intf != NULL ) { + main_data.p_intf->p_playlist = p_playlist; + main_data.p_intf->i_list_index = i_list_index; + InitSignalHandler(); /* prepare signals for interception */ + intf_Run( main_data.p_intf ); intf_Destroy( main_data.p_intf ); } @@ -426,6 +462,24 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) main_PutIntVariable( VOUT_GRAYSCALE_VAR, 0 ); break; + /* DVD options */ + case 'a': + if ( ! strcmp(optarg, "mpeg") ) + main_PutIntVariable( INPUT_DVD_AUDIO_VAR, REQUESTED_MPEG ); + else if ( ! strcmp(optarg, "lpcm") ) + main_PutIntVariable( INPUT_DVD_AUDIO_VAR, REQUESTED_LPCM ); + else if ( ! strcmp(optarg, "off") ) + main_PutIntVariable( INPUT_DVD_AUDIO_VAR, REQUESTED_NOAUDIO ); + else + main_PutIntVariable( INPUT_DVD_AUDIO_VAR, REQUESTED_AC3 ); + break; + case 'c': + main_PutIntVariable( INPUT_DVD_CHANNEL_VAR, atoi(optarg) ); + break; + case 's': + main_PutIntVariable( INPUT_DVD_SUBTITLE_VAR, atoi(optarg) ); + break; + /* Input options */ case OPT_NOVLANS: /* --novlans */ p_main->b_vlans = 0; @@ -487,6 +541,10 @@ static void Usage( int i_fashion ) " -g, --grayscale \tgrayscale output\n" " --color \tcolor output\n" "\n" + " -a, --dvdaudio \tchoose DVD audio type\n" + " -c, --dvdchannel \tchoose DVD audio channel\n" + " -s, --dvdsubtitle \tchoose DVD subtitle channel\n" + "\n" " --novlans \tdisable vlans\n" " --server \tvideo server address\n" " --port \tvideo server port\n" @@ -522,6 +580,13 @@ static void Usage( int i_fashion ) " " VOUT_FB_DEV_VAR "= \tframebuffer device path\n" " " VOUT_GRAYSCALE_VAR "={1|0} \tgrayscale or color output\n" ); + /* DVD parameters */ + intf_Msg( "\n" + "DVD parameters:\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\n" ); + /* Input parameters */ intf_Msg( "\n" "Input parameters:\n" @@ -544,7 +609,7 @@ static void Version( void ) "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.\n" ); - + } /*****************************************************************************