Commit d82e9eb7 authored by Laurent Aimar's avatar Laurent Aimar

* all: rework of the input.

parent 3d331406
...@@ -44,27 +44,17 @@ ...@@ -44,27 +44,17 @@
"Allows you to modify the default caching value for DVDnav streams. This "\ "Allows you to modify the default caching value for DVDnav streams. This "\
"value should be set in millisecond units." ) "value should be set in millisecond units." )
static int AccessOpen ( vlc_object_t * ); static int Open ( vlc_object_t * );
static void AccessClose( vlc_object_t * ); static void Close( vlc_object_t * );
static int DemuxOpen ( vlc_object_t * );
static void DemuxClose( vlc_object_t * );
vlc_module_begin(); vlc_module_begin();
set_description( _("DVDnav Input") ); set_description( _("DVDnav Input") );
add_integer( "dvdnav-caching", DEFAULT_PTS_DELAY / 1000, NULL, add_integer( "dvdnav-caching", DEFAULT_PTS_DELAY / 1000, NULL,
CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE ); CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );
set_capability( "access", 0 ); set_capability( "access_demux", 0 );
add_shortcut( "dvdnav" ); add_shortcut( "dvdnav" );
add_shortcut( "dvdnavsimple" ); add_shortcut( "dvdnavsimple" );
set_callbacks( AccessOpen, AccessClose ); set_callbacks( Open, Close );
add_submodule();
set_description( _("DVDnav Input (demux)") );
set_capability( "demux2", 0 );
add_shortcut( "dvdnav" );
add_shortcut( "dvdnavsimple" );
set_callbacks( DemuxOpen, DemuxClose );
vlc_module_end(); vlc_module_end();
/* TODO /* TODO
...@@ -80,7 +70,6 @@ vlc_module_end(); ...@@ -80,7 +70,6 @@ vlc_module_end();
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static ssize_t AccessRead( input_thread_t *, byte_t *, size_t ); /* dummy */
static char *ParseCL( vlc_object_t *, char *, vlc_bool_t, int *, int *, int *); static char *ParseCL( vlc_object_t *, char *, vlc_bool_t, int *, int *, int *);
typedef struct typedef struct
...@@ -124,10 +113,13 @@ struct demux_sys_t ...@@ -124,10 +113,13 @@ struct demux_sys_t
/* */ /* */
vlc_bool_t b_es_out_ok; vlc_bool_t b_es_out_ok;
vlc_bool_t b_simple; vlc_bool_t b_simple;
int i_title;
input_title_t **title;
}; };
static int DemuxControl( demux_t *, int, va_list ); static int Control( demux_t *, int, va_list );
static int DemuxDemux ( demux_t * ); static int Demux ( demux_t * );
static int DemuxBlock ( demux_t *, uint8_t *pkt, int i_pkt ); static int DemuxBlock ( demux_t *, uint8_t *pkt, int i_pkt );
enum enum
...@@ -138,186 +130,26 @@ enum ...@@ -138,186 +130,26 @@ enum
AR_221_1_PICTURE = 4, /* 2.21:1 picture (movie) */ AR_221_1_PICTURE = 4, /* 2.21:1 picture (movie) */
}; };
#if 0
static int MenusCallback( vlc_object_t *, char const *, static int MenusCallback( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * ); vlc_value_t, vlc_value_t, void * );
#endif
static void DemuxTitles( demux_t *p_demux );
static void ESSubtitleUpdate( demux_t * ); static void ESSubtitleUpdate( demux_t * );
static void ButtonUpdate( demux_t * ); static void ButtonUpdate( demux_t * );
/*****************************************************************************
* Open: see if dvdnav can handle the input and if so force dvdnav demux
*****************************************************************************
* For now it has to be like that (ie open dvdnav twice) but will be fixed
* when a demux can work without an access module.
*****************************************************************************/
static int AccessOpen( vlc_object_t *p_this )
{
input_thread_t *p_input = (input_thread_t *)p_this;
dvdnav_t *dvdnav;
int i_title, i_chapter, i_angle;
char *psz_name;
vlc_value_t val;
vlc_bool_t b_force;
/* We try only if we are forced */
if( p_input->psz_demux && *p_input->psz_demux &&
strncmp( p_input->psz_demux, "dvdnav", 6 ) )
{
msg_Warn( p_input, "dvdnav access discarded (demuxer forced)" );
return VLC_EGENERIC;
}
b_force = p_input->psz_access &&
!strncmp( p_input->psz_access, "dvdnav", 6 );
psz_name = ParseCL( VLC_OBJECT(p_input), p_input->psz_name, b_force,
&i_title, &i_chapter, &i_angle );
if( !psz_name )
{
return VLC_EGENERIC;
}
/* Test dvdnav */
if( dvdnav_open( &dvdnav, psz_name ) != DVDNAV_STATUS_OK )
{
msg_Warn( p_input, "cannot open dvdnav" );
free( psz_name );
return VLC_EGENERIC;
}
dvdnav_close( dvdnav );
free( psz_name );
/* Fill p_input fields */
p_input->pf_read = AccessRead;
p_input->pf_set_program = input_SetProgram;
p_input->pf_set_area = NULL;
p_input->pf_seek = NULL;
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.b_pace_control = VLC_TRUE;
p_input->stream.b_seekable = VLC_TRUE;
p_input->stream.p_selected_area->i_tell = 0;
/* Bogus for demux1 compatibility */
p_input->stream.p_selected_area->i_size = 10000;
p_input->stream.i_method = INPUT_METHOD_DVD;
vlc_mutex_unlock( &p_input->stream.stream_lock );
p_input->i_mtu = 0;
/* Force dvdnav demux */
if( p_input->psz_access && !strncmp(p_input->psz_access, "dvdnav", 6 ) )
p_input->psz_demux = strdup( p_input->psz_access );
else
p_input->psz_demux = strdup( "dvdnav" );
/* Update default_pts to a suitable value for udp access */
var_Create( p_input, "dvdnav-caching", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
var_Get( p_input, "dvdnav-caching", &val );
p_input->i_pts_delay = val.i_int * 1000;
return VLC_SUCCESS;
}
/*****************************************************************************
* Close: free unused data structures
*****************************************************************************/
static void AccessClose( vlc_object_t *p_this )
{
}
/*****************************************************************************
* Read: Should not be called (ie not used by the dvdnav demuxer)
*****************************************************************************/
static ssize_t AccessRead( input_thread_t *p_input, byte_t *p_buffer,
size_t i_len )
{
memset( p_buffer, 0, i_len );
return i_len;
}
/*****************************************************************************
* ParseCL: parse command line
*****************************************************************************/
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 = 0;
*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 : 0;
*i_chapter = *i_chapter ? *i_chapter : 1;
*i_angle = *i_angle ? *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
msg_Dbg( p_this, "dvdroot=%s title=%d chapter=%d angle=%d",
psz_source, *i_title, *i_chapter, *i_angle );
return psz_source;
}
/***************************************************************************** /*****************************************************************************
* DemuxOpen: * DemuxOpen:
*****************************************************************************/ *****************************************************************************/
static int DemuxOpen( vlc_object_t *p_this ) static int Open( vlc_object_t *p_this )
{ {
demux_t *p_demux = (demux_t*)p_this; demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys; demux_sys_t *p_sys;
vlc_value_t val, text; int i_title, i_chapter, i_angle;
int i_title, i_titles, i_chapter, i_chapters, i_angle, i;
char *psz_name; char *psz_name;
if( strncmp( p_demux->psz_access, "dvdnav", 6 ) || if( strncmp( p_demux->psz_access, "dvdnav", 6 ) )
strncmp( p_demux->psz_demux, "dvdnav", 6 ) )
{ {
msg_Warn( p_demux, "dvdnav module discarded" ); msg_Warn( p_demux, "dvdnav module discarded" );
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -330,7 +162,9 @@ static int DemuxOpen( vlc_object_t *p_this ) ...@@ -330,7 +162,9 @@ static int DemuxOpen( vlc_object_t *p_this )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/* Init p_sys */ /* fill p_demux field */
p_demux->pf_demux = Demux;
p_demux->pf_control = Control;
p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) ); p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
memset( p_sys, 0, sizeof( demux_sys_t ) ); memset( p_sys, 0, sizeof( demux_sys_t ) );
...@@ -376,29 +210,46 @@ static int DemuxOpen( vlc_object_t *p_this ) ...@@ -376,29 +210,46 @@ static int DemuxOpen( vlc_object_t *p_this )
dvdnav_err_to_string( p_sys->dvdnav ) ); dvdnav_err_to_string( p_sys->dvdnav ) );
} }
#if 0 // FIXME: Doesn't work with libdvdnav CVS! // FIXME: Doesn't work with libdvdnav CVS!
/* Find out number of titles/chapters */ // Bah don't use CVS ;) --fenrir (anyway it's needed now)
dvdnav_get_number_of_titles( p_sys->dvdnav, &i_titles ); DemuxTitles( p_demux );
for( i = 1; i <= i_titles; i++ )
/* Set forced title/chapter */
if( i_title != 0 )
{ {
i_chapters = 0; if( dvdnav_title_play( p_sys->dvdnav, i_title ) != DVDNAV_STATUS_OK )
dvdnav_get_number_of_parts( p_sys->dvdnav, i, &i_chapters ); {
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;
}
} }
#endif
if( dvdnav_title_play( p_sys->dvdnav, i_title ) != if( i_chapter != 0 && i_title != 0 )
DVDNAV_STATUS_OK )
{ {
msg_Warn( p_demux, "cannot set title/chapter" ); if( dvdnav_part_play( p_sys->dvdnav, i_title, i_chapter ) != DVDNAV_STATUS_OK )
{
msg_Warn( p_demux, "cannot set chapter" );
i_chapter = 0;
}
else
{
p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
p_demux->info.i_seekpoint = i_chapter;
}
} }
/* fill p_demux field */ /* Update default_pts to a suitable value for dvdnav access */
p_demux->pf_control = DemuxControl; var_Create( p_demux, "dvdnav-caching", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
p_demux->pf_demux = DemuxDemux;
/* For simple mode (no menus), we're done */ /* For simple mode (no menus), we're done */
if( p_sys->b_simple ) return VLC_SUCCESS; if( p_sys->b_simple ) return VLC_SUCCESS;
/* FIXME hack hack hack hachk FIXME */
/* Get p_input and create variable */ /* Get p_input and create variable */
p_sys->p_input = vlc_object_find( p_demux, VLC_OBJECT_INPUT, FIND_PARENT ); p_sys->p_input = vlc_object_find( p_demux, VLC_OBJECT_INPUT, FIND_PARENT );
var_Create( p_sys->p_input, "x-start", VLC_VAR_INTEGER ); var_Create( p_sys->p_input, "x-start", VLC_VAR_INTEGER );
...@@ -410,27 +261,6 @@ static int DemuxOpen( vlc_object_t *p_this ) ...@@ -410,27 +261,6 @@ static int DemuxOpen( vlc_object_t *p_this )
var_Create( p_sys->p_input, "highlight", VLC_VAR_BOOL ); var_Create( p_sys->p_input, "highlight", VLC_VAR_BOOL );
var_Create( p_sys->p_input, "highlight-mutex", VLC_VAR_MUTEX ); var_Create( p_sys->p_input, "highlight-mutex", VLC_VAR_MUTEX );
/* Create a few object variables used for navigation in the interfaces */
var_Create( p_sys->p_input, "dvd_menus",
VLC_VAR_INTEGER | VLC_VAR_HASCHOICE | VLC_VAR_ISCOMMAND );
text.psz_string = _("DVD menus");
var_Change( p_sys->p_input, "dvd_menus", VLC_VAR_SETTEXT, &text, NULL );
var_AddCallback( p_sys->p_input, "dvd_menus", MenusCallback, p_demux );
val.i_int = DVD_MENU_Escape; text.psz_string = _("Resume");
var_Change( p_sys->p_input, "dvd_menus", VLC_VAR_ADDCHOICE, &val, &text );
val.i_int = DVD_MENU_Root; text.psz_string = _("Root");
var_Change( p_sys->p_input, "dvd_menus", VLC_VAR_ADDCHOICE, &val, &text );
val.i_int = DVD_MENU_Title; text.psz_string = _("Title");
var_Change( p_sys->p_input, "dvd_menus", VLC_VAR_ADDCHOICE, &val, &text );
val.i_int = DVD_MENU_Part; text.psz_string = _("Chapter");
var_Change( p_sys->p_input, "dvd_menus", VLC_VAR_ADDCHOICE, &val, &text );
val.i_int = DVD_MENU_Subpicture; text.psz_string = _("Subtitle");
var_Change( p_sys->p_input, "dvd_menus", VLC_VAR_ADDCHOICE, &val, &text );
val.i_int = DVD_MENU_Audio; text.psz_string = _("Audio");
var_Change( p_sys->p_input, "dvd_menus", VLC_VAR_ADDCHOICE, &val, &text );
val.i_int = DVD_MENU_Angle; text.psz_string = _("Angle");
var_Change( p_sys->p_input, "dvd_menus", VLC_VAR_ADDCHOICE, &val, &text );
/* Now create our event thread catcher */ /* Now create our event thread catcher */
p_sys->p_ev = vlc_object_create( p_demux, sizeof( event_thread_t ) ); p_sys->p_ev = vlc_object_create( p_demux, sizeof( event_thread_t ) );
p_sys->p_ev->p_demux = p_demux; p_sys->p_ev->p_demux = p_demux;
...@@ -441,9 +271,9 @@ static int DemuxOpen( vlc_object_t *p_this ) ...@@ -441,9 +271,9 @@ static int DemuxOpen( vlc_object_t *p_this )
} }
/***************************************************************************** /*****************************************************************************
* DemuxClose: * Close:
*****************************************************************************/ *****************************************************************************/
static void DemuxClose( vlc_object_t *p_this ) static void Close( vlc_object_t *p_this )
{ {
demux_t *p_demux = (demux_t*)p_this; demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
...@@ -483,12 +313,17 @@ static void DemuxClose( vlc_object_t *p_this ) ...@@ -483,12 +313,17 @@ static void DemuxClose( vlc_object_t *p_this )
} }
/***************************************************************************** /*****************************************************************************
* DemuxControl: * Control:
*****************************************************************************/ *****************************************************************************/
static int DemuxControl( demux_t *p_demux, int i_query, va_list args ) static int Control( demux_t *p_demux, int i_query, va_list args )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
double f, *pf; double f, *pf;
vlc_bool_t *pb;
int64_t *pi64;
input_title_t ***ppp_title;
int *pi_int;
int i;
switch( i_query ) switch( i_query )
{ {
...@@ -525,6 +360,92 @@ static int DemuxControl( demux_t *p_demux, int i_query, va_list args ) ...@@ -525,6 +360,92 @@ static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/* Special for access_demux */
case DEMUX_CAN_PAUSE:
case DEMUX_CAN_CONTROL_PACE:
/* TODO */
pb = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
*pb = VLC_TRUE;
return VLC_SUCCESS;
case DEMUX_SET_PAUSE_STATE:
return VLC_SUCCESS;
case DEMUX_GET_TITLE_INFO:
ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
pi_int = (int*)va_arg( args, int* );
/* Duplicate title infos */
*pi_int = p_sys->i_title;
*ppp_title = malloc( sizeof( input_title_t ** ) * p_sys->i_title );
for( i = 0; i < p_sys->i_title; i++ )
{
(*ppp_title)[i] = vlc_input_title_Duplicate( p_sys->title[i] );
}
return VLC_SUCCESS;
case DEMUX_SET_TITLE:
i = (int)va_arg( args, int );
if( ( i == 0 && dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Root ) != DVDNAV_STATUS_OK ) ||
( i != 0 && dvdnav_title_play( p_sys->dvdnav, i ) != DVDNAV_STATUS_OK ) )
{
msg_Warn( p_demux, "cannot set title/chapter" );
return VLC_EGENERIC;
}
p_demux->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SEEKPOINT;
p_demux->info.i_title = i;
p_demux->info.i_seekpoint = 0;
return VLC_SUCCESS;
case DEMUX_SET_SEEKPOINT:
i = (int)va_arg( args, int );
if( p_demux->info.i_title == 0 )
{
int i_ret;
/* Special case */
switch( i )
{
case 0:
i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Escape );
break;
case 1:
i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Root );
break;
case 2:
i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Title );
break;
case 3:
i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Part );
break;
case 4:
i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Subpicture );
break;
case 5:
i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Audio );
break;
case 6:
i_ret = dvdnav_menu_call( p_sys->dvdnav, DVD_MENU_Angle );
break;
default:
return VLC_EGENERIC;
}
if( i_ret != DVDNAV_STATUS_OK )
return VLC_EGENERIC;
}
else if( dvdnav_part_play( p_sys->dvdnav, p_demux->info.i_title, i ) != DVDNAV_STATUS_OK )
{
msg_Warn( p_demux, "cannot set title/chapter" );
return VLC_EGENERIC;
}
p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
p_demux->info.i_seekpoint = i;
return VLC_SUCCESS;
case DEMUX_GET_PTS_DELAY:
pi64 = (int64_t*)va_arg( args, int64_t * );
*pi64 = (int64_t)var_GetInteger( p_demux, "dvdnav-caching" ) * I64C(1000);
return VLC_SUCCESS;
/* TODO implement others */ /* TODO implement others */
default: default:
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -532,9 +453,9 @@ static int DemuxControl( demux_t *p_demux, int i_query, va_list args ) ...@@ -532,9 +453,9 @@ static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
} }
/***************************************************************************** /*****************************************************************************
* DemuxDemux: * Demux:
*****************************************************************************/ *****************************************************************************/
static int DemuxDemux( demux_t *p_demux ) static int Demux( demux_t *p_demux )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
...@@ -558,11 +479,10 @@ static int DemuxDemux( demux_t *p_demux ) ...@@ -558,11 +479,10 @@ static int DemuxDemux( demux_t *p_demux )
} }
#if DVD_READ_CACHE #if DVD_READ_CACHE
if( dvdnav_get_next_cache_block( p_sys->dvdnav, &packet, &i_event, &i_len ) if( dvdnav_get_next_cache_block( p_sys->dvdnav, &packet, &i_event, &i_len ) == DVDNAV_STATUS_ERR )
#else #else
if( dvdnav_get_next_block( p_sys->dvdnav, packet, &i_event, &i_len ) if( dvdnav_get_next_block( p_sys->dvdnav, packet, &i_event, &i_len ) == DVDNAV_STATUS_ERR )
#endif #endif
== DVDNAV_STATUS_ERR )
{ {
msg_Warn( p_demux, "cannot get next block (%s)", msg_Warn( p_demux, "cannot get next block (%s)",
dvdnav_err_to_string( p_sys->dvdnav ) ); dvdnav_err_to_string( p_sys->dvdnav ) );
...@@ -638,7 +558,10 @@ static int DemuxDemux( demux_t *p_demux ) ...@@ -638,7 +558,10 @@ static int DemuxDemux( demux_t *p_demux )
} }
case DVDNAV_VTS_CHANGE: case DVDNAV_VTS_CHANGE:
{ {
int32_t i_title = 0;
int32_t i_part = 0;
int i; int i;
dvdnav_vts_change_event_t *event = (dvdnav_vts_change_event_t*)packet; dvdnav_vts_change_event_t *event = (dvdnav_vts_change_event_t*)packet;
msg_Dbg( p_demux, "DVDNAV_VTS_CHANGE" ); msg_Dbg( p_demux, "DVDNAV_VTS_CHANGE" );
msg_Dbg( p_demux, " - vtsN=%d", event->new_vtsN ); msg_Dbg( p_demux, " - vtsN=%d", event->new_vtsN );
...@@ -662,25 +585,29 @@ static int DemuxDemux( demux_t *p_demux ) ...@@ -662,25 +585,29 @@ static int DemuxDemux( demux_t *p_demux )
tk->b_seen = VLC_FALSE; tk->b_seen = VLC_FALSE;
} }
if( p_sys->b_simple )
{
int32_t i_title = 0;
int32_t i_part = 0;
if( dvdnav_current_title_info( p_sys->dvdnav, &i_title, if( dvdnav_current_title_info( p_sys->dvdnav, &i_title,
&i_part ) == DVDNAV_STATUS_OK ) &i_part ) == DVDNAV_STATUS_OK )
{ {
if( i_title == 0 ) if( p_sys->b_simple && i_title == 0 )
{ {
/* we have returned in menu, stop dvd */ /* we have returned in menu, stop dvd */
/* FIXME is it the right way ? */ /* FIXME is it the right way ? */
return 0; return 0;
} }
if( i_title >= 0 && i_title < p_sys->i_title &&
p_demux->info.i_title != i_title )
{
p_demux->info.i_update |= INPUT_UPDATE_TITLE;
p_demux->info.i_title = i_title;
} }
} }
break; break;
} }
case DVDNAV_CELL_CHANGE: case DVDNAV_CELL_CHANGE:
{ {
int32_t i_title = 0;
int32_t i_part = 0;
dvdnav_cell_change_event_t *event = dvdnav_cell_change_event_t *event =
(dvdnav_cell_change_event_t*)packet; (dvdnav_cell_change_event_t*)packet;
msg_Dbg( p_demux, "DVDNAV_CELL_CHANGE" ); msg_Dbg( p_demux, "DVDNAV_CELL_CHANGE" );
...@@ -691,8 +618,22 @@ static int DemuxDemux( demux_t *p_demux ) ...@@ -691,8 +618,22 @@ static int DemuxDemux( demux_t *p_demux )
msg_Dbg( p_demux, " - pgc_length=%lld", event->pgc_length ); msg_Dbg( p_demux, " - pgc_length=%lld", event->pgc_length );
msg_Dbg( p_demux, " - cell_start=%lld", event->cell_start ); msg_Dbg( p_demux, " - cell_start=%lld", event->cell_start );
msg_Dbg( p_demux, " - pg_start=%lld", event->pg_start ); msg_Dbg( p_demux, " - pg_start=%lld", event->pg_start );
/* FIXME is it correct or there is better way to know chapter change */
if( dvdnav_current_title_info( p_sys->dvdnav, &i_title,
&i_part ) == DVDNAV_STATUS_OK )
{
if( i_title >= 0 && i_title < p_sys->i_title &&
i_part >= 0 && i_part < p_sys->title[i_title]->i_seekpoint &&
p_demux->info.i_seekpoint != i_part )
{
p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
p_demux->info.i_seekpoint = i_part;
}
}
break; break;
} }
case DVDNAV_NAV_PACKET: case DVDNAV_NAV_PACKET:
{ {
#ifdef DVDNAV_DEBUG #ifdef DVDNAV_DEBUG
...@@ -751,6 +692,139 @@ static int DemuxDemux( demux_t *p_demux ) ...@@ -751,6 +692,139 @@ static int DemuxDemux( demux_t *p_demux )
return 1; return 1;
} }
/*****************************************************************************
* ParseCL: parse command line
*****************************************************************************/
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 = 0;
*i_chapter = 0;
*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 : 0;
*i_chapter = *i_chapter ? *i_chapter : 0;
*i_angle = *i_angle ? *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
msg_Dbg( p_this, "dvdroot=%s title=%d chapter=%d angle=%d",
psz_source, *i_title, *i_chapter, *i_angle );
return psz_source;
}
static void DemuxTitles( demux_t *p_demux )
{
demux_sys_t *p_sys = p_demux->p_sys;
input_title_t *t;
seekpoint_t *s;
int32_t i_titles;
int i;
/* Menu */
t = vlc_input_title_New();
t->b_menu = VLC_TRUE;
t->psz_name = strdup( "DVD Menu" );
s = vlc_seekpoint_New();
s->psz_name = strdup( "Resume" );
TAB_APPEND( t->i_seekpoint, t->seekpoint, s );
s = vlc_seekpoint_New();
s->psz_name = strdup( "Root" );
TAB_APPEND( t->i_seekpoint, t->seekpoint, s );
s = vlc_seekpoint_New();
s->psz_name = strdup( "Title" );
TAB_APPEND( t->i_seekpoint, t->seekpoint, s );
s = vlc_seekpoint_New();
s->psz_name = strdup( "Chapter" );
TAB_APPEND( t->i_seekpoint, t->seekpoint, s );
s = vlc_seekpoint_New();
s->psz_name = strdup( "Subtitle" );
TAB_APPEND( t->i_seekpoint, t->seekpoint, s );
s = vlc_seekpoint_New();
s->psz_name = strdup( "Audio" );
TAB_APPEND( t->i_seekpoint, t->seekpoint, s );
s = vlc_seekpoint_New();
s->psz_name = strdup( "Angle" );
TAB_APPEND( t->i_seekpoint, t->seekpoint, s );
TAB_APPEND( p_sys->i_title, p_sys->title, t );
/* Find out number of titles/chapters */
dvdnav_get_number_of_titles( p_sys->dvdnav, &i_titles );
for( i = 1; i < i_titles; i++ )
{
int32_t i_chapters = 0;
int j;
dvdnav_get_number_of_parts( p_sys->dvdnav, i, &i_chapters );
t = vlc_input_title_New();
for( j = 0; j < __MAX( i_chapters, 1 ); j++ )
{
s = vlc_seekpoint_New();
TAB_APPEND( t->i_seekpoint, t->seekpoint, s );
}
TAB_APPEND( p_sys->i_title, p_sys->title, t );
}
}
/***************************************************************************** /*****************************************************************************
* Update functions: * Update functions:
*****************************************************************************/ *****************************************************************************/
...@@ -1220,6 +1294,7 @@ static int EventKey( vlc_object_t *p_this, char const *psz_var, ...@@ -1220,6 +1294,7 @@ static int EventKey( vlc_object_t *p_this, char const *psz_var,
return VLC_SUCCESS; return VLC_SUCCESS;
} }
#if 0
static int MenusCallback( vlc_object_t *p_this, char const *psz_name, static int MenusCallback( vlc_object_t *p_this, char const *psz_name,
vlc_value_t oldval, vlc_value_t newval, void *p_arg ) vlc_value_t oldval, vlc_value_t newval, void *p_arg )
{ {
...@@ -1230,3 +1305,4 @@ static int MenusCallback( vlc_object_t *p_this, char const *psz_name, ...@@ -1230,3 +1305,4 @@ static int MenusCallback( vlc_object_t *p_this, char const *psz_name,
return VLC_SUCCESS; return VLC_SUCCESS;
} }
#endif
...@@ -44,11 +44,8 @@ using namespace std; ...@@ -44,11 +44,8 @@ using namespace std;
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
*****************************************************************************/ *****************************************************************************/
static int DemuxOpen ( vlc_object_t * ); static int Open ( vlc_object_t * );
static void DemuxClose( vlc_object_t * ); static void Close( vlc_object_t * );
static int AccessOpen ( vlc_object_t * );
static void AccessClose( vlc_object_t * );
#define CACHING_TEXT N_("Caching value (ms)") #define CACHING_TEXT N_("Caching value (ms)")
#define CACHING_LONGTEXT N_( \ #define CACHING_LONGTEXT N_( \
...@@ -58,15 +55,15 @@ static void AccessClose( vlc_object_t * ); ...@@ -58,15 +55,15 @@ static void AccessClose( vlc_object_t * );
vlc_module_begin(); vlc_module_begin();
set_description( _("live.com (RTSP/RTP/SDP) demuxer" ) ); set_description( _("live.com (RTSP/RTP/SDP) demuxer" ) );
set_capability( "demux2", 50 ); set_capability( "demux2", 50 );
set_callbacks( DemuxOpen, DemuxClose ); set_callbacks( Open, Close );
add_shortcut( "live" ); add_shortcut( "live" );
add_submodule(); add_submodule();
set_description( _("RTSP/RTP describe") ); set_description( _("RTSP/RTP access and demux") );
add_shortcut( "rtsp" ); add_shortcut( "rtsp" );
add_shortcut( "sdp" ); add_shortcut( "sdp" );
set_capability( "access", 0 ); set_capability( "access_demux", 0 );
set_callbacks( AccessOpen, AccessClose ); set_callbacks( Open, Close );
add_bool( "rtsp-tcp", 0, NULL, add_bool( "rtsp-tcp", 0, NULL,
N_("Use RTP over RTSP (TCP)"), N_("Use RTP over RTSP (TCP)"),
N_("Use RTP over RTSP (TCP)"), VLC_TRUE ); N_("Use RTP over RTSP (TCP)"), VLC_TRUE );
...@@ -84,187 +81,7 @@ vlc_module_end(); ...@@ -84,187 +81,7 @@ vlc_module_end();
*/ */
/***************************************************************************** /*****************************************************************************
* Local prototypes for access * Local prototypes
*****************************************************************************/
struct access_sys_t
{
int i_sdp;
char *p_sdp;
int i_pos;
};
static ssize_t Read ( input_thread_t *, byte_t *, size_t );
static ssize_t MRLRead( input_thread_t *, byte_t *, size_t );
/*****************************************************************************
* AccessOpen:
*****************************************************************************/
static int AccessOpen( vlc_object_t *p_this )
{
input_thread_t *p_input = (input_thread_t *)p_this;
access_sys_t *p_sys;
TaskScheduler *scheduler = NULL;
UsageEnvironment *env = NULL;
RTSPClient *rtsp = NULL;
vlc_value_t val;
char *psz_url;
if( p_input->psz_access == NULL || ( strcasecmp( p_input->psz_access, "rtsp" ) && strcasecmp( p_input->psz_access, "sdp" ) ) )
{
msg_Warn( p_input, "RTSP access discarded" );
return VLC_EGENERIC;
}
if( !strcasecmp( p_input->psz_access, "rtsp" ) )
{
if( ( scheduler = BasicTaskScheduler::createNew() ) == NULL )
{
msg_Err( p_input, "BasicTaskScheduler::createNew failed" );
return VLC_EGENERIC;
}
if( ( env = BasicUsageEnvironment::createNew(*scheduler) ) == NULL )
{
delete scheduler;
msg_Err( p_input, "BasicUsageEnvironment::createNew failed" );
return VLC_EGENERIC;
}
if( ( rtsp = RTSPClient::createNew(*env, 1/*verbose*/, "VLC Media Player" ) ) == NULL )
{
delete env;
delete scheduler;
msg_Err( p_input, "RTSPClient::createNew failed" );
return VLC_EGENERIC;
}
psz_url = (char*)malloc( strlen( p_input->psz_name ) + 8 );
sprintf( psz_url, "rtsp://%s", p_input->psz_name );
p_sys = (access_sys_t*)malloc( sizeof( access_sys_t ) );
p_sys->p_sdp = rtsp->describeURL( psz_url );
if( p_sys->p_sdp == NULL )
{
msg_Err( p_input, "describeURL failed (%s)", env->getResultMsg() );
free( psz_url );
delete env;
delete scheduler;
free( p_sys );
return VLC_EGENERIC;
}
free( psz_url );
p_sys->i_sdp = strlen( p_sys->p_sdp );
p_sys->i_pos = 0;
delete env;
delete scheduler;
var_Create( p_input, "rtsp-tcp", VLC_VAR_BOOL|VLC_VAR_DOINHERIT );
var_Get( p_input, "rtsp-tcp", &val );
p_input->p_access_data = p_sys;
p_input->i_mtu = 0;
/* Set exported functions */
p_input->pf_read = Read;
p_input->pf_seek = NULL;
p_input->pf_set_program = input_SetProgram;
p_input->pf_set_area = NULL;
p_input->p_private = NULL;
p_input->psz_demux = "live";
/* Finished to set some variable */
vlc_mutex_lock( &p_input->stream.stream_lock );
/* FIXME that's not true but eg over tcp, server send data too fast */
p_input->stream.b_pace_control = val.b_bool;
p_input->stream.p_selected_area->i_tell = 0;
p_input->stream.b_seekable = 1; /* Hack to display time */
p_input->stream.p_selected_area->i_size = p_sys->i_sdp;
p_input->stream.i_method = INPUT_METHOD_NETWORK;
vlc_mutex_unlock( &p_input->stream.stream_lock );
/* Update default_pts to a suitable value for RTSP access */
var_Create( p_input, "rtsp-caching", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
var_Get( p_input, "rtsp-caching", &val );
p_input->i_pts_delay = val.i_int * 1000;
return VLC_SUCCESS;
}
else
{
p_input->p_access_data = (access_sys_t*)0;
p_input->i_mtu = 0;
p_input->pf_read = MRLRead;
p_input->pf_seek = NULL;
p_input->pf_set_program = input_SetProgram;
p_input->pf_set_area = NULL;
p_input->p_private = NULL;
p_input->psz_demux = "live";
/* Finished to set some variable */
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.b_pace_control = VLC_TRUE;
p_input->stream.p_selected_area->i_tell = 0;
p_input->stream.b_seekable = VLC_FALSE;
p_input->stream.p_selected_area->i_size = strlen(p_input->psz_name);
p_input->stream.i_method = INPUT_METHOD_NETWORK;
vlc_mutex_unlock( &p_input->stream.stream_lock );
return VLC_SUCCESS;
}
}
/*****************************************************************************
* AccessClose:
*****************************************************************************/
static void AccessClose( vlc_object_t *p_this )
{
input_thread_t *p_input = (input_thread_t *)p_this;
access_sys_t *p_sys = p_input->p_access_data;
if( !strcasecmp( p_input->psz_access, "rtsp" ) )
{
delete[] p_sys->p_sdp;
free( p_sys );
}
}
/*****************************************************************************
* Read:
*****************************************************************************/
static ssize_t Read ( input_thread_t *p_input, byte_t *p_buffer, size_t i_len )
{
access_sys_t *p_sys = p_input->p_access_data;
int i_copy = __MIN( (int)i_len, p_sys->i_sdp - p_sys->i_pos );
if( i_copy > 0 )
{
memcpy( p_buffer, &p_sys->p_sdp[p_sys->i_pos], i_copy );
p_sys->i_pos += i_copy;
}
return i_copy;
}
/*****************************************************************************
* MRLRead: read data from the mrl
*****************************************************************************/
static ssize_t MRLRead ( input_thread_t *p_input, byte_t *p_buffer, size_t i_len )
{
int i_done = (int)p_input->p_access_data;
int i_copy = __MIN( (int)i_len, (int)strlen(p_input->psz_name) - i_done );
if( i_copy > 0 )
{
memcpy( p_buffer, &p_input->psz_name[i_done], i_copy );
i_done += i_copy;
p_input->p_access_data = (access_sys_t*)i_done;
}
return i_copy;
}
/*****************************************************************************
* Local prototypes for demux2
*****************************************************************************/ *****************************************************************************/
typedef struct typedef struct
{ {
...@@ -315,7 +132,7 @@ static int Control( demux_t *, int, va_list ); ...@@ -315,7 +132,7 @@ static int Control( demux_t *, int, va_list );
/***************************************************************************** /*****************************************************************************
* DemuxOpen: * DemuxOpen:
*****************************************************************************/ *****************************************************************************/
static int DemuxOpen ( vlc_object_t *p_this ) static int Open ( vlc_object_t *p_this )
{ {
demux_t *p_demux = (demux_t*)p_this; demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys; demux_sys_t *p_sys;
...@@ -323,14 +140,15 @@ static int DemuxOpen ( vlc_object_t *p_this ) ...@@ -323,14 +140,15 @@ static int DemuxOpen ( vlc_object_t *p_this )
MediaSubsessionIterator *iter; MediaSubsessionIterator *iter;
MediaSubsession *sub; MediaSubsession *sub;
vlc_value_t val; vlc_bool_t b_rtsp_tcp;
uint8_t *p_peek; uint8_t *p_peek;
int i_sdp; int i_sdp;
int i_sdp_max; int i_sdp_max;
uint8_t *p_sdp; uint8_t *p_sdp;
if( p_demux->s )
{
/* See if it looks like a SDP /* See if it looks like a SDP
v, o, s fields are mandatory and in this order */ v, o, s fields are mandatory and in this order */
if( stream_Peek( p_demux->s, &p_peek, 7 ) < 7 ) if( stream_Peek( p_demux->s, &p_peek, 7 ) < 7 )
...@@ -339,11 +157,16 @@ static int DemuxOpen ( vlc_object_t *p_this ) ...@@ -339,11 +157,16 @@ static int DemuxOpen ( vlc_object_t *p_this )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
if( strncmp( (char*)p_peek, "v=0\r\n", 5 ) && strncmp( (char*)p_peek, "v=0\n", 4 ) && if( strncmp( (char*)p_peek, "v=0\r\n", 5 ) && strncmp( (char*)p_peek, "v=0\n", 4 ) &&
( strcasecmp( p_demux->psz_access, "rtsp" ) || p_peek[0] < 'a' || p_peek[0] > 'z' || p_peek[1] != '=' ) ) ( p_peek[0] < 'a' || p_peek[0] > 'z' || p_peek[1] != '=' ) )
{ {
msg_Warn( p_demux, "SDP module discarded" ); msg_Warn( p_demux, "SDP module discarded" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
}
else
{
var_Create( p_demux, "rtsp-caching", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
}
p_demux->pf_demux = Demux; p_demux->pf_demux = Demux;
p_demux->pf_control= Control; p_demux->pf_control= Control;
...@@ -360,6 +183,56 @@ static int DemuxOpen ( vlc_object_t *p_this ) ...@@ -360,6 +183,56 @@ static int DemuxOpen ( vlc_object_t *p_this )
p_sys->i_length = 0; p_sys->i_length = 0;
p_sys->i_start = 0; p_sys->i_start = 0;
if( ( p_sys->scheduler = BasicTaskScheduler::createNew() ) == NULL )
{
msg_Err( p_demux, "BasicTaskScheduler::createNew failed" );
goto error;
}
if( ( p_sys->env = BasicUsageEnvironment::createNew(*p_sys->scheduler) ) == NULL )
{
msg_Err( p_demux, "BasicUsageEnvironment::createNew failed" );
goto error;
}
if( p_demux->s == NULL && !strcasecmp( p_demux->psz_access, "rtsp" ) )
{
char *psz_url;
char *psz_options;
if( ( p_sys->rtsp = RTSPClient::createNew(*p_sys->env, 1/*verbose*/, "VLC Media Player" ) ) == NULL )
{
msg_Err( p_demux, "RTSPClient::createNew failed (%s)", p_sys->env->getResultMsg() );
goto error;
}
psz_url = (char*)malloc( strlen( p_demux->psz_path ) + 8 );
sprintf( psz_url, "rtsp://%s", p_demux->psz_path );
psz_options = p_sys->rtsp->sendOptionsCmd( psz_url );
if( psz_options )
delete [] psz_options;
p_sdp = (uint8_t*)p_sys->rtsp->describeURL( psz_url );
if( p_sdp == NULL )
{
msg_Err( p_demux, "describeURL failed (%s)", p_sys->env->getResultMsg() );
free( psz_url );
goto error;
}
free( psz_url );
/* malloc-ated copy */
p_sys->p_sdp = strdup( (char*)p_sdp );
delete[] p_sdp;
fprintf( stderr, "sdp=%s\n", p_sys->p_sdp );
}
else if( p_demux->s == NULL && !strcasecmp( p_demux->psz_access, "sdp" ) )
{
p_sys->p_sdp = strdup( p_demux->psz_path );
}
else
{
/* Gather the complete sdp file */ /* Gather the complete sdp file */
i_sdp = 0; i_sdp = 0;
i_sdp_max = 1000; i_sdp_max = 1000;
...@@ -389,35 +262,6 @@ static int DemuxOpen ( vlc_object_t *p_this ) ...@@ -389,35 +262,6 @@ static int DemuxOpen ( vlc_object_t *p_this )
p_sys->p_sdp = (char*)p_sdp; p_sys->p_sdp = (char*)p_sdp;
fprintf( stderr, "sdp=%s\n", p_sys->p_sdp ); fprintf( stderr, "sdp=%s\n", p_sys->p_sdp );
if( ( p_sys->scheduler = BasicTaskScheduler::createNew() ) == NULL )
{
msg_Err( p_demux, "BasicTaskScheduler::createNew failed" );
goto error;
}
if( ( p_sys->env = BasicUsageEnvironment::createNew(*p_sys->scheduler) ) == NULL )
{
msg_Err( p_demux, "BasicUsageEnvironment::createNew failed" );
goto error;
}
if( !strcasecmp( p_demux->psz_access, "rtsp" ) )
{
char *psz_url;
char *psz_options;
if( ( p_sys->rtsp = RTSPClient::createNew(*p_sys->env, 1/*verbose*/, "VLC Media Player" ) ) == NULL )
{
msg_Err( p_demux, "RTSPClient::createNew failed (%s)", p_sys->env->getResultMsg() );
goto error;
}
psz_url = (char*)malloc( strlen( p_demux->psz_path ) + 8 );
sprintf( psz_url, "rtsp://%s", p_demux->psz_path );
psz_options = p_sys->rtsp->sendOptionsCmd( psz_url );
if( psz_options )
delete [] psz_options;
free( psz_url );
} }
if( ( p_sys->ms = MediaSession::createNew(*p_sys->env, p_sys->p_sdp ) ) == NULL ) if( ( p_sys->ms = MediaSession::createNew(*p_sys->env, p_sys->p_sdp ) ) == NULL )
{ {
...@@ -425,8 +269,7 @@ static int DemuxOpen ( vlc_object_t *p_this ) ...@@ -425,8 +269,7 @@ static int DemuxOpen ( vlc_object_t *p_this )
goto error; goto error;
} }
var_Create( p_demux, "rtsp-tcp", VLC_VAR_BOOL|VLC_VAR_DOINHERIT ); b_rtsp_tcp = var_CreateGetBool( p_demux, "rtsp-tcp" );
var_Get( p_demux, "rtsp-tcp", &val );
/* Initialise each media subsession */ /* Initialise each media subsession */
iter = new MediaSubsessionIterator( *p_sys->ms ); iter = new MediaSubsessionIterator( *p_sys->ms );
...@@ -466,7 +309,7 @@ static int DemuxOpen ( vlc_object_t *p_this ) ...@@ -466,7 +309,7 @@ static int DemuxOpen ( vlc_object_t *p_this )
/* Issue the SETUP */ /* Issue the SETUP */
if( p_sys->rtsp ) if( p_sys->rtsp )
{ {
p_sys->rtsp->setupMediaSubsession( *sub, False, val.b_bool ? True : False ); p_sys->rtsp->setupMediaSubsession( *sub, False, b_rtsp_tcp ? True : False );
} }
} }
} }
...@@ -693,7 +536,7 @@ error: ...@@ -693,7 +536,7 @@ error:
/***************************************************************************** /*****************************************************************************
* DemuxClose: * DemuxClose:
*****************************************************************************/ *****************************************************************************/
static void DemuxClose( vlc_object_t *p_this ) static void Close( vlc_object_t *p_this )
{ {
demux_t *p_demux = (demux_t*)p_this; demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
...@@ -775,7 +618,8 @@ static int Demux( demux_t *p_demux ) ...@@ -775,7 +618,8 @@ static int Demux( demux_t *p_demux )
p_sys->i_pcr = i_pcr; p_sys->i_pcr = i_pcr;
es_out_Control( p_demux->out, ES_OUT_SET_PCR, i_pcr ); es_out_Control( p_demux->out, ES_OUT_SET_PCR, i_pcr );
if( p_sys->i_pcr_start <= 0 || p_sys->i_pcr_start > i_pcr ) if( p_sys->i_pcr_start <= 0 || p_sys->i_pcr_start > i_pcr ||
( p_sys->i_length > 0 && i_pcr - p_sys->i_pcr_start > p_sys->i_length ) )
{ {
p_sys->i_pcr_start = i_pcr; p_sys->i_pcr_start = i_pcr;
} }
...@@ -835,6 +679,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) ...@@ -835,6 +679,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
int64_t *pi64; int64_t *pi64;
double *pf, f; double *pf, f;
vlc_bool_t *pb;
switch( i_query ) switch( i_query )
{ {
...@@ -891,6 +736,25 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) ...@@ -891,6 +736,25 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/* Special for access_demux */
case DEMUX_CAN_PAUSE:
case DEMUX_CAN_CONTROL_PACE:
/* TODO */
pb = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
*pb = VLC_FALSE;
return VLC_SUCCESS;
case DEMUX_SET_PAUSE_STATE:
case DEMUX_GET_TITLE_INFO:
case DEMUX_SET_TITLE:
case DEMUX_SET_SEEKPOINT:
return VLC_EGENERIC;
case DEMUX_GET_PTS_DELAY:
pi64 = (int64_t*)va_arg( args, int64_t * );
*pi64 = (int64_t)var_GetInteger( p_demux, "rtsp-caching" ) * I64C(1000);
return VLC_SUCCESS;
default: default:
return VLC_EGENERIC; return VLC_EGENERIC;
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* id3.c: simple id3 tag skipper * id3.c: simple id3 tag skipper
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: id3.c,v 1.8 2004/03/03 11:38:14 fenrir Exp $ * $Id$
* *
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no> * Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
* *
...@@ -30,10 +30,6 @@ ...@@ -30,10 +30,6 @@
#include <vlc/vlc.h> #include <vlc/vlc.h>
#include <vlc/input.h> #include <vlc/input.h>
#include "ninput.h"
#include <sys/types.h>
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
......
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