static void input_ChangeState( input_thread_t *p_input, int i_state ); /* TODO fix name */
-/* Do not let a pts_delay from access/demux go beyong 60s */
-#define INPUT_PTS_DELAY_MAX INT64_C(60000000)
-
#undef input_Create
/**
* Create a new input_thread_t.
if( !p_input->p )
return NULL;
+ /* Parse input options */
+ vlc_mutex_lock( &p_item->lock );
+ assert( (int)p_item->optflagc == p_item->i_options );
+ for( i = 0; i < p_item->i_options; i++ )
+ var_OptionParse( VLC_OBJECT(p_input), p_item->ppsz_options[i],
+ !!(p_item->optflagv[i] & VLC_INPUT_OPTION_TRUSTED) );
+ vlc_mutex_unlock( &p_item->lock );
+
p_input->b_preparsing = b_quick;
p_input->psz_header = psz_header ? strdup( psz_header ) : NULL;
p_input->p->title = NULL;
p_input->p->i_title_offset = p_input->p->i_seekpoint_offset = 0;
p_input->p->i_state = INIT_S;
- p_input->p->i_rate = INPUT_RATE_DEFAULT
- / var_InheritFloat( p_input, "rate" );
+ double f_rate = var_InheritFloat( p_input, "rate" );
+ if( f_rate <= 0. )
+ {
+ msg_Warn( p_input, "Negative or zero rate values are forbidden" );
+ f_rate = 1.;
+ }
+ p_input->p->i_rate = INPUT_RATE_DEFAULT / f_rate;
p_input->p->b_recording = false;
memset( &p_input->p->bookmark, 0, sizeof(p_input->p->bookmark) );
TAB_INIT( p_input->p->i_bookmark, p_input->p->pp_bookmark );
p_input->p->i_control = 0;
p_input->p->b_abort = false;
- /* Parse input options */
- vlc_mutex_lock( &p_item->lock );
- assert( (int)p_item->optflagc == p_item->i_options );
- for( i = 0; i < p_item->i_options; i++ )
- var_OptionParse( VLC_OBJECT(p_input), p_item->ppsz_options[i],
- !!(p_item->optflagv[i] & VLC_INPUT_OPTION_TRUSTED) );
- vlc_mutex_unlock( &p_item->lock );
-
/* Create Object Variables for private use only */
input_ConfigVarInit( p_input );
/* */
es_out_SetDelay( p_input->p->p_es_out_display, AUDIO_ES, i_audio_delay );
es_out_SetDelay( p_input->p->p_es_out_display, SPU_ES, i_spu_delay );
- es_out_SetJitter( p_input->p->p_es_out, i_pts_delay, i_cr_average );
+ es_out_SetJitter( p_input->p->p_es_out, i_pts_delay, 0, i_cr_average );
}
static void InitPrograms( input_thread_t * p_input )
break;
case INPUT_CONTROL_SET_RATE:
- case INPUT_CONTROL_SET_RATE_SLOWER:
- case INPUT_CONTROL_SET_RATE_FASTER:
{
- int i_rate;
- int i_rate_sign;
-
/* Get rate and direction */
- if( i_type == INPUT_CONTROL_SET_RATE )
- {
- i_rate = abs( val.i_int );
- i_rate_sign = val.i_int < 0 ? -1 : 1;
- }
- else
- {
- static const int ppi_factor[][2] = {
- {1,64}, {1,32}, {1,16}, {1,8}, {1,4}, {1,3}, {1,2}, {2,3},
- {1,1},
- {3,2}, {2,1}, {3,1}, {4,1}, {8,1}, {16,1}, {32,1}, {64,1},
- {0,0}
- };
- int i_error;
- int i_idx;
- int i;
-
- i_rate_sign = p_input->p->i_rate < 0 ? -1 : 1;
-
- i_error = INT_MAX;
- i_idx = -1;
- for( i = 0; ppi_factor[i][0] != 0; i++ )
- {
- const int i_test_r = INPUT_RATE_DEFAULT * ppi_factor[i][0] / ppi_factor[i][1];
- const int i_test_e = abs( abs( p_input->p->i_rate ) - i_test_r );
- if( i_test_e < i_error )
- {
- i_idx = i;
- i_error = i_test_e;
- }
- }
-
- assert( i_idx >= 0 && ppi_factor[i_idx][0] != 0 );
-
- if( i_type == INPUT_CONTROL_SET_RATE_SLOWER )
- {
- if( ppi_factor[i_idx+1][0] > 0 )
- i_rate = INPUT_RATE_DEFAULT * ppi_factor[i_idx+1][0] / ppi_factor[i_idx+1][1];
- else
- i_rate = INPUT_RATE_MAX+1;
- }
- else
- {
- assert( i_type == INPUT_CONTROL_SET_RATE_FASTER );
- if( i_idx > 0 )
- i_rate = INPUT_RATE_DEFAULT * ppi_factor[i_idx-1][0] / ppi_factor[i_idx-1][1];
- else
- i_rate = INPUT_RATE_MIN-1;
- }
- }
+ int i_rate = abs( val.i_int );
+ int i_rate_sign = val.i_int < 0 ? -1 : 1;
/* Check rate bound */
if( i_rate < INPUT_RATE_MIN )
/* Split uri */
input_SplitMRL( &psz_access, &psz_demux, &psz_path, psz_dup );
- /* FIXME: file:// handling plugins do not support URIs properly...
- * So we pre-decode the URI to a path for them. Note that we do not do it
- * for non-standard VLC-specific schemes. */
- if( !strcmp( psz_access, "file" ) )
- {
- if( psz_path[0] != '/'
-#if (DIR_SEP_CHAR != '/')
- /* We accept invalid URIs too. */
- && psz_path[0] != DIR_SEP_CHAR
-#endif
- )
- { /* host specified -> only localhost is supported */
- static const size_t i_localhost = sizeof("localhost")-1;
- if( strncmp( psz_path, "localhost/", i_localhost + 1) != 0 )
- {
- msg_Err( p_input, "cannot open remote file `%s://%s'",
- psz_access, psz_path );
- msg_Info( p_input, "Did you mean `%s:///%s'?",
- psz_access, psz_path );
- goto error;
- }
- psz_path += i_localhost;
- }
- /* Remove HTML anchor if present (not supported). */
- char *p = strchr( psz_path, '#' );
- if( p )
- *p = '\0';
- /* Then URI-decode the path. */
- decode_URI( psz_path );
-#if defined( WIN32 ) && !defined( UNDER_CE )
- /* Strip leading slash in front of the drive letter */
- psz_path++;
-#endif
-#if (DIR_SEP_CHAR != '/')
- /* Turn slashes into anti-slashes */
- for( char *s = strchr( psz_path, '/' ); s; s = strchr( s + 1, '/' ) )
- *s = DIR_SEP_CHAR;
-#endif
- }
-
msg_Dbg( p_input, "`%s' gives access `%s' demux `%s' path `%s'",
psz_mrl, psz_access, psz_demux, psz_path );
if( !p_input->b_preparsing )
psz_demux = in->p_access->psz_demux;
}
- {
- /* Take access/stream redirections into account */
- char *psz_real_path;
- char *psz_buf = NULL;
- if( in->p_stream->psz_path )
- {
- const char *psz_a, *psz_d;
- psz_buf = strdup( in->p_stream->psz_path );
- input_SplitMRL( &psz_a, &psz_d, &psz_real_path, psz_buf );
- }
- else
- {
- psz_real_path = psz_path;
- }
- in->p_demux = demux_New( p_input, p_input, psz_access, psz_demux,
- psz_real_path,
- in->p_stream, p_input->p->p_es_out,
- p_input->b_preparsing );
- free( psz_buf );
- }
+ in->p_demux = demux_New( p_input, p_input, psz_access, psz_demux,
+ /* Take access/stream redirections into account: */
+ in->p_stream->psz_path ? in->p_stream->psz_path : psz_path,
+ in->p_stream, p_input->p->p_es_out,
+ p_input->b_preparsing );
if( in->p_demux == NULL )
{
* MRLSplit: parse the access, demux and url part of the
* Media Resource Locator.
*****************************************************************************/
-void input_SplitMRL( const char **ppsz_access, const char **ppsz_demux, char **ppsz_path,
- char *psz_dup )
+void input_SplitMRL( const char **ppsz_access, const char **ppsz_demux,
+ char **ppsz_path, char *psz_dup )
{
- char *psz_access = NULL;
- char *psz_demux = NULL;
+ const char *psz_access;
+ const char *psz_demux = "";
char *psz_path;
/* Either there is an access/demux specification before ://
*psz_path = '\0';
psz_path += 3; /* skips "://" */
- /* Separate access from demux (<access>/<demux>://<path>) */
psz_access = psz_dup;
- psz_demux = strchr( psz_access, '/' );
- if( psz_demux )
- *psz_demux++ = '\0';
-
/* We really don't want module name substitution here! */
if( psz_access[0] == '$' )
psz_access++;
- if( psz_demux && psz_demux[0] == '$' )
- psz_demux++;
+
+ /* Separate access from demux (<access>/<demux>://<path>) */
+ char *p = strchr( psz_access, '/' );
+ if( p )
+ {
+ *p = '\0';
+ psz_demux = p + 1;
+ if( psz_demux[0] == '$' )
+ psz_demux++;
+ }
+
+ /* Remove HTML anchor if present (not supported).
+ * The hash symbol itself should be URI-encoded. */
+ p = strchr( psz_path, '#' );
+ if( p )
+ *p = '\0';
}
else
{
+#ifndef NDEBUG
+ fprintf( stderr, "%s(\"%s\"): not a valid URI!\n", __func__,
+ psz_dup );
+#endif
psz_path = psz_dup;
+ psz_access = "";
}
- *ppsz_access = psz_access ? psz_access : "";
- *ppsz_demux = psz_demux ? psz_demux : "";
+
+ *ppsz_access = psz_access;
+ *ppsz_demux = psz_demux;
*ppsz_path = psz_path;
}
free( psz_path );
}
+ char *url = make_URI( psz_subtitle );
+
var_Change( p_input, "spu-es", VLC_VAR_CHOICESCOUNT, &count, NULL );
sub = InputSourceNew( p_input );
- if( !sub || InputSourceInit( p_input, sub, psz_subtitle, "subtitle" ) )
+ if( !sub || !url
+ || InputSourceInit( p_input, sub, url, "subtitle" ) )
{
free( sub );
+ free( url );
return;
}
+ free( url );
TAB_APPEND( p_input->p->i_slave, p_input->p->slave, sub );
/* Select the ES */