*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
.B *.mpg, *.vob
Plain MPEG-1/2 files
.TP
-.B dvd:<device>[@<raw device>]
+.B dvd:[<device>][@<raw device>][@[<title>][,[<chapter>][,<angle>]]]
DVD device (for instance dvd:/dev/dvd). The raw device is optional and
must have been prepared beforehands.
.TP
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
-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
/*****************************************************************************
- * 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>
*
{
dvdcss_handle dvdhandle; /* libdvdcss handle */
+ int i_audio_nb;
+ int i_spu_nb;
+
/* Navigation information */
int i_title;
int i_title_id;
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;
-/* 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.
* -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>
*
# include <strings.h>
#endif
-#if defined( WIN32 )
-# include <io.h> /* read() */
-#endif
-
#ifdef GOD_DAMN_DMCA
# include "dummy_dvdcss.h"
#else
#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
*****************************************************************************/
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
#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
*/
*****************************************************************************/
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 )
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 )
{
/* 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
}
#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 ) )
{
vlc_mutex_unlock( &p_input->stream.stream_lock );
return 0;
-
}
/*****************************************************************************
}
/*****************************************************************************
- * 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 )
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;
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);
{
/* 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 */
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
*/
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
{
/* 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 )
}
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];
/* 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 )
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 );
}
}
-#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;
return 0;
}
+#define title \
+ p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_title_id-1].title
/*****************************************************************************
* DVDRead: reads data packets.
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;
}
{
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,
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 );
}
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;
+}
--- /dev/null
+/* 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 );
+}
--- /dev/null
+/* 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] );
+ }
+ }
+}
--- /dev/null
+/* 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 * );
+
* 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>
# include <videolan/dvdcss.h>
#endif
-#include "input_dvd.h"
+#include "dvd.h"
#include "dvd_ifo.h"
#include "dvd_udf.h"
--- /dev/null
+/* 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
--- /dev/null
+/* 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 );
* 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>
*
# include <videolan/dvdcss.h>
#endif
-#include "input_dvd.h"
+#include "dvd.h"
#include "dvd_ifo.h"
#include "iso_lang.h"
* 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>
*
# include <videolan/dvdcss.h>
#endif
-#include "input_dvd.h"
+#include "dvd.h"
#include "dvd_ifo.h"
#define UDFADshort 1
* 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>
*
/* 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 )
* 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>
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 );
* 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>
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 );
}
-/*
- * 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
****************************************************************************/
* 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;
* 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>
*
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
* 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>
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 );
{
intf_WarnMsg( 2, "Drive letter %c: specified in source string",
p_input->psz_source ) ;
- psz_parser = "";
+ psz_parser = "";
}
#endif
/* 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;