From 55ce4df11c23b08329ba70385dbde6889d417edf Mon Sep 17 00:00:00 2001 From: =?utf8?q?St=C3=A9phane=20Borel?= Date: Wed, 6 Mar 2002 01:20:56 +0000 Subject: [PATCH] *Removed an occurance of former angle item in gtk. *Fixed a bug in ES management introduced lately in DVD/DvdRead. *Beginning of reorganisation in DVD plugin source files, in order to try to make it easier to understand. There is some work left though :p. *Decreased the score for VCD plugin, as the VCD demuxer was used even for DVD :p. It should make autodetection work. Some comment: -I think that VCDInit should make a test on the access plugin and be launched only if the access plugin is VCD, -VCDOpen shouldn't set p_input->b_error: if it fails we just try another module, -PSRead doesn't need to be duplicated anymore: input_ReadPS is now available for plugins (cf Christophe's commit). Please comment around that: I'd like to know if the behaviour I've described is the one everyone expects. Enjoy my new bugs :p --- doc/vlc.1 | 24 +- plugins/dvd/Makefile | 2 +- plugins/dvd/{input_dvd.h => dvd.h} | 10 +- plugins/dvd/{input_dvd.c => dvd_access.c} | 920 +++++----------------- plugins/dvd/dvd_demux.c | 138 ++++ plugins/dvd/dvd_es.c | 305 +++++++ plugins/dvd/dvd_es.h | 27 + plugins/dvd/dvd_ifo.c | 4 +- plugins/dvd/dvd_seek.c | 222 ++++++ plugins/dvd/dvd_seek.h | 26 + plugins/dvd/dvd_summary.c | 4 +- plugins/dvd/dvd_udf.c | 4 +- plugins/dvdread/input_dvdread.c | 10 +- plugins/gtk/gtk_display.c | 4 +- plugins/gtk/gtk_menu.c | 55 +- plugins/vcd/vcd.c | 6 +- src/input/input.c | 8 +- 17 files changed, 960 insertions(+), 809 deletions(-) rename plugins/dvd/{input_dvd.h => dvd.h} (93%) rename plugins/dvd/{input_dvd.c => dvd_access.c} (59%) create mode 100644 plugins/dvd/dvd_demux.c create mode 100644 plugins/dvd/dvd_es.c create mode 100644 plugins/dvd/dvd_es.h create mode 100644 plugins/dvd/dvd_seek.c create mode 100644 plugins/dvd/dvd_seek.h diff --git a/doc/vlc.1 b/doc/vlc.1 index 3aa66b65ba..b33f5fcb31 100644 --- a/doc/vlc.1 +++ b/doc/vlc.1 @@ -33,7 +33,7 @@ recognizes several URL-style items: .B *.mpg, *.vob Plain MPEG-1/2 files .TP -.B dvd:[@] +.B dvd:[][@][@[][,[<chapter>][,<angle>]]] DVD device (for instance dvd:/dev/dvd). The raw device is optional and must have been prepared beforehands. .TP @@ -140,35 +140,19 @@ displaying of all images. Note that vlc is not guaranteed to behave properly if you ask it to display more images than your CPU can cope with. .TP -.B \-t, \-\-dvdtitle <title> -Choose the DVD title. Most movies on DVDs start on the first title, but you may want to manually select another title. -.TP -.B \-T, \-\-dvdchapter <title> -Choose the DVD chapter. DVDs are divided into titles, which in turn are divided into chapters. -.TP -.B \-a, \-\-dvdaudio [ ac3 | lpcm | mpeg | off ] +.B \-a, \-\-input_audio [ 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 \-u, \-\-dvdangle <num> -Choose the angle, available on some DVDs. -.TP -.B \-c, \-\-dvdchannel [ 0\-15 ] +.B \-c, \-\-input_channel [ 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 ] +.B \-s, \-\-input_subtitle [ 0\-31 ] Select the subtitle channel, if there is one in the stream. .TP -.B \-\-dvdcss-method <method> -Select the CSS decryption scheme when using libdvdcss. Usually to choose -from "disc", "title" or "key", but depends on your libdvdcss version. -.TP -.B \-\-dvdcss-verbose <level> -Select the CSS decryption verbosity level, 0, 1 or 2. -.TP .B \-\-input <method> Choose the input method, "dvd", "ps", "ts" for instance. .TP diff --git a/plugins/dvd/Makefile b/plugins/dvd/Makefile index 6d1a3f7022..92e8bcde72 100644 --- a/plugins/dvd/Makefile +++ b/plugins/dvd/Makefile @@ -1,4 +1,4 @@ -dvd_SOURCES = dvd.c input_dvd.c dvd_ifo.c dvd_udf.c dvd_summary.c $(SRC_DVD_EXTRA) +dvd_SOURCES = dvd.c dvd_access.c dvd_demux.c dvd_seek.c dvd_es.c dvd_ifo.c dvd_udf.c dvd_summary.c $(SRC_DVD_EXTRA) EXTRA_DEP = ../../lib/libdvdcss.a ../../lib/libdvdcss.so diff --git a/plugins/dvd/input_dvd.h b/plugins/dvd/dvd.h similarity index 93% rename from plugins/dvd/input_dvd.h rename to plugins/dvd/dvd.h index 9f3e00d531..3cb03a49a9 100644 --- a/plugins/dvd/input_dvd.h +++ b/plugins/dvd/dvd.h @@ -1,8 +1,8 @@ /***************************************************************************** - * input_dvd.h: thread structure of the DVD plugin + * dvd.h: thread structure of the DVD plugin ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: input_dvd.h,v 1.25 2002/03/01 01:12:28 stef Exp $ + * $Id: dvd.h,v 1.1 2002/03/06 01:20:56 stef Exp $ * * Author: Stéphane Borel <stef@via.ecp.fr> * @@ -36,6 +36,9 @@ typedef struct thread_dvd_data_s { dvdcss_handle dvdhandle; /* libdvdcss handle */ + int i_audio_nb; + int i_spu_nb; + /* Navigation information */ int i_title; int i_title_id; @@ -57,9 +60,6 @@ typedef struct thread_dvd_data_s int i_start; int i_size; - /* Scrambling Information */ - struct css_s * p_css; - /* Structure that contains all information of the DVD */ struct ifo_s * p_ifo; diff --git a/plugins/dvd/input_dvd.c b/plugins/dvd/dvd_access.c similarity index 59% rename from plugins/dvd/input_dvd.c rename to plugins/dvd/dvd_access.c index b9e7c08ad8..c48a76fb03 100644 --- a/plugins/dvd/input_dvd.c +++ b/plugins/dvd/dvd_access.c @@ -1,4 +1,4 @@ -/* input_dvd.c: DVD raw reading plugin. +/* dvd_access.c: DVD access plugin. ***************************************************************************** * This plugins should handle all the known specificities of the DVD format, * especially the 2048 bytes logical block size. @@ -8,7 +8,7 @@ * -dvd_udf to find files ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: input_dvd.c,v 1.132 2002/03/05 17:46:33 stef Exp $ + * $Id: dvd_access.c,v 1.1 2002/03/06 01:20:56 stef Exp $ * * Author: Stéphane Borel <stef@via.ecp.fr> * @@ -50,10 +50,6 @@ # include <strings.h> #endif -#if defined( WIN32 ) -# include <io.h> /* read() */ -#endif - #ifdef GOD_DAMN_DMCA # include "dummy_dvdcss.h" #else @@ -65,16 +61,15 @@ #include "input_ext-dec.h" #include "input_ext-plugins.h" -#include "input_dvd.h" +#include "dvd.h" +#include "dvd_es.h" +#include "dvd_seek.h" #include "dvd_ifo.h" #include "dvd_summary.h" #include "iso_lang.h" #include "debug.h" -/* how many packets DVDDemux will read in each loop */ -#define DVD_READ_ONCE 64 - /***************************************************************************** * Local prototypes *****************************************************************************/ @@ -87,17 +82,7 @@ static int DVDSetProgram ( struct input_thread_s *, pgrm_descriptor_t * ); static int DVDRead ( struct input_thread_s *, byte_t *, size_t ); static void DVDSeek ( struct input_thread_s *, off_t ); -static int DVDRewind ( struct input_thread_s * ); -static int DVDDemux ( struct input_thread_s * ); -static int DVDInit ( struct input_thread_s * ); -static void DVDEnd ( struct input_thread_s * ); - -/* called only inside */ -static void DVDLaunchDecoders( input_thread_t * p_input ); -static int DVDChooseAngle( thread_dvd_data_t * ); -static int DVDFindCell( thread_dvd_data_t * ); -static int DVDFindSector( thread_dvd_data_t * ); -static int DVDChapterSelect( thread_dvd_data_t *, int ); +static char * DVDParse( input_thread_t * ); /***************************************************************************** * Functions exported as capabilities. They are declared as static so that @@ -115,124 +100,6 @@ void _M( access_getfunctions)( function_list_t * p_function_list ) #undef input } -void _M( demux_getfunctions)( function_list_t * p_function_list ) -{ -#define demux p_function_list->functions.demux - demux.pf_init = DVDInit; - demux.pf_end = DVDEnd; - demux.pf_demux = DVDDemux; - demux.pf_rewind = DVDRewind; -#undef demux -} - -/* - * Data demux functions - */ - -/***************************************************************************** - * DVDInit: initializes DVD structures - *****************************************************************************/ -static int DVDInit( input_thread_t * p_input ) -{ - - if( strncmp( p_input->p_access_module->psz_name, "dvd", 3 ) ) - { - return -1; - } - - vlc_mutex_lock( &p_input->stream.stream_lock ); - - DVDLaunchDecoders( p_input ); - - vlc_mutex_unlock( &p_input->stream.stream_lock ); - - return 0; -} - -/***************************************************************************** - * DVDEnd: frees unused data - *****************************************************************************/ -static void DVDEnd( input_thread_t * p_input ) -{ -} - -/***************************************************************************** - * DVDDemux - *****************************************************************************/ -#define PEEK( SIZE ) \ - i_result = input_Peek( p_input, &p_peek, SIZE ); \ - if( i_result == -1 ) \ - { \ - return( -1 ); \ - } \ - else if( i_result < SIZE ) \ - { \ - /* EOF */ \ - return( 0 ); \ - } - -static int DVDDemux( input_thread_t * p_input ) -{ - int i; - byte_t * p_peek; - data_packet_t * p_data; - ssize_t i_result; - int i_packet_size; - - - /* Read headers to compute payload length */ - for( i = 0 ; i < DVD_READ_ONCE ; i++ ) - { - - /* Read what we believe to be a packet header. */ - PEEK( 4 ); - - /* Default header */ - if( U32_AT( p_peek ) != 0x1BA ) - { - /* That's the case for all packets, except pack header. */ - i_packet_size = U16_AT( p_peek + 4 ); - } - else - { - /* MPEG-2 Pack header. */ - i_packet_size = 8; - } - - /* Fetch a packet of the appropriate size. */ - i_result = input_SplitBuffer( p_input, &p_data, i_packet_size + 6 ); - if( i_result <= 0 ) - { - return( i_result ); - } - - /* In MPEG-2 pack headers we still have to read stuffing bytes. */ - if( (p_data->p_demux_start[3] == 0xBA) && (i_packet_size == 8) ) - { - size_t i_stuffing = (p_data->p_demux_start[13] & 0x7); - /* Force refill of the input buffer - though we don't care - * about p_peek. Please note that this is unoptimized. */ - PEEK( i_stuffing ); - p_input->p_current_data += i_stuffing; - } - - input_DemuxPS( p_input, p_data ); - - } - - return i; -} - -/***************************************************************************** - * DVDRewind : reads a stream backward - *****************************************************************************/ -static int DVDRewind( input_thread_t * p_input ) -{ - return( -1 ); -} - - - /* * Data access functions */ @@ -242,216 +109,39 @@ static int DVDRewind( input_thread_t * p_input ) *****************************************************************************/ static int DVDOpen( struct input_thread_s *p_input ) { - struct stat stat_info; - char * psz_orig; - char * psz_parser; char * psz_device; - char * psz_raw; - char * psz_next; dvdcss_handle dvdhandle; thread_dvd_data_t * p_dvd; input_area_t * p_area; - boolean_t b_options = 0; - int i_title = 1; - int i_chapter = 1; - int i_angle = 1; int i; - psz_orig = psz_parser = psz_device = strdup( p_input->psz_name ); - if( !psz_orig ) - { - return( -1 ); - } - - - /* Parse input string : - * [device][@rawdevice][@[title][,[chapter][,angle]]] */ - while( *psz_parser && *psz_parser != '@' ) - { - psz_parser++; - } - - if( *psz_parser == '@' ) - { - /* Maybe found raw device or option list */ - *psz_parser = '\0'; - psz_raw = ++psz_parser; - } - else - { - psz_raw = NULL; - } - - if( *psz_parser && !strtol( psz_parser, NULL, 10 ) ) - { - /* what we've found is either a raw device or a partial option - * list e.g. @,29 or both a device and a list ; search end of string */ - while( *psz_parser && *psz_parser != '@' ) - { - psz_parser++; - } - - if( *psz_parser == '@' ) - { - /* found end of raw device, and beginning of options */ - *psz_parser = '\0'; - ++psz_parser; - b_options = 1; - } - else - { - psz_parser = psz_raw + 1; - for( i=0 ; i<3 ; i++ ) - { - if( !*psz_parser ) - { - /* we have only a raw device */ - break; - } - if( strtol( psz_parser, NULL, 10 ) ) - { - /* we have only a partial list of options, no device */ - psz_parser = psz_raw; - psz_raw = NULL; - b_options = 1; - break; - } - psz_parser++; - } - } - } - else - { - /* found beginning of options ; no raw device specified */ - psz_raw = NULL; - b_options = 1; - } - - if( b_options ) - { - /* Found options */ - i_title = (int)strtol( psz_parser, &psz_next, 10 ); - if( *psz_next ) - { - psz_parser = psz_next + 1; - i_chapter = (int)strtol( psz_parser, &psz_next, 10 ); - if( *psz_next ) - { - i_angle = (int)strtol( psz_next + 1, NULL, 10 ); - } - } - - i_title = i_title ? i_title : 1; - i_chapter = i_chapter ? i_chapter : 1; - i_angle = i_angle ? i_angle : 1; - } - - if( psz_raw ) - { - if( *psz_raw ) - { - /* check the raw device */ - if( stat( psz_raw, &stat_info ) == -1 ) - { - intf_WarnMsg( 3, "dvd warning: cannot stat() raw" - " device `%s' (%s)", - psz_raw, strerror(errno)); - /* put back '@' */ - *(psz_raw - 1) = '@'; - psz_raw = NULL; - } - else - { - char * psz_env; - -#ifndef WIN32 - if( !S_ISCHR(stat_info.st_mode) ) - { - intf_WarnMsg( 3, "dvd warning: raw device %s is" - " not a valid char device", psz_raw ); - /* put back '@' */ - *(psz_raw - 1) = '@'; - psz_raw = NULL; - } - else -#endif - { - psz_env = malloc( strlen("DVDCSS_RAW_DEVICE=") - + strlen( psz_raw ) + 1 ); - sprintf( psz_env, "DVDCSS_RAW_DEVICE=%s", psz_raw ); - putenv( psz_env ); - } - } - } - else - { - psz_raw = NULL; - } - } - - if( !*psz_device ) - { - if( !p_input->psz_access ) - { - /* no device and no access specified: we probably don't want DVD */ - free( psz_orig ); - return -1; - } - psz_device = config_GetPszVariable( INPUT_DVD_DEVICE_VAR ); - } - - /* check block device */ - if( stat( psz_device, &stat_info ) == -1 ) - { - intf_ErrMsg( "input error: cannot stat() device `%s' (%s)", - psz_device, strerror(errno)); - return( -1 ); - } - -#ifndef WIN32 - if( !S_ISBLK(stat_info.st_mode) && !S_ISCHR(stat_info.st_mode) ) + p_dvd = malloc( sizeof(thread_dvd_data_t) ); + if( p_dvd == NULL ) { - intf_WarnMsg( 3, "input: DVD plugin discarded" - " (not a valid block device)" ); + intf_ErrMsg( "dvd error: out of memory" ); return -1; } -#endif + p_input->p_access_data = (void *)p_dvd; - if( psz_raw ) + /* Parse command line */ + if( !( psz_device = DVDParse( p_input ) ) ) { + free( p_dvd ); + return -1; } - - intf_WarnMsg( 2, "input: dvd=%s raw=%s title=%d chapter=%d angle=%d", - psz_device, psz_raw, i_title, i_chapter, i_angle ); /* * set up input */ p_input->i_mtu = 0; - vlc_mutex_lock( &p_input->stream.stream_lock ); - - p_input->stream.i_method = INPUT_METHOD_DVD; - - /* If we are here we can control the pace... */ - p_input->stream.b_pace_control = 1; - - p_input->stream.b_seekable = 1; - p_input->stream.p_selected_area->i_size = 0; - - p_input->stream.p_selected_area->i_tell = 0; - - vlc_mutex_unlock( &p_input->stream.stream_lock ); - /* * get plugin ready */ dvdhandle = dvdcss_open( psz_device ); - /* free allocated strings */ - if( psz_device != psz_orig ) - free( psz_device ); - free( psz_orig ); + /* free allocated string */ + free( psz_device ); if( dvdhandle == NULL ) @@ -460,15 +150,7 @@ static int DVDOpen( struct input_thread_s *p_input ) return -1; } - p_dvd = malloc( sizeof(thread_dvd_data_t) ); - if( p_dvd == NULL ) - { - intf_ErrMsg( "dvd error: out of memory" ); - return -1; - } - p_dvd->dvdhandle = (dvdcss_handle) dvdhandle; - p_input->p_access_data = (void *)p_dvd; if( dvdcss_seek( p_dvd->dvdhandle, 0, DVDCSS_NOFLAGS ) < 0 ) { @@ -495,11 +177,17 @@ static int DVDOpen( struct input_thread_s *p_input ) /* Set stream and area data */ vlc_mutex_lock( &p_input->stream.stream_lock ); + p_input->stream.i_method = INPUT_METHOD_DVD; + p_input->stream.b_pace_control = 1; + p_input->stream.b_seekable = 1; + p_input->stream.p_selected_area->i_size = 0; + p_input->stream.p_selected_area->i_tell = 0; + /* Initialize ES structures */ input_InitStream( p_input, sizeof( stream_ps_data_t ) ); #define title_inf p_dvd->p_ifo->vmg.title_inf - intf_WarnMsg( 2, "dvd info: number of titles: %d", title_inf.i_title_nb ); + intf_WarnMsg( 3, "dvd info: number of titles: %d", title_inf.i_title_nb ); #define area p_input->stream.pp_areas /* We start from 1 here since the default area 0 @@ -527,17 +215,19 @@ static int DVDOpen( struct input_thread_s *p_input ) } #undef area - p_dvd->i_title = i_title <= title_inf.i_title_nb ? i_title : 1; + p_dvd->i_title = p_dvd->i_title <= title_inf.i_title_nb ? + p_dvd->i_title : 1; #undef title_inf - p_area = p_input->stream.pp_areas[p_dvd->i_title]; - p_dvd->i_chapter = i_chapter < p_area->i_part_nb ? i_chapter : 1; + p_dvd->i_chapter = p_dvd->i_chapter < p_area->i_part_nb ? + p_dvd->i_chapter : 1; p_area->i_part = p_dvd->i_chapter; - p_dvd->i_angle = i_angle; - + p_dvd->i_audio_nb = 0; + p_dvd->i_spu_nb = 0; + /* set title, chapter, audio and subpic */ if( DVDSetArea( p_input, p_area ) ) { @@ -548,7 +238,6 @@ static int DVDOpen( struct input_thread_s *p_input ) vlc_mutex_unlock( &p_input->stream.stream_lock ); return 0; - } /***************************************************************************** @@ -570,7 +259,7 @@ static void DVDClose( struct input_thread_s *p_input ) } /***************************************************************************** - * DVDSetProgram: Does nothing, a DVD is mono-program + * DVDSetProgram: used to change angle *****************************************************************************/ static int DVDSetProgram( input_thread_t * p_input, pgrm_descriptor_t * p_program ) @@ -583,6 +272,8 @@ static int DVDSetProgram( input_thread_t * p_input, p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); i_angle = p_program->i_number; + /* DVD is actually mono-program: we only need the current angle + * number, so copy the data between programs */ memcpy( p_program, p_input->stream.p_selected_program, sizeof(pgrm_descriptor_t) ); p_program->i_number = i_angle; @@ -623,11 +314,7 @@ static int DVDSetProgram( input_thread_t * p_input, static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) { thread_dvd_data_t * p_dvd; - es_descriptor_t * p_es; - u16 i_id; int i_vts_title; - int i_audio_nb = 0; - int i_spu_nb = 0; int i; p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); @@ -639,13 +326,12 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) { /* Reset the Chapter position of the old title */ p_input->stream.p_selected_area->i_part = 0; + p_input->stream.p_selected_area = p_area; /* * We have to load all title information */ /* Change the default area */ - p_input->stream.p_selected_area = - p_input->stream.pp_areas[p_area->i_id]; /* title number: it is not vts nb!, * it is what appears in the interface list */ @@ -674,15 +360,7 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) intf_WarnMsg( 3, "dvd: title %d vts_title %d pgc %d", p_dvd->i_title, i_vts_title, p_dvd->i_title_id ); - /* - * Angle management - */ - p_dvd->i_angle_nb = vmg.title_inf.p_attr[p_dvd->i_title-1].i_angle_nb; - if( ( p_dvd->i_angle <= 0 ) || p_dvd->i_angle > p_dvd->i_angle_nb ) - { - p_dvd->i_angle = 1; - } - + /* * Set selected title start and size */ @@ -738,14 +416,6 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) p_input->stream.p_selected_area->i_start = LB2OFF( p_dvd->i_start ); p_input->stream.p_selected_area->i_size = LB2OFF( p_dvd->i_size ); -#if 0 - /* start at the beginning of the title */ - /* FIXME: create a conf option to select whether to restart - * title or not */ - p_input->stream.p_selected_area->i_tell = 0; - p_input->stream.p_selected_area->i_part = 1; -#endif - /* * Destroy obsolete ES by reinitializing programs * and find all ES in title with ifo data @@ -754,23 +424,14 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) { /* We don't use input_EndStream here since * we keep area structures */ - - /* Unselect all ES */ - /* - for( i = 0 ; i < p_input->stream.i_selected_es_number ; i++ ) + while( p_input->stream.i_es_number ) { - input_UnselectES( p_input, p_input->stream.pp_selected_es[i] ); + input_DelES( p_input, p_input->stream.pp_es[0] ); } -*/ - for( i = 0 ; i < p_input->stream.i_es_number ; i++ ) + while( p_input->stream.i_pgrm_number ) { - input_DelES( p_input, p_input->stream.pp_es[i] ); - } - - for( i = 0 ; i < p_input->stream.i_pgrm_number ; i++ ) - { - input_DelProgram( p_input, p_input->stream.pp_programs[i] ); + input_DelProgram( p_input, p_input->stream.pp_programs[0] ); } if( p_input->stream.pp_selected_es ) @@ -780,9 +441,16 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) } p_input->stream.i_selected_es_number = 0; } - - /* angle */ - + + /* + * Angle management: angles are handled through programs + */ + p_dvd->i_angle_nb = vmg.title_inf.p_attr[p_dvd->i_title-1].i_angle_nb; + if( ( p_dvd->i_angle <= 0 ) || p_dvd->i_angle > p_dvd->i_angle_nb ) + { + p_dvd->i_angle = 1; + } + input_AddProgram( p_input, 1, sizeof( stream_ps_data_t ) ); p_input->stream.p_selected_program = p_input->stream.pp_programs[0]; @@ -798,130 +466,12 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) /* No PSM to read in DVD mode, we already have all information */ p_input->stream.p_selected_program->b_is_ok = 1; - p_es = NULL; - - /* ES 0 -> video MPEG2 */ - IfoPrintVideo( p_dvd ); - - p_es = input_AddES( p_input, NULL, 0xe0, 0 ); - p_es->i_stream_id = 0xe0; - p_es->i_type = MPEG2_VIDEO_ES; - p_es->i_cat = VIDEO_ES; + DVDReadVideo( p_input ); -#define audio_status \ - vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_audio_status[i-1] - /* Audio ES, in the order they appear in .ifo */ - for( i = 1 ; i <= vts.manager_inf.i_audio_nb ; i++ ) - { - IfoPrintAudio( p_dvd, i ); - - /* audio channel is active if first byte is 0x80 */ - if( audio_status.i_available ) - { - i_audio_nb++; - - switch( vts.manager_inf.p_audio_attr[i-1].i_coding_mode ) - { - case 0x00: /* AC3 */ - i_id = ( ( 0x80 + audio_status.i_position ) << 8 ) | 0xbd; - p_es = input_AddES( p_input, NULL, i_id, 0 ); - p_es->i_stream_id = 0xbd; - p_es->i_type = AC3_AUDIO_ES; - p_es->b_audio = 1; - p_es->i_cat = AUDIO_ES; - strcpy( p_es->psz_desc, DecodeLanguage( hton16( - vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) ); - strcat( p_es->psz_desc, " (ac3)" ); - - break; - case 0x02: - case 0x03: /* MPEG audio */ - i_id = 0xc0 + audio_status.i_position; - p_es = input_AddES( p_input, NULL, i_id, 0 ); - p_es->i_stream_id = i_id; - p_es->i_type = MPEG2_AUDIO_ES; - p_es->b_audio = 1; - p_es->i_cat = AUDIO_ES; - strcpy( p_es->psz_desc, DecodeLanguage( hton16( - vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) ); - strcat( p_es->psz_desc, " (mpeg)" ); - - break; - case 0x04: /* LPCM */ - - i_id = ( ( 0xa0 + audio_status.i_position ) << 8 ) | 0xbd; - p_es = input_AddES( p_input, NULL, i_id, 0 ); - p_es->i_stream_id = 0xbd; - p_es->i_type = LPCM_AUDIO_ES; - p_es->b_audio = 1; - p_es->i_cat = AUDIO_ES; - strcpy( p_es->psz_desc, DecodeLanguage( hton16( - vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) ); - strcat( p_es->psz_desc, " (lpcm)" ); - - break; - case 0x06: /* DTS */ - i_id = ( ( 0x88 + audio_status.i_position ) << 8 ) | 0xbd; - intf_ErrMsg( "dvd warning: DTS audio not handled yet" - "(0x%x)", i_id ); - break; - default: - i_id = 0; - intf_ErrMsg( "dvd warning: unknown audio type %.2x", - vts.manager_inf.p_audio_attr[i-1].i_coding_mode ); - } - } - } -#undef audio_status -#define spu_status \ - vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_spu_status[i-1] - - /* Sub Picture ES */ - - for( i = 1 ; i <= vts.manager_inf.i_spu_nb; i++ ) - { - IfoPrintSpu( p_dvd, i ); - - if( spu_status.i_available ) - { - i_spu_nb++; - - /* there are several streams for one spu */ - if( vts.manager_inf.video_attr.i_ratio ) - { - /* 16:9 */ - switch( vts.manager_inf.video_attr.i_perm_displ ) - { - case 1: - i_id = ( ( 0x20 + spu_status.i_position_pan ) << 8 ) - | 0xbd; - break; - case 2: - i_id = ( ( 0x20 + spu_status.i_position_letter ) << 8 ) - | 0xbd; - break; - default: - i_id = ( ( 0x20 + spu_status.i_position_wide ) << 8 ) - | 0xbd; - break; - } - } - else - { - /* 4:3 */ - i_id = ( ( 0x20 + spu_status.i_position_43 ) << 8 ) - | 0xbd; - } - p_es = input_AddES( p_input, NULL, i_id, 0 ); - p_es->i_stream_id = 0xbd; - p_es->i_type = DVD_SPU_ES; - p_es->i_cat = SPU_ES; - strcpy( p_es->psz_desc, DecodeLanguage( hton16( - vts.manager_inf.p_spu_attr[i-1].i_lang_code ) ) ); - } - } -#undef spu_status - + DVDReadAudio( p_input ); + + DVDReadSPU( p_input ); + /* FIXME: hack to check that the demuxer is ready, and set * the decoders */ if( p_input->p_demux_module ) @@ -953,9 +503,9 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) return -1; } + p_input->stream.p_selected_area->i_part = p_dvd->i_chapter; p_input->stream.p_selected_area->i_tell = LB2OFF( p_dvd->i_start ) - p_area->i_start; - p_input->stream.p_selected_area->i_part = p_dvd->i_chapter; intf_WarnMsg( 4, "dvd info: chapter %d start at: %lld", p_area->i_part, p_area->i_tell ); @@ -967,9 +517,6 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) } } -#define title \ - p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_title_id-1].title - /* warn interface that something has changed */ p_input->stream.b_seekable = 1; p_input->stream.b_changed = 1; @@ -977,6 +524,8 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) return 0; } +#define title \ + p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_title_id-1].title /***************************************************************************** * DVDRead: reads data packets. @@ -1029,7 +578,8 @@ static int DVDRead( input_thread_t * p_input, p_dvd->i_title_start + p_dvd->i_sector, DVDCSS_SEEK_MPEG ) ) < 0 ) { - intf_ErrMsg( "dvd error: %s", dvdcss_error( p_dvd->dvdhandle ) ); + intf_ErrMsg( "dvd error: %s", + dvdcss_error( p_dvd->dvdhandle ) ); return -1; } @@ -1062,9 +612,6 @@ static int DVDRead( input_thread_t * p_input, { i_block_once = i_blocks; } - /* - intf_WarnMsg( 2, "Sector: 0x%x Read: %d Chapter: %d", p_dvd->i_sector, i_block_once, p_dvd->i_chapter ); - */ /* Reads from DVD */ i_read_blocks = dvdcss_read( p_dvd->dvdhandle, p_buffer, @@ -1104,17 +651,10 @@ static int DVDRead( input_thread_t * p_input, intf_WarnMsg( 4, "dvd info: new title" ); p_dvd->i_title++; DVDSetArea( p_input, p_input->stream.pp_areas[p_dvd->i_title] ); - vlc_mutex_unlock( &p_input->stream.stream_lock ); - return LB2OFF( i_read_total ); } vlc_mutex_unlock( &p_input->stream.stream_lock ); -/* - if( i_read_blocks != i_block_once ) - { - return -1; - } -*/ + return LB2OFF( i_read_total ); } @@ -1235,238 +775,194 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off ) LB2OFF ( i_block ) - p_input->stream.p_selected_area->i_start; vlc_mutex_unlock( &p_input->stream.stream_lock ); - intf_WarnMsg( 7, "Program Cell: %d Cell: %d Chapter: %d", + intf_WarnMsg( 4, "Program Cell: %d Cell: %d Chapter: %d", p_dvd->i_prg_cell, p_dvd->i_cell, p_dvd->i_chapter ); return; } -#define cell p_dvd->p_ifo->vts.cell_inf - /***************************************************************************** - * DVDFindCell: adjust the title cell index with the program cell + * DVDParse: parse command line *****************************************************************************/ -static int DVDFindCell( thread_dvd_data_t * p_dvd ) +static char * DVDParse( input_thread_t * p_input ) { - int i_cell; - int i_index; - - i_cell = p_dvd->i_cell; - i_index = p_dvd->i_prg_cell; + thread_dvd_data_t * p_dvd; + struct stat stat_info; + char * psz_parser; + char * psz_device; + char * psz_raw; + char * psz_next; + boolean_t b_options = 0; + int i_title = 1; + int i_chapter = 1; + int i_angle = 1; + int i; + + p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); - if( i_cell >= cell.i_cell_nb ) + psz_parser = psz_device = strdup( p_input->psz_name ); + if( !psz_parser ) { - return -1; + return NULL; } - while( ( ( title.p_cell_pos[i_index].i_vob_id != - cell.p_cell_map[i_cell].i_vob_id ) || - ( title.p_cell_pos[i_index].i_cell_id != - cell.p_cell_map[i_cell].i_cell_id ) ) && - ( i_cell < cell.i_cell_nb - 1 ) ) + /* Parse input string : + * [device][@rawdevice][@[title][,[chapter][,angle]]] */ + while( *psz_parser && *psz_parser != '@' ) { - i_cell++; + psz_parser++; } -/* -intf_WarnMsg( 12, "FindCell: i_cell %d i_index %d found %d nb %d", - p_dvd->i_cell, - p_dvd->i_prg_cell, - i_cell, - cell.i_cell_nb ); -*/ - - p_dvd->i_cell = i_cell; - - return 0; -} - -#undef cell - -/***************************************************************************** - * DVDFindSector: find cell index in adress map from index in - * information table program map and give corresponding sectors. - *****************************************************************************/ -static int DVDFindSector( thread_dvd_data_t * p_dvd ) -{ - - if( p_dvd->i_sector > title.p_cell_play[p_dvd->i_prg_cell].i_end_sector ) + if( *psz_parser == '@' ) { - p_dvd->i_prg_cell++; - - if( DVDChooseAngle( p_dvd ) < 0 ) - { - return -1; - } + /* Maybe found raw device or option list */ + *psz_parser = '\0'; + psz_raw = ++psz_parser; } - - if( DVDFindCell( p_dvd ) < 0 ) + else { - intf_ErrMsg( "dvd error: can't find sector" ); - return -1; + psz_raw = NULL; } - - /* Find start and end sectors of new cell */ -#if 1 - p_dvd->i_sector = __MAX( - p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_start_sector, - title.p_cell_play[p_dvd->i_prg_cell].i_start_sector ); - p_dvd->i_end_sector = __MIN( - p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector, - title.p_cell_play[p_dvd->i_prg_cell].i_end_sector ); -#else - p_dvd->i_sector = title.p_cell_play[p_dvd->i_prg_cell].i_start_sector; - p_dvd->i_end_sector = title.p_cell_play[p_dvd->i_prg_cell].i_end_sector; -#endif - -/* - intf_WarnMsg( 12, "cell: %d sector1: 0x%x end1: 0x%x\n" - "index: %d sector2: 0x%x end2: 0x%x\n" - "category: 0x%x ilvu end: 0x%x vobu start 0x%x", - p_dvd->i_cell, - p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_start_sector, - p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector, - p_dvd->i_prg_cell, - title.p_cell_play[p_dvd->i_prg_cell].i_start_sector, - title.p_cell_play[p_dvd->i_prg_cell].i_end_sector, - title.p_cell_play[p_dvd->i_prg_cell].i_category, - title.p_cell_play[p_dvd->i_prg_cell].i_first_ilvu_vobu_esector, - title.p_cell_play[p_dvd->i_prg_cell].i_last_vobu_start_sector ); -*/ - - return 0; -} - -/***************************************************************************** - * DVDChapterSelect: find the cell corresponding to requested chapter - *****************************************************************************/ -static int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter ) -{ - - /* Find cell index in Program chain for current chapter */ - p_dvd->i_prg_cell = title.chapter_map.pi_start_cell[i_chapter-1] - 1; - p_dvd->i_cell = 0; - p_dvd->i_sector = 0; - DVDChooseAngle( p_dvd ); - - /* Search for cell_index in cell adress_table and initialize - * start sector */ - if( DVDFindSector( p_dvd ) < 0 ) + if( *psz_parser && !strtol( psz_parser, NULL, 10 ) ) { - intf_ErrMsg( "dvd error: can't select chapter" ); - return -1; + /* what we've found is either a raw device or a partial option + * list e.g. @,29 or both a device and a list ; search end of string */ + while( *psz_parser && *psz_parser != '@' ) + { + psz_parser++; + } + + if( *psz_parser == '@' ) + { + /* found end of raw device, and beginning of options */ + *psz_parser = '\0'; + ++psz_parser; + b_options = 1; + } + else + { + psz_parser = psz_raw + 1; + for( i=0 ; i<3 ; i++ ) + { + if( !*psz_parser ) + { + /* we have only a raw device */ + break; + } + if( strtol( psz_parser, NULL, 10 ) ) + { + /* we have only a partial list of options, no device */ + psz_parser = psz_raw; + psz_raw = NULL; + b_options = 1; + break; + } + psz_parser++; + } + } } - - /* start is : beginning of vts vobs + offset to vob x */ - p_dvd->i_start = p_dvd->i_title_start + p_dvd->i_sector; - - /* Position the fd pointer on the right address */ - if( ( p_dvd->i_start = dvdcss_seek( p_dvd->dvdhandle, - p_dvd->i_start, - DVDCSS_SEEK_MPEG ) ) < 0 ) + else { - intf_ErrMsg( "dvd error: %s", dvdcss_error( p_dvd->dvdhandle ) ); - return -1; + /* found beginning of options ; no raw device specified */ + psz_raw = NULL; + b_options = 1; } - p_dvd->i_chapter = i_chapter; - return 0; -} - -/***************************************************************************** - * DVDChooseAngle: select the cell corresponding to the selected angle - *****************************************************************************/ -static int DVDChooseAngle( thread_dvd_data_t * p_dvd ) -{ - /* basic handling of angles */ - switch( ( ( title.p_cell_play[p_dvd->i_prg_cell].i_category & 0xf000 ) - >> 12 ) ) + if( b_options ) { - /* we enter a muli-angle section */ - case 0x5: - p_dvd->i_prg_cell += p_dvd->i_angle - 1; - p_dvd->i_angle_cell = 0; - break; - /* we exit a multi-angle section */ - case 0x9: - case 0xd: - p_dvd->i_prg_cell += p_dvd->i_angle_nb - p_dvd->i_angle; - break; - } - - return 0; -} - -#undef title -/***************************************************************************** - * DVDLaunchDecoders - *****************************************************************************/ -static void DVDLaunchDecoders( input_thread_t * p_input ) -{ - thread_dvd_data_t * p_dvd; - int i_audio; - int i_spu; - - p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); + /* Found options */ + i_title = (int)strtol( psz_parser, &psz_next, 10 ); + if( *psz_next ) + { + psz_parser = psz_next + 1; + i_chapter = (int)strtol( psz_parser, &psz_next, 10 ); + if( *psz_next ) + { + i_angle = (int)strtol( psz_next + 1, NULL, 10 ); + } + } - /* Select Video stream (always 0) */ - if( p_main->b_video ) - { - input_SelectES( p_input, p_input->stream.pp_es[0] ); + p_dvd->i_title = i_title ? i_title : 1; + p_dvd->i_chapter = i_chapter ? i_chapter : 1; + p_dvd->i_angle = i_angle ? i_angle : 1; } - /* Select audio stream */ - if( p_main->b_audio ) + if( psz_raw ) { - /* For audio: first one if none or a not existing one specified */ - i_audio = config_GetIntVariable( INPUT_CHANNEL_VAR ); - if( i_audio < 0 /*|| i_audio > i_audio_nb*/ ) - { - config_PutIntVariable( INPUT_CHANNEL_VAR, 1 ); - i_audio = 1; - } - if( i_audio > 0 /*&& i_audio_nb > 0*/ ) + if( *psz_raw ) { - if( config_GetIntVariable( AOUT_SPDIF_VAR ) || - ( config_GetIntVariable( INPUT_AUDIO_VAR ) == - REQUESTED_AC3 ) ) + /* check the raw device */ + if( stat( psz_raw, &stat_info ) == -1 ) + { + intf_WarnMsg( 3, "dvd warning: cannot stat() raw" + " device `%s' (%s)", + psz_raw, strerror(errno)); + /* put back '@' */ + *(psz_raw - 1) = '@'; + psz_raw = NULL; + } + else { - int i_ac3 = i_audio; - while( ( p_input->stream.pp_es[i_ac3]->i_type != - AC3_AUDIO_ES ) && ( i_ac3 <= - p_dvd->p_ifo->vts.manager_inf.i_audio_nb ) ) + char * psz_env; + +#ifndef WIN32 + if( !S_ISCHR(stat_info.st_mode) ) { - i_ac3++; + intf_WarnMsg( 3, "dvd warning: raw device %s is" + " not a valid char device", psz_raw ); + /* put back '@' */ + *(psz_raw - 1) = '@'; + psz_raw = NULL; } - if( p_input->stream.pp_es[i_ac3]->i_type == AC3_AUDIO_ES ) + else +#endif { - input_SelectES( p_input, - p_input->stream.pp_es[i_ac3] ); + psz_env = malloc( strlen("DVDCSS_RAW_DEVICE=") + + strlen( psz_raw ) + 1 ); + sprintf( psz_env, "DVDCSS_RAW_DEVICE=%s", psz_raw ); + putenv( psz_env ); } } - else - { - input_SelectES( p_input, - p_input->stream.pp_es[i_audio] ); - } } - } - - /* Select subtitle */ - if( p_main->b_video ) - { - /* for spu, default is none */ - i_spu = config_GetIntVariable( INPUT_SUBTITLE_VAR ); - if( i_spu < 0 /*|| i_spu > i_spu_nb*/ ) + else { - config_PutIntVariable( INPUT_SUBTITLE_VAR, 0 ); - i_spu = 0; + psz_raw = NULL; } - if( i_spu > 0 /* && i_spu_nb > 0*/ ) + } + + if( !*psz_device ) + { + free( psz_device ); + + if( !p_input->psz_access ) { - i_spu += p_dvd->p_ifo->vts.manager_inf.i_audio_nb; - input_SelectES( p_input, p_input->stream.pp_es[i_spu] ); + /* no device and no access specified: we probably don't want DVD */ + return NULL; } + psz_device = config_GetPszVariable( INPUT_DVD_DEVICE_VAR ); } -} + + /* check block device */ + if( stat( psz_device, &stat_info ) == -1 ) + { + intf_ErrMsg( "input error: cannot stat() device `%s' (%s)", + psz_device, strerror(errno)); + return NULL; + } + +#ifndef WIN32 + if( !S_ISBLK(stat_info.st_mode) && !S_ISCHR(stat_info.st_mode) ) + { + intf_WarnMsg( 3, "input: DVD plugin discarded" + " (not a valid block device)" ); + return NULL; + } +#endif + + intf_WarnMsg( 2, "input: dvd=%s raw=%s title=%d chapter=%d angle=%d", + psz_device, psz_raw, p_dvd->i_title, + p_dvd->i_chapter, p_dvd->i_angle ); + + return psz_device; +} diff --git a/plugins/dvd/dvd_demux.c b/plugins/dvd/dvd_demux.c new file mode 100644 index 0000000000..389c54cd88 --- /dev/null +++ b/plugins/dvd/dvd_demux.c @@ -0,0 +1,138 @@ +/* dvd_demux.c: DVD demux functions. + ***************************************************************************** + * Copyright (C) 1998-2001 VideoLAN + * $Id: dvd_demux.c,v 1.1 2002/03/06 01:20:56 stef Exp $ + * + * Author: Stéphane Borel <stef@via.ecp.fr> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <videolan/vlc.h> + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif + +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <errno.h> + +#ifdef STRNCASECMP_IN_STRINGS_H +# include <strings.h> +#endif + +#include "stream_control.h" +#include "input_ext-intf.h" +#include "input_ext-dec.h" +#include "input_ext-plugins.h" + +#include "debug.h" + +/* how many packets DVDDemux will read in each loop */ +#define DVD_READ_ONCE 64 + +/***************************************************************************** + * Local prototypes + *****************************************************************************/ + +/* called from outside */ +static int DVDRewind ( struct input_thread_s * ); +static int DVDDemux ( struct input_thread_s * ); +static int DVDInit ( struct input_thread_s * ); +static void DVDEnd ( struct input_thread_s * ); + +void DVDLaunchDecoders( input_thread_t * ); + +/***************************************************************************** + * Functions exported as capabilities. They are declared as static so that + * we don't pollute the namespace too much. + *****************************************************************************/ +void _M( demux_getfunctions)( function_list_t * p_function_list ) +{ +#define demux p_function_list->functions.demux + demux.pf_init = DVDInit; + demux.pf_end = DVDEnd; + demux.pf_demux = DVDDemux; + demux.pf_rewind = DVDRewind; +#undef demux +} + +/* + * Data demux functions + */ + +/***************************************************************************** + * DVDInit: initializes DVD structures + *****************************************************************************/ +static int DVDInit( input_thread_t * p_input ) +{ + + if( strncmp( p_input->p_access_module->psz_name, "dvd", 3 ) ) + { + return -1; + } + + vlc_mutex_lock( &p_input->stream.stream_lock ); + + DVDLaunchDecoders( p_input ); + + vlc_mutex_unlock( &p_input->stream.stream_lock ); + + return 0; +} + +/***************************************************************************** + * DVDEnd: frees unused data + *****************************************************************************/ +static void DVDEnd( input_thread_t * p_input ) +{ +} + +/***************************************************************************** + * DVDDemux + *****************************************************************************/ +static int DVDDemux( input_thread_t * p_input ) +{ + int i; + data_packet_t * p_data; + + /* Read headers to compute payload length */ + for( i = 0 ; i < DVD_READ_ONCE ; i++ ) + { + input_ReadPS( p_input, &p_data ); + + input_DemuxPS( p_input, p_data ); + } + + return i; +} + +/***************************************************************************** + * DVDRewind : reads a stream backward + *****************************************************************************/ +static int DVDRewind( input_thread_t * p_input ) +{ + return( -1 ); +} diff --git a/plugins/dvd/dvd_es.c b/plugins/dvd/dvd_es.c new file mode 100644 index 0000000000..44d6743cab --- /dev/null +++ b/plugins/dvd/dvd_es.c @@ -0,0 +1,305 @@ +/* dvd_es.c: functions to find and select ES + ***************************************************************************** + * Copyright (C) 1998-2001 VideoLAN + * $Id: dvd_es.c,v 1.1 2002/03/06 01:20:56 stef Exp $ + * + * Author: Stéphane Borel <stef@via.ecp.fr> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <videolan/vlc.h> + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif + +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <errno.h> + +#ifdef STRNCASECMP_IN_STRINGS_H +# include <strings.h> +#endif + +#ifdef GOD_DAMN_DMCA +# include "dummy_dvdcss.h" +#else +# include <videolan/dvdcss.h> +#endif + +#include "stream_control.h" +#include "input_ext-intf.h" +#include "input_ext-dec.h" +#include "input_ext-plugins.h" + +#include "dvd.h" +#include "dvd_ifo.h" +#include "dvd_summary.h" +#include "iso_lang.h" + +#include "debug.h" + +/***************************************************************************** + * Local prototypes + *****************************************************************************/ + +void DVDLaunchDecoders( input_thread_t * p_input ); + +#define vmg p_dvd->p_ifo->vmg +#define vts p_dvd->p_ifo->vts + +/***************************************************************************** + * DVDReadVideo + *****************************************************************************/ +void DVDReadVideo( input_thread_t * p_input ) +{ + thread_dvd_data_t * p_dvd; + es_descriptor_t * p_es; + + p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); + + /* ES 0 -> video MPEG2 */ + IfoPrintVideo( p_dvd ); + + p_es = input_AddES( p_input, NULL, 0xe0, 0 ); + p_es->i_stream_id = 0xe0; + p_es->i_type = MPEG2_VIDEO_ES; + p_es->i_cat = VIDEO_ES; +} + +/***************************************************************************** + * DVDReadAudio + *****************************************************************************/ +#define audio_status \ + vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_audio_status[i-1] + +void DVDReadAudio( input_thread_t * p_input ) +{ + thread_dvd_data_t * p_dvd; + es_descriptor_t * p_es; + int i_id; + int i; + + p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); + + /* Audio ES, in the order they appear in .ifo */ + for( i = 1 ; i <= vts.manager_inf.i_audio_nb ; i++ ) + { + IfoPrintAudio( p_dvd, i ); + + /* audio channel is active if first byte is 0x80 */ + if( audio_status.i_available ) + { + p_dvd->i_audio_nb++; + + switch( vts.manager_inf.p_audio_attr[i-1].i_coding_mode ) + { + case 0x00: /* AC3 */ + i_id = ( ( 0x80 + audio_status.i_position ) << 8 ) | 0xbd; + p_es = input_AddES( p_input, NULL, i_id, 0 ); + p_es->i_stream_id = 0xbd; + p_es->i_type = AC3_AUDIO_ES; + p_es->b_audio = 1; + p_es->i_cat = AUDIO_ES; + strcpy( p_es->psz_desc, DecodeLanguage( hton16( + vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) ); + strcat( p_es->psz_desc, " (ac3)" ); + + break; + case 0x02: + case 0x03: /* MPEG audio */ + i_id = 0xc0 + audio_status.i_position; + p_es = input_AddES( p_input, NULL, i_id, 0 ); + p_es->i_stream_id = i_id; + p_es->i_type = MPEG2_AUDIO_ES; + p_es->b_audio = 1; + p_es->i_cat = AUDIO_ES; + strcpy( p_es->psz_desc, DecodeLanguage( hton16( + vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) ); + strcat( p_es->psz_desc, " (mpeg)" ); + + break; + case 0x04: /* LPCM */ + + i_id = ( ( 0xa0 + audio_status.i_position ) << 8 ) | 0xbd; + p_es = input_AddES( p_input, NULL, i_id, 0 ); + p_es->i_stream_id = 0xbd; + p_es->i_type = LPCM_AUDIO_ES; + p_es->b_audio = 1; + p_es->i_cat = AUDIO_ES; + strcpy( p_es->psz_desc, DecodeLanguage( hton16( + vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) ); + strcat( p_es->psz_desc, " (lpcm)" ); + + break; + case 0x06: /* DTS */ + i_id = ( ( 0x88 + audio_status.i_position ) << 8 ) | 0xbd; + intf_ErrMsg( "dvd warning: DTS audio not handled yet" + "(0x%x)", i_id ); + break; + default: + i_id = 0; + intf_ErrMsg( "dvd warning: unknown audio type %.2x", + vts.manager_inf.p_audio_attr[i-1].i_coding_mode ); + } + } + } +} +#undef audio_status + +/***************************************************************************** + * DVDReadSPU: Read subpictures ES + *****************************************************************************/ +#define spu_status \ + vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_spu_status[i-1] + +void DVDReadSPU( input_thread_t * p_input ) +{ + thread_dvd_data_t * p_dvd; + es_descriptor_t * p_es; + int i_id; + int i; + + p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); + + for( i = 1 ; i <= vts.manager_inf.i_spu_nb; i++ ) + { + IfoPrintSpu( p_dvd, i ); + + if( spu_status.i_available ) + { + p_dvd->i_spu_nb++; + + /* there are several streams for one spu */ + if( vts.manager_inf.video_attr.i_ratio ) + { + /* 16:9 */ + switch( vts.manager_inf.video_attr.i_perm_displ ) + { + case 1: + i_id = ( ( 0x20 + spu_status.i_position_pan ) << 8 ) + | 0xbd; + break; + case 2: + i_id = ( ( 0x20 + spu_status.i_position_letter ) << 8 ) + | 0xbd; + break; + default: + i_id = ( ( 0x20 + spu_status.i_position_wide ) << 8 ) + | 0xbd; + break; + } + } + else + { + /* 4:3 */ + i_id = ( ( 0x20 + spu_status.i_position_43 ) << 8 ) + | 0xbd; + } + p_es = input_AddES( p_input, NULL, i_id, 0 ); + p_es->i_stream_id = 0xbd; + p_es->i_type = DVD_SPU_ES; + p_es->i_cat = SPU_ES; + strcpy( p_es->psz_desc, DecodeLanguage( hton16( + vts.manager_inf.p_spu_attr[i-1].i_lang_code ) ) ); + } + } +} +#undef spu_status + +#undef vts +#undef vmg + +/***************************************************************************** + * DVDLaunchDecoders + *****************************************************************************/ +void DVDLaunchDecoders( input_thread_t * p_input ) +{ + thread_dvd_data_t * p_dvd; + int i_audio; + int i_spu; + + p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); + + /* Select Video stream (always 0) */ + if( p_main->b_video ) + { + input_SelectES( p_input, p_input->stream.pp_es[0] ); + } + + /* Select audio stream */ + if( p_main->b_audio ) + { + /* For audio: first one if none or a not existing one specified */ + i_audio = config_GetIntVariable( INPUT_CHANNEL_VAR ); + if( i_audio < 0 || i_audio > p_dvd->i_audio_nb ) + { + config_PutIntVariable( INPUT_CHANNEL_VAR, 1 ); + i_audio = 1; + } + if( i_audio > 0 && p_dvd->i_audio_nb > 0 ) + { + if( config_GetIntVariable( AOUT_SPDIF_VAR ) || + ( config_GetIntVariable( INPUT_AUDIO_VAR ) == + REQUESTED_AC3 ) ) + { + int i_ac3 = i_audio; + while( ( p_input->stream.pp_es[i_ac3]->i_type != + AC3_AUDIO_ES ) && ( i_ac3 <= + p_dvd->p_ifo->vts.manager_inf.i_audio_nb ) ) + { + i_ac3++; + } + if( p_input->stream.pp_es[i_ac3]->i_type == AC3_AUDIO_ES ) + { + input_SelectES( p_input, + p_input->stream.pp_es[i_ac3] ); + } + } + else + { + input_SelectES( p_input, + p_input->stream.pp_es[i_audio] ); + } + } + } + + /* Select subtitle */ + if( p_main->b_video ) + { + /* for spu, default is none */ + i_spu = config_GetIntVariable( INPUT_SUBTITLE_VAR ); + if( i_spu < 0 || i_spu > p_dvd->i_spu_nb ) + { + config_PutIntVariable( INPUT_SUBTITLE_VAR, 0 ); + i_spu = 0; + } + if( i_spu > 0 && p_dvd->i_spu_nb > 0 ) + { + i_spu += p_dvd->p_ifo->vts.manager_inf.i_audio_nb; + input_SelectES( p_input, p_input->stream.pp_es[i_spu] ); + } + } +} diff --git a/plugins/dvd/dvd_es.h b/plugins/dvd/dvd_es.h new file mode 100644 index 0000000000..5bb54973c9 --- /dev/null +++ b/plugins/dvd/dvd_es.h @@ -0,0 +1,27 @@ +/* dvd_es.h: functions to find and select ES + ***************************************************************************** + * Copyright (C) 1998-2001 VideoLAN + * $Id: dvd_es.h,v 1.1 2002/03/06 01:20:56 stef Exp $ + * + * Author: Stéphane Borel <stef@via.ecp.fr> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +void DVDLaunchDecoders ( input_thread_t * ); +void DVDReadVideo ( input_thread_t * ); +void DVDReadAudio ( input_thread_t * ); +void DVDReadSPU ( input_thread_t * ); + diff --git a/plugins/dvd/dvd_ifo.c b/plugins/dvd/dvd_ifo.c index ed4498f665..1258d38eea 100644 --- a/plugins/dvd/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.43 2001/12/30 07:09:55 sam Exp $ + * $Id: dvd_ifo.c,v 1.44 2002/03/06 01:20:56 stef Exp $ * * Authors: Stéphane Borel <stef@via.ecp.fr> * German Tischler <tanis@gaspode.franken.de> @@ -50,7 +50,7 @@ # include <videolan/dvdcss.h> #endif -#include "input_dvd.h" +#include "dvd.h" #include "dvd_ifo.h" #include "dvd_udf.h" diff --git a/plugins/dvd/dvd_seek.c b/plugins/dvd/dvd_seek.c new file mode 100644 index 0000000000..9c6b3f639b --- /dev/null +++ b/plugins/dvd/dvd_seek.c @@ -0,0 +1,222 @@ +/* dvd_seek.c: functions to navigate through DVD. + ***************************************************************************** + * Copyright (C) 1998-2001 VideoLAN + * $Id: dvd_seek.c,v 1.1 2002/03/06 01:20:56 stef Exp $ + * + * Author: Stéphane Borel <stef@via.ecp.fr> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <videolan/vlc.h> + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif + +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <errno.h> + +#ifdef STRNCASECMP_IN_STRINGS_H +# include <strings.h> +#endif + +#ifdef GOD_DAMN_DMCA +# include "dummy_dvdcss.h" +#else +# include <videolan/dvdcss.h> +#endif + +#include "stream_control.h" +#include "input_ext-intf.h" +#include "input_ext-dec.h" +#include "input_ext-plugins.h" + +#include "dvd.h" +#include "dvd_seek.h" +#include "dvd_ifo.h" + +#include "debug.h" + +#define title \ + p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_title_id-1].title +#define cell p_dvd->p_ifo->vts.cell_inf + +/***************************************************************************** + * DVDFindCell: adjust the title cell index with the program cell + *****************************************************************************/ +int DVDFindCell( thread_dvd_data_t * p_dvd ) +{ + int i_cell; + int i_index; + + i_cell = p_dvd->i_cell; + i_index = p_dvd->i_prg_cell; + + if( i_cell >= cell.i_cell_nb ) + { + return -1; + } + + while( ( ( title.p_cell_pos[i_index].i_vob_id != + cell.p_cell_map[i_cell].i_vob_id ) || + ( title.p_cell_pos[i_index].i_cell_id != + cell.p_cell_map[i_cell].i_cell_id ) ) && + ( i_cell < cell.i_cell_nb - 1 ) ) + { + i_cell++; + } + +/* +intf_WarnMsg( 12, "FindCell: i_cell %d i_index %d found %d nb %d", + p_dvd->i_cell, + p_dvd->i_prg_cell, + i_cell, + cell.i_cell_nb ); +*/ + + p_dvd->i_cell = i_cell; + + return 0; +} + +#undef cell + +/***************************************************************************** + * DVDFindSector: find cell index in adress map from index in + * information table program map and give corresponding sectors. + *****************************************************************************/ +int DVDFindSector( thread_dvd_data_t * p_dvd ) +{ + + if( p_dvd->i_sector > title.p_cell_play[p_dvd->i_prg_cell].i_end_sector ) + { + p_dvd->i_prg_cell++; + + if( DVDChooseAngle( p_dvd ) < 0 ) + { + return -1; + } + } + + if( DVDFindCell( p_dvd ) < 0 ) + { + intf_ErrMsg( "dvd error: can't find sector" ); + return -1; + } + + /* Find start and end sectors of new cell */ +#if 1 + p_dvd->i_sector = __MAX( + p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_start_sector, + title.p_cell_play[p_dvd->i_prg_cell].i_start_sector ); + p_dvd->i_end_sector = __MIN( + p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector, + title.p_cell_play[p_dvd->i_prg_cell].i_end_sector ); +#else + p_dvd->i_sector = title.p_cell_play[p_dvd->i_prg_cell].i_start_sector; + p_dvd->i_end_sector = title.p_cell_play[p_dvd->i_prg_cell].i_end_sector; +#endif + +/* + intf_WarnMsg( 12, "cell: %d sector1: 0x%x end1: 0x%x\n" + "index: %d sector2: 0x%x end2: 0x%x\n" + "category: 0x%x ilvu end: 0x%x vobu start 0x%x", + p_dvd->i_cell, + p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_start_sector, + p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector, + p_dvd->i_prg_cell, + title.p_cell_play[p_dvd->i_prg_cell].i_start_sector, + title.p_cell_play[p_dvd->i_prg_cell].i_end_sector, + title.p_cell_play[p_dvd->i_prg_cell].i_category, + title.p_cell_play[p_dvd->i_prg_cell].i_first_ilvu_vobu_esector, + title.p_cell_play[p_dvd->i_prg_cell].i_last_vobu_start_sector ); +*/ + + return 0; +} + +/***************************************************************************** + * DVDChapterSelect: find the cell corresponding to requested chapter + *****************************************************************************/ +int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter ) +{ + + /* Find cell index in Program chain for current chapter */ + p_dvd->i_prg_cell = title.chapter_map.pi_start_cell[i_chapter-1] - 1; + p_dvd->i_cell = 0; + p_dvd->i_sector = 0; + + DVDChooseAngle( p_dvd ); + + /* Search for cell_index in cell adress_table and initialize + * start sector */ + if( DVDFindSector( p_dvd ) < 0 ) + { + intf_ErrMsg( "dvd error: can't select chapter" ); + return -1; + } + + /* start is : beginning of vts vobs + offset to vob x */ + p_dvd->i_start = p_dvd->i_title_start + p_dvd->i_sector; + + /* Position the fd pointer on the right address */ + if( ( p_dvd->i_start = dvdcss_seek( p_dvd->dvdhandle, + p_dvd->i_start, + DVDCSS_SEEK_MPEG ) ) < 0 ) + { + intf_ErrMsg( "dvd error: %s", dvdcss_error( p_dvd->dvdhandle ) ); + return -1; + } + + p_dvd->i_chapter = i_chapter; + return 0; +} + +/***************************************************************************** + * DVDChooseAngle: select the cell corresponding to the selected angle + *****************************************************************************/ +int DVDChooseAngle( thread_dvd_data_t * p_dvd ) +{ + /* basic handling of angles */ + switch( ( ( title.p_cell_play[p_dvd->i_prg_cell].i_category & 0xf000 ) + >> 12 ) ) + { + /* we enter a muli-angle section */ + case 0x5: + p_dvd->i_prg_cell += p_dvd->i_angle - 1; + p_dvd->i_angle_cell = 0; + break; + /* we exit a multi-angle section */ + case 0x9: + case 0xd: + p_dvd->i_prg_cell += p_dvd->i_angle_nb - p_dvd->i_angle; + break; + } + + return 0; +} + +#undef title diff --git a/plugins/dvd/dvd_seek.h b/plugins/dvd/dvd_seek.h new file mode 100644 index 0000000000..feba1b48b3 --- /dev/null +++ b/plugins/dvd/dvd_seek.h @@ -0,0 +1,26 @@ +/* dvd_seek.h: DVD access plugin. + ***************************************************************************** + * Copyright (C) 1998-2001 VideoLAN + * $Id: dvd_seek.h,v 1.1 2002/03/06 01:20:56 stef Exp $ + * + * Author: Stéphane Borel <stef@via.ecp.fr> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +int DVDChooseAngle( thread_dvd_data_t * ); +int DVDFindCell( thread_dvd_data_t * ); +int DVDFindSector( thread_dvd_data_t * ); +int DVDChapterSelect( thread_dvd_data_t *, int ); diff --git a/plugins/dvd/dvd_summary.c b/plugins/dvd/dvd_summary.c index 125d428131..79f5ff43d8 100644 --- a/plugins/dvd/dvd_summary.c +++ b/plugins/dvd/dvd_summary.c @@ -3,7 +3,7 @@ * found in .ifo. ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: dvd_summary.c,v 1.13 2002/03/05 17:46:33 stef Exp $ + * $Id: dvd_summary.c,v 1.14 2002/03/06 01:20:56 stef Exp $ * * Author: Stéphane Borel <stef@via.ecp.fr> * @@ -53,7 +53,7 @@ # include <videolan/dvdcss.h> #endif -#include "input_dvd.h" +#include "dvd.h" #include "dvd_ifo.h" #include "iso_lang.h" diff --git a/plugins/dvd/dvd_udf.c b/plugins/dvd/dvd_udf.c index 713da7d3fa..4ee667e385 100644 --- a/plugins/dvd/dvd_udf.c +++ b/plugins/dvd/dvd_udf.c @@ -5,7 +5,7 @@ * contains the basic udf handling functions ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: dvd_udf.c,v 1.18 2001/12/30 07:09:55 sam Exp $ + * $Id: dvd_udf.c,v 1.19 2002/03/06 01:20:56 stef Exp $ * * Author: Stéphane Borel <stef@via.ecp.fr> * @@ -53,7 +53,7 @@ # include <videolan/dvdcss.h> #endif -#include "input_dvd.h" +#include "dvd.h" #include "dvd_ifo.h" #define UDFADshort 1 diff --git a/plugins/dvdread/input_dvdread.c b/plugins/dvdread/input_dvdread.c index 13b1331180..3290d4f944 100644 --- a/plugins/dvdread/input_dvdread.c +++ b/plugins/dvdread/input_dvdread.c @@ -6,7 +6,7 @@ * It depends on: libdvdread for ifo files and block reading. ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: input_dvdread.c,v 1.29 2002/03/05 17:46:33 stef Exp $ + * $Id: input_dvdread.c,v 1.30 2002/03/06 01:20:56 stef Exp $ * * Author: Stéphane Borel <stef@via.ecp.fr> * @@ -609,14 +609,14 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area ) /* We don't use input_EndStream here since * we keep area structures */ - for( i = 0 ; i < p_input->stream.i_es_number ; i++ ) + while( p_input->stream.i_es_number ) { - input_DelES( p_input, p_input->stream.pp_es[i] ); + input_DelES( p_input, p_input->stream.pp_es[0] ); } - for( i = 0 ; i < p_input->stream.i_pgrm_number ; i++ ) + while( p_input->stream.i_pgrm_number ) { - input_DelProgram( p_input, p_input->stream.pp_programs[i] ); + input_DelProgram( p_input, p_input->stream.pp_programs[0] ); } if( p_input->stream.pp_selected_es ) diff --git a/plugins/gtk/gtk_display.c b/plugins/gtk/gtk_display.c index 1f9bf79326..96fdc442a6 100644 --- a/plugins/gtk/gtk_display.c +++ b/plugins/gtk/gtk_display.c @@ -2,7 +2,7 @@ * gtk_display.c: Gtk+ tools for main interface ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: gtk_display.c,v 1.17 2002/03/05 17:46:33 stef Exp $ + * $Id: gtk_display.c,v 1.18 2002/03/06 01:20:56 stef Exp $ * * Authors: Samuel Hocevar <sam@zoy.org> * Stéphane Borel <stef@via.ecp.fr> @@ -216,13 +216,11 @@ gint GtkModeManage( intf_thread_t * p_intf ) gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_title"), FALSE ); gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_chapter"), FALSE ); - gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_angle"), FALSE ); gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_audio"), FALSE ); gtk_widget_set_sensitive( GETWIDGET(p_window,"menubar_subpictures"), FALSE ); gtk_widget_set_sensitive( GETWIDGET(p_popup,"popup_navigation"), FALSE ); - gtk_widget_set_sensitive( GETWIDGET(p_popup,"popup_angle"), FALSE ); gtk_widget_set_sensitive( GETWIDGET(p_popup,"popup_audio"), FALSE ); gtk_widget_set_sensitive( GETWIDGET(p_popup,"popup_subpictures"), FALSE ); diff --git a/plugins/gtk/gtk_menu.c b/plugins/gtk/gtk_menu.c index 2e7d7580c2..f435539829 100644 --- a/plugins/gtk/gtk_menu.c +++ b/plugins/gtk/gtk_menu.c @@ -2,7 +2,7 @@ * gtk_menu.c : functions to handle menu items. ***************************************************************************** * Copyright (C) 2000, 2001 VideoLAN - * $Id: gtk_menu.c,v 1.21 2002/03/05 17:46:33 stef Exp $ + * $Id: gtk_menu.c,v 1.22 2002/03/06 01:20:56 stef Exp $ * * Authors: Samuel Hocevar <sam@zoy.org> * Stéphane Borel <stef@via.ecp.fr> @@ -70,8 +70,6 @@ static gint GtkTitleMenu( gpointer, GtkWidget *, static gint GtkRadioMenu( intf_thread_t *, GtkWidget *, GSList *, char *, int, int, void( *pf_toggle )( GtkCheckMenuItem *, gpointer ) ); -void GtkMenubarAngleToggle( GtkCheckMenuItem *, gpointer ); -void GtkPopupAngleToggle( GtkCheckMenuItem *, gpointer ); gint GtkSetupMenus( intf_thread_t * p_intf ); @@ -279,49 +277,6 @@ void GtkMenubarChapterToggle( GtkCheckMenuItem * menuitem, gpointer user_data ) } -/* - * Angle - */ - -#if 0 -#define GTKANGLETOGGLE( intf, window, menu, callback ) \ - intf_thread_t * p_intf; \ - GtkWidget * p_menu; \ - input_area_t * p_area; \ - \ - p_intf = GetIntf( GTK_WIDGET(menuitem), (intf) ); \ - \ - if( menuitem->active && !p_intf->p_sys->b_angle_update ) \ - { \ - p_menu = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( \ - p_intf->p_sys->window ), (menu) ) ); \ - p_area = p_input_bank->pp_input[0]->stream.p_selected_area; \ - p_area->i_angle = (gint)((long)user_data); \ - \ - input_ChangeArea( p_input_bank->pp_input[0], (input_area_t*)p_area ); \ - \ - p_intf->p_sys->b_angle_update = 1; \ - vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock ); \ - GtkRadioMenu( p_intf, p_menu, NULL, "Angle", \ - p_area->i_angle_nb, p_area->i_angle, (callback) ); \ - vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock ); \ - p_intf->p_sys->b_angle_update = 0; \ - } - -void GtkMenubarAngleToggle( GtkCheckMenuItem * menuitem, gpointer user_data ) -{ - GTKANGLETOGGLE( "intf_window", p_popup, "popup_angle", - GtkPopupAngleToggle ); -} - -void GtkPopupAngleToggle( GtkCheckMenuItem * menuitem, gpointer user_data ) -{ - GTKANGLETOGGLE( "intf_popup", p_window, "menubar_angle", - GtkMenubarAngleToggle ); -} - -#undef GTKANGLETOGGLE -#endif /**************************************************************************** * Functions to generate menus ****************************************************************************/ @@ -539,10 +494,10 @@ static gint GtkProgramMenu( gpointer p_data, * function, the interface lock has to be taken *****************************************************************************/ static gint GtkLanguageMenus( gpointer p_data, - GtkWidget * p_root, - es_descriptor_t * p_es, - gint i_cat, - void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) ) + GtkWidget * p_root, + es_descriptor_t * p_es, + gint i_cat, + void(*pf_toggle )( GtkCheckMenuItem *, gpointer ) ) { intf_thread_t * p_intf; GtkWidget * p_menu; diff --git a/plugins/vcd/vcd.c b/plugins/vcd/vcd.c index 414072d120..efdc73e1dc 100644 --- a/plugins/vcd/vcd.c +++ b/plugins/vcd/vcd.c @@ -2,7 +2,7 @@ * vcd.c : VCD input module for vlc ***************************************************************************** * Copyright (C) 2000 VideoLAN - * $Id: vcd.c,v 1.6 2002/03/05 23:29:36 jobi Exp $ + * $Id: vcd.c,v 1.7 2002/03/06 01:20:56 stef Exp $ * * Authors: Samuel Hocevar <sam@zoy.org> * @@ -43,8 +43,8 @@ MODULE_CONFIG_STOP MODULE_INIT_START SET_DESCRIPTION( "VCD input module" ) - ADD_CAPABILITY( DEMUX, 205 ) - ADD_CAPABILITY( ACCESS, 105 ) + ADD_CAPABILITY( DEMUX, 180 ) + ADD_CAPABILITY( ACCESS, 80 ) ADD_SHORTCUT( "vcd" ) MODULE_INIT_STOP diff --git a/src/input/input.c b/src/input/input.c index 888677c713..168de84cc9 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -4,7 +4,7 @@ * decoders. ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: input.c,v 1.186 2002/03/05 06:48:33 gbazin Exp $ + * $Id: input.c,v 1.187 2002/03/06 01:20:56 stef Exp $ * * Authors: Christophe Massiot <massiot@via.ecp.fr> * Alexis Guillard <alexis.guillard@bt.com> @@ -188,7 +188,7 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status ) p_input->stream.control.i_rate = DEFAULT_RATE; p_input->stream.control.b_mute = 0; p_input->stream.control.b_grayscale = config_GetIntVariable( - VOUT_GRAYSCALE_VAR ); + VOUT_GRAYSCALE_VAR ); p_input->stream.control.i_smp = config_GetIntVariable( VDEC_SMP_VAR ); intf_WarnMsg( 1, "input: playlist item `%s'", p_input->psz_source ); @@ -444,7 +444,7 @@ static int InitThread( input_thread_t * p_input ) { intf_WarnMsg( 2, "Drive letter %c: specified in source string", p_input->psz_source ) ; - psz_parser = ""; + psz_parser = ""; } #endif @@ -462,7 +462,7 @@ static int InitThread( input_thread_t * p_input ) /* Come back to parse the access and demux plug-ins */ psz_parser = p_input->psz_source; - if( !*psz_parser ) + if( !*psz_parser ) { /* No access */ p_input->psz_access = NULL; -- 2.39.2