Commit 25d2a663 authored by Gildas Bazin's avatar Gildas Bazin

* src/input/*, include/vlc_input.h: the MRL is now parsed for titles/chapters directly in the core.

  - syntax is: [url][@[title-start][,chapter-start][-[title-end][,chapter-end]]]
  - core also handles start/end boundaries itself (simplifies the access plugins).
* modules/access/dvdread.c,dvdnav.c,cdda.c: removed MRL parsing code.
parent 235b3bcb
......@@ -201,6 +201,14 @@ typedef struct
int i_title;
input_title_t **title;
int i_title_offset;
int i_seekpoint_offset;
int i_title_start;
int i_title_end;
int i_seekpoint_start;
int i_seekpoint_end;
/* Properties */
vlc_bool_t b_can_pace_control;
vlc_bool_t b_can_pause;
......@@ -253,6 +261,9 @@ struct input_thread_t
int i_title;
input_title_t **title;
int i_title_offset;
int i_seekpoint_offset;
/* User bookmarks FIXME won't be easy with multiples input */
int i_bookmark;
seekpoint_t **bookmark;
......
......@@ -72,9 +72,6 @@ struct access_sys_t
int i_titles;
input_title_t *title[99]; /* No more that 99 track in a cd-audio */
int i_title_start;
int i_title_end;
/* Current position */
int i_sector; /* Current Sector */
int * p_sectors; /* Track sectors */
......@@ -90,54 +87,38 @@ static int Control( access_t *, int, va_list );
/*****************************************************************************
* Open: open cdda
* MRL syntax: [dev_path][@[title-start][-[title-end]]]
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
access_t *p_access = (access_t*)p_this;
access_sys_t *p_sys;
char *psz_dup, *psz;
int i, i_title_start = -1, i_title_end = -1;
vcddev_t *vcddev;
char *psz_name;
int i;
/* Command line: [dev_path][@[title-start][-[title-end]]] */
psz_dup = p_access->psz_path? strdup( p_access->psz_path ) : 0;
if( psz_dup && ( psz = strchr( psz_dup, '@' ) ) )
{
*psz++ = 0;
i_title_start = i_title_end = strtol( psz, NULL, 0 );
if( ( psz = strchr( psz, '-' ) ) )
{
*psz++;
i_title_end = strtol( psz, NULL, 0 );
}
}
if( !psz_dup || !*psz_dup )
if( !p_access->psz_path || !*p_access->psz_path )
{
if( psz_dup ) free( psz_dup );
/* Only when selected */
if( !p_access->b_force ) return VLC_EGENERIC;
if( !p_this->b_force ) return VLC_EGENERIC;
psz_dup = var_CreateGetString( p_access, "cd-audio" );
if( !psz_dup || !*psz_dup )
psz_name = var_CreateGetString( p_this, "cd-audio" );
if( !psz_name || !*psz_name )
{
if( psz_dup ) free( psz_dup );
if( psz_name ) free( psz_name );
return VLC_EGENERIC;
}
}
else psz_name = strdup( p_access->psz_path );
/* Open CDDA */
if( (vcddev = ioctl_Open( VLC_OBJECT(p_access), psz_dup )) == NULL )
if( (vcddev = ioctl_Open( VLC_OBJECT(p_access), psz_name )) == NULL )
{
msg_Warn( p_access, "could not open %s", psz_dup );
free( psz_dup );
msg_Warn( p_access, "could not open %s", psz_name );
free( psz_name );
return VLC_EGENERIC;
}
free( psz_dup );
free( psz_name );
/* Set up p_access */
p_access->pf_read = NULL;
......@@ -184,17 +165,8 @@ static int Open( vlc_object_t *p_this )
t->i_length = I64C(1000000) * t->i_size / 44100 / 4;
}
/* Starting title and sector */
if( i_title_start < 1 || i_title_start > p_sys->i_titles )
p_sys->i_title_start = 1;
else p_sys->i_title_start = i_title_start;
if( i_title_end < 1 || i_title_end > p_sys->i_titles )
p_sys->i_title_end = -1;
else p_sys->i_title_end = i_title_end;
p_sys->i_sector = p_sys->p_sectors[p_sys->i_title_start-1];
p_access->info.i_title = p_sys->i_title_start-1;
p_access->info.i_size = p_sys->title[p_sys->i_title_start-1]->i_size;
p_sys->i_sector = p_sys->p_sectors[0];
p_access->info.i_size = p_sys->title[0]->i_size;
/* Build a WAV header for the output data */
memset( &p_sys->waveheader, 0, sizeof(WAVEHEADER) );
......@@ -266,9 +238,7 @@ static block_t *Block( access_t *p_access )
/* Check end of title */
while( p_sys->i_sector >= p_sys->p_sectors[p_access->info.i_title + 1] )
{
if( p_access->info.i_title + 1 >= p_sys->i_titles ||
( p_sys->i_title_end > 0 &&
p_access->info.i_title + 1 >= p_sys->i_title_end ) )
if( p_access->info.i_title + 1 >= p_sys->i_titles )
{
p_access->info.b_eof = VLC_TRUE;
return NULL;
......@@ -371,6 +341,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
case ACCESS_GET_TITLE_INFO:
ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
pi_int = (int*)va_arg( args, int* );
*((int*)va_arg( args, int* )) = 1; /* Title offset */
/* Duplicate title infos */
*pi_int = p_sys->i_titles;
......@@ -394,10 +365,6 @@ static int Control( access_t *p_access, int i_query, va_list args )
/* Next sector to read */
p_sys->i_sector = p_sys->p_sectors[i];
/* User tries to access another title so better reset
* the end title */
p_sys->i_title_end = -1;
}
break;
......
......@@ -52,6 +52,10 @@
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#define ANGLE_TEXT N_("DVD angle")
#define ANGLE_LONGTEXT N_( \
"Allows you to select the default DVD angle." )
#define CACHING_TEXT N_("Caching value in ms")
#define CACHING_LONGTEXT N_( \
"Allows you to modify the default caching value for DVDnav streams. This "\
......@@ -66,6 +70,8 @@ static void Close( vlc_object_t * );
vlc_module_begin();
set_description( _("DVDnav Input") );
add_integer( "dvdnav-angle", 1, NULL, ANGLE_TEXT,
ANGLE_LONGTEXT, VLC_FALSE );
add_integer( "dvdnav-caching", DEFAULT_PTS_DELAY / 1000, NULL,
CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );
add_bool( "dvdnav-menu", VLC_TRUE, NULL,
......@@ -82,8 +88,6 @@ vlc_module_end();
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static char *ParseCL( vlc_object_t *, char *, vlc_bool_t, int *, int *, int *);
typedef struct
{
VLC_COMMON_MEMBERS
......@@ -146,16 +150,28 @@ static int Open( vlc_object_t *p_this )
demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys;
dvdnav_t *p_dvdnav;
int i_title, i_chapter, i_angle;
int i_angle;
char *psz_name;
vlc_value_t val;
psz_name = ParseCL( VLC_OBJECT(p_demux), p_demux->psz_path, VLC_TRUE,
&i_title, &i_chapter, &i_angle );
if( !psz_name )
if( !p_demux->psz_path || !*p_demux->psz_path )
{
/* Only when selected */
if( !p_this->b_force ) return VLC_EGENERIC;
psz_name = var_CreateGetString( p_this, "dvd" );
if( !psz_name || !*psz_name )
{
if( psz_name ) free( psz_name );
return VLC_EGENERIC;
}
}
else psz_name = strdup( p_demux->psz_path );
#ifdef WIN32
if( psz_name[0] && psz_name[1] == ':' &&
psz_name[2] == '\\' && psz_name[3] == '\0' ) psz_name[2] = '\0';
#endif
/* Try some simple probing to avoid going through dvdnav_open too often */
if( ProbeDVD( p_demux, psz_name ) != VLC_SUCCESS )
......@@ -164,9 +180,6 @@ static int Open( vlc_object_t *p_this )
return VLC_EGENERIC;
}
msg_Dbg( p_this, "dvdroot=%s title=%d chapter=%d angle=%d",
psz_name, i_title, i_chapter, i_angle );
/* Open dvdnav */
if( dvdnav_open( &p_dvdnav, psz_name ) != DVDNAV_STATUS_OK )
{
......@@ -227,39 +240,9 @@ static int Open( vlc_object_t *p_this )
DemuxTitles( p_demux );
/* Set forced title/chapter */
if( i_title > 0 )
{
if( dvdnav_title_play( p_sys->dvdnav, i_title ) != DVDNAV_STATUS_OK )
{
msg_Warn( p_demux, "cannot set title" );
i_title = 0;
}
else
{
p_demux->info.i_update |= INPUT_UPDATE_TITLE;
p_demux->info.i_title = i_title;
}
}
if( i_chapter > 1 && i_title > 0 )
{
if( dvdnav_part_play( p_sys->dvdnav, i_title, i_chapter ) !=
DVDNAV_STATUS_OK )
{
msg_Warn( p_demux, "cannot set chapter" );
i_chapter = 1;
}
else
{
p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
p_demux->info.i_seekpoint = i_chapter;
}
}
var_Create( p_demux, "dvdnav-menu", VLC_VAR_BOOL|VLC_VAR_DOINHERIT );
var_Get( p_demux, "dvdnav-menu", &val );
if( (i_title < 0 && val.b_bool) || i_title == 0 )
if( val.b_bool )
{
msg_Dbg( p_demux, "trying to go to dvd menu" );
......@@ -273,15 +256,12 @@ static int Open( vlc_object_t *p_this )
{
msg_Warn( p_demux, "cannot go to dvd menu" );
}
else
{
p_demux->info.i_update |=
INPUT_UPDATE_TITLE | INPUT_UPDATE_SEEKPOINT;
p_demux->info.i_title = 0;
p_demux->info.i_seekpoint = 0;
}
}
var_Create( p_demux, "dvdnav-angle", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
var_Get( p_demux, "dvdnav-angle", &val );
i_angle = val.i_int > 0 ? val.i_int : 1;
/* Update default_pts to a suitable value for dvdnav access */
var_Create( p_demux, "dvdnav-caching", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
......@@ -426,6 +406,8 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
case DEMUX_GET_TITLE_INFO:
ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
pi_int = (int*)va_arg( args, int* );
*((int*)va_arg( args, int* )) = 0; /* Title offset */
*((int*)va_arg( args, int* )) = 1; /* Chapter offset */
/* Duplicate title infos */
*pi_int = p_sys->i_title;
......@@ -732,73 +714,6 @@ static int Demux( demux_t *p_demux )
return 1;
}
/*****************************************************************************
* ParseCL: parse command line.
* Titles start from 0 (menu), chapters and angles start from 1.
*****************************************************************************/
static char *ParseCL( vlc_object_t *p_this, char *psz_name, vlc_bool_t b_force,
int *i_title, int *i_chapter, int *i_angle )
{
char *psz_parser, *psz_source, *psz_next;
psz_source = strdup( psz_name );
if( psz_source == NULL ) return NULL;
*i_title = -1;
*i_chapter = 1;
*i_angle = 1;
/* Start with the end, because you could have :
* dvdnav:/Volumes/my@toto/VIDEO_TS@1,1
* (yes, this is kludgy). */
for( psz_parser = psz_source + strlen(psz_source) - 1;
psz_parser >= psz_source && *psz_parser != '@';
psz_parser-- );
if( psz_parser >= psz_source && *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 >= 0 ? *i_title : -1;
*i_chapter = *i_chapter > 0 ? *i_chapter : 1;
*i_angle = *i_angle > 0 ? *i_angle : 1;
if( !*psz_source )
{
free( psz_source );
if( !b_force )
{
return NULL;
}
psz_source = config_GetPsz( p_this, "dvd" );
if( !psz_source ) return NULL;
}
#ifdef WIN32
if( psz_source[0] && psz_source[1] == ':' &&
psz_source[2] == '\\' && psz_source[3] == '\0' )
{
psz_source[2] = '\0';
}
#endif
return psz_source;
}
static void DemuxTitles( demux_t *p_demux )
{
demux_sys_t *p_sys = p_demux->p_sys;
......@@ -855,8 +770,6 @@ static void DemuxTitles( demux_t *p_demux )
for( j = 0; j < __MAX( i_chapters, 1 ); j++ )
{
s = vlc_seekpoint_New();
s->psz_name = malloc( strlen( _("Chapter %i") ) + 20 );
sprintf( s->psz_name, _("Chapter %i"), j + 1 );
TAB_APPEND( t->i_seekpoint, t->seekpoint, s );
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -281,8 +281,8 @@ void input_ControlVarNavigation( input_thread_t *p_input )
if( p_input->title[i]->psz_name == NULL ||
*p_input->title[i]->psz_name == '\0' )
{
text.psz_string = malloc( strlen( _("Title %i") ) + 20 );
sprintf( text.psz_string, _("Title %i"), i );
asprintf( &text.psz_string, _("Title %i"),
i + p_input->i_title_offset );
}
else
{
......@@ -304,8 +304,8 @@ void input_ControlVarNavigation( input_thread_t *p_input )
*p_input->title[i]->seekpoint[j]->psz_name == '\0' )
{
/* Default value */
text2.psz_string = malloc( strlen( _("Chapter %i") ) + 20 );
sprintf( text2.psz_string, _("Chapter %i"), j );
asprintf( &text2.psz_string, _("Chapter %i"),
j + p_input->i_seekpoint_offset );
}
else
{
......@@ -364,8 +364,8 @@ void input_ControlVarTitle( input_thread_t *p_input, int i_title )
*t->seekpoint[i]->psz_name == '\0' )
{
/* Default value */
text.psz_string = malloc( strlen( _("Chapter %i") ) + 20 );
sprintf( text.psz_string, _("Chapter %i"), i );
asprintf( &text.psz_string, _("Chapter %i"),
i + p_input->i_seekpoint_offset );
}
else
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment