* It depends on: libdvdread for ifo files and block reading.
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: input_dvdread.c,v 1.23 2002/03/01 14:17:22 stef Exp $
+ * $Id: input_dvdread.c,v 1.34 2002/03/18 19:14:52 sam Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
#include <fcntl.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
*****************************************************************************/
static int DvdReadInit( input_thread_t * p_input )
{
- if( strncmp( p_input->p_access_module->psz_name, "dvdread", 7 ) )
+ if( p_input->stream.i_method != INPUT_METHOD_DVD )
{
return -1;
}
*****************************************************************************/
static int DvdReadOpen( struct input_thread_s *p_input )
{
+ char * psz_orig;
+ char * psz_parser;
+ char * psz_source;
+ char * psz_next;
struct stat stat_info;
thread_dvd_data_t * p_dvd;
dvd_reader_t * p_dvdread;
input_area_t * p_area;
- int i_title;
- int i_chapter;
+ int i_title = 1;
+ int i_chapter = 1;
+ int i_angle = 1;
int i;
- if( stat( p_input->psz_name, &stat_info ) == -1 )
+ psz_orig = psz_parser = psz_source = strdup( p_input->psz_name );
+ if( !psz_orig )
{
- intf_ErrMsg( "input error: cannot stat() device `%s' (%s)",
- p_input->psz_name, strerror(errno));
+ return( -1 );
+ }
+
+ while( *psz_parser && *psz_parser != '@' )
+ {
+ psz_parser++;
+ }
+
+ if( *psz_parser == '@' )
+ {
+ /* Found options */
+ *psz_parser = '\0';
+ ++psz_parser;
+
+ 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_source )
+ {
+ if( !p_input->psz_access )
+ {
+ free( psz_orig );
+ return -1;
+ }
+ psz_source = config_GetPszVariable( "dvd_device" );
+ }
+
+ if( stat( psz_source, &stat_info ) == -1 )
+ {
+ intf_ErrMsg( "input error: cannot stat() source `%s' (%s)",
+ psz_source, strerror(errno));
return( -1 );
}
if( !S_ISBLK(stat_info.st_mode) &&
return -1;
}
- p_dvdread = DVDOpen( p_input->psz_name );
+ intf_WarnMsg( 2, "input: dvdroot=%s title=%d chapter=%d angle=%d",
+ psz_source, i_title, i_chapter, i_angle );
+
+
+ p_dvdread = DVDOpen( psz_source );
+
+ /* free allocated strings */
+ if( psz_source != psz_orig )
+ free( psz_source );
+ free( psz_orig );
+
if( ! p_dvdread )
{
intf_ErrMsg( "dvdread error: libdvdcss can't open source" );
p_dvd->p_title = NULL;
p_dvd->p_vts_file = NULL;
+
p_input->p_access_data = (void *)p_dvd;
/* Ifo allocation & initialisation */
area[i]->i_part_nb = tt_srpt->title[i-1].nr_of_ptts;
area[i]->i_part = 1;
- /* Number of angles */
- area[i]->i_angle_nb = 0;
- area[i]->i_angle = 1;
-
area[i]->i_plugin_data = tt_srpt->title[i-1].title_set_nr;
}
#undef area
- /* Get requested title - if none try the first title */
- i_title = config_GetIntVariable( INPUT_TITLE_VAR );
- if( i_title <= 0 || i_title > tt_srpt->nr_of_srpts )
- {
- i_title = 1;
- }
-
+ p_dvd->i_title = i_title <= tt_srpt->nr_of_srpts ? i_title : 1;
#undef tt_srpt
- /* Get requested chapter - if none defaults to first one */
- i_chapter = config_GetIntVariable( INPUT_CHAPTER_VAR );
- if( i_chapter <= 0 )
- {
- i_chapter = 1;
- }
-
- p_input->stream.pp_areas[i_title]->i_part = i_chapter;
+ p_area = p_input->stream.pp_areas[p_dvd->i_title];
+ p_dvd->i_chapter = i_chapter;
- p_area = p_input->stream.pp_areas[i_title];
+ p_dvd->i_chapter = i_chapter < p_area->i_part_nb ? i_chapter : 1;
+ p_area->i_part = p_dvd->i_chapter;
+
+ p_dvd->i_angle = i_angle;
/* set title, chapter, audio and subpic */
if( DvdReadSetArea( p_input, p_area ) )
vlc_mutex_unlock( &p_input->stream.stream_lock );
+ p_input->psz_demux = "dvdread";
+
return 0;
}
static int DvdReadSetProgram( input_thread_t * p_input,
pgrm_descriptor_t * p_program )
{
+ if( p_input->stream.p_selected_program != p_program )
+ {
+ thread_dvd_data_t * p_dvd;
+
+ p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
+ p_dvd->i_angle = p_program->i_number;
+
+ memcpy( p_program, p_input->stream.p_selected_program,
+ sizeof(pgrm_descriptor_t) );
+ p_program->i_number = p_dvd->i_angle;
+ p_input->stream.p_selected_program = p_program;
+
+ intf_WarnMsg( 3, "dvd info: angle %d selected", p_dvd->i_angle );
+ }
+
return 0;
}
/*
* Angle management
*/
- p_area->i_angle_nb = p_vmg->tt_srpt->title[p_area->i_id-1].nr_of_angles;
- p_area->i_angle = config_GetIntVariable( INPUT_ANGLE_VAR );
+ p_dvd->i_angle_nb = p_vmg->tt_srpt->title[p_area->i_id-1].nr_of_angles;
- if( ( p_area->i_angle <= 0 ) || p_area->i_angle > p_area->i_angle_nb )
+ if( p_dvd->i_angle > p_dvd->i_angle_nb )
{
- p_area->i_angle = 1;
+ p_dvd->i_angle = 1;
}
- p_dvd->i_angle = p_area->i_angle;
- p_dvd->i_angle_nb = p_area->i_angle_nb;
/*
* We've got enough info, time to open the title set data.
/* We don't use input_EndStream here since
* we keep area structures */
- 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] );
}
- free( p_input->stream.pp_selected_es );
- input_DelProgram( p_input, p_input->stream.p_selected_program );
+ while( p_input->stream.i_pgrm_number )
+ {
+ input_DelProgram( p_input, p_input->stream.pp_programs[0] );
+ }
- p_input->stream.pp_selected_es = NULL;
+ if( p_input->stream.pp_selected_es )
+ {
+ free( p_input->stream.pp_selected_es );
+ p_input->stream.pp_selected_es = NULL;
+ }
p_input->stream.i_selected_es_number = 0;
}
- input_AddProgram( p_input, 0, sizeof( stream_ps_data_t ) );
+ input_AddProgram( p_input, 1, sizeof( stream_ps_data_t ) );
p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
+ for( i = 1 ; i < p_dvd->i_angle_nb ; i++ )
+ {
+ input_AddProgram( p_input, i+1, 0 );
+ }
+
+ DvdReadSetProgram( p_input,
+ p_input->stream.pp_programs[p_dvd->i_angle-1] );
+
/* No PSM to read in DVD mode, we already have all information */
p_input->stream.p_selected_program->b_is_ok = 1;
/* ES 0 -> video MPEG2 */
// IfoPrintVideo( p_dvd );
- p_es = input_AddES( p_input, p_input->stream.p_selected_program, 0xe0, 0 );
+ 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;
{
case 0x00: /* AC3 */
i_id = ( ( 0x80 + i_position ) << 8 ) | 0xbd;
- p_es = input_AddES( p_input,
- p_input->stream.p_selected_program, i_id, 0 );
+ 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;
case 0x02:
case 0x03: /* MPEG audio */
i_id = 0xc0 + i_position;
- p_es = input_AddES( p_input,
- p_input->stream.p_selected_program, i_id, 0 );
+ 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;
case 0x04: /* LPCM */
i_id = ( ( 0xa0 + i_position ) << 8 ) | 0xbd;
- p_es = input_AddES( p_input,
- p_input->stream.p_selected_program, i_id, 0 );
+ p_es = input_AddES( p_input, NULL, i_id, 0 );
p_es->i_stream_id = i_id;
p_es->i_type = LPCM_AUDIO_ES;
p_es->b_audio = 1;
}
i_id = ( ( 0x20 + i_position ) << 8 ) | 0xbd;
- p_es = input_AddES( p_input,
- p_input->stream.p_selected_program, i_id, 0 );
+ 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;
#undef p_vts
#undef p_vmg
- if( p_area->i_angle != p_dvd->i_angle )
- {
- p_dvd->i_angle = p_area->i_angle;
-
- intf_WarnMsg( 3, "dvd info: angle %d selected", p_area->i_angle );
- }
/* warn interface that something has changed */
p_area->i_tell = LB2OFF( p_dvd->i_next_vobu ) - p_area->i_start;
p_input->stream.b_seekable = 1;
if( p_main->b_audio )
{
/* For audio: first one if none or a not existing one specified */
- int i_audio = config_GetIntVariable( INPUT_CHANNEL_VAR );
+ int i_audio = config_GetIntVariable( "input_channel" );
if( i_audio < 0 /*|| i_audio > i_audio_nb*/ )
{
- config_PutIntVariable( INPUT_CHANNEL_VAR, 1 );
+ config_PutIntVariable( "input_channel", 1 );
i_audio = 1;
}
if( i_audio > 0/* && i_audio_nb > 0*/ )
{
- if( config_GetIntVariable( AOUT_SPDIF_VAR ) ||
- ( config_GetIntVariable( INPUT_AUDIO_VAR ) ==
- REQUESTED_AC3 ) )
+ if( config_GetIntVariable( "input_audio" ) == REQUESTED_AC3 )
{
int i_ac3 = i_audio;
while( ( p_input->stream.pp_es[i_ac3]->i_type !=
if( p_main->b_video )
{
/* for spu, default is none */
- int i_spu = config_GetIntVariable( INPUT_SUBTITLE_VAR );
+ int i_spu = config_GetIntVariable( "input_subtitle" );
if( i_spu < 0 /*|| i_spu > i_spu_nb*/ )
{
- config_PutIntVariable( INPUT_SUBTITLE_VAR, 0 );
+ config_PutIntVariable( "input_subtitle", 0 );
i_spu = 0;
}
if( i_spu > 0 /*&& i_spu_nb > 0*/ )