X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finput%2Finput.c;h=35da58bd31014e589b6593654d4653b3310b4210;hb=4d85871d1b29265a6cc5744677f0f0bb9bfac20f;hp=4672cd7e1da49252b92fb8b6856b89d2a9631bac;hpb=9658acc090c330151e4069066f47eae18afe149a;p=vlc diff --git a/src/input/input.c b/src/input/input.c index 4672cd7e1d..35da58bd31 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -53,6 +53,7 @@ #include #include #include +#include #ifdef HAVE_SYS_STAT_H # include @@ -110,9 +111,6 @@ static void SubtitleAdd( input_thread_t *p_input, char *psz_subtitle, bool b_for 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. @@ -247,18 +245,6 @@ void input_Stop( input_thread_t *p_input, bool b_abort ) input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL ); } -input_resource_t *input_DetachResource( input_thread_t *p_input ) -{ - assert( p_input->b_dead ); - - input_resource_SetInput( p_input->p->p_resource, NULL ); - - input_resource_t *p_resource = input_resource_Detach( p_input->p->p_resource ); - p_input->p->p_sout = NULL; - - return p_resource; -} - /** * Get the item from an input thread * FIXME it does not increase ref count of the item. @@ -399,9 +385,15 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, /* */ if( p_resource ) - p_input->p->p_resource = p_resource; + { + p_input->p->p_resource_private = NULL; + p_input->p->p_resource = input_resource_Hold( p_resource ); + } else - p_input->p->p_resource = input_resource_New(); + { + p_input->p->p_resource_private = input_resource_New( VLC_OBJECT( p_input ) ); + p_input->p->p_resource = input_resource_Hold( p_input->p->p_resource_private ); + } input_resource_SetInput( p_input->p->p_resource, p_input ); /* Init control buffer */ @@ -510,7 +502,9 @@ static void Destructor( input_thread_t * p_input ) es_out_Delete( p_input->p->p_es_out_display ); if( p_input->p->p_resource ) - input_resource_Delete( p_input->p->p_resource ); + input_resource_Release( p_input->p->p_resource ); + if( p_input->p->p_resource_private ) + input_resource_Release( p_input->p->p_resource_private ); vlc_gc_decref( p_input->p->p_item ); @@ -1142,13 +1136,13 @@ static void UpdatePtsDelay( input_thread_t *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 ) { int i_es_out_mode; - vlc_value_t val; + vlc_list_t list; /* Compute correct pts_delay */ UpdatePtsDelay( p_input ); @@ -1157,22 +1151,31 @@ static void InitPrograms( input_thread_t * p_input ) i_es_out_mode = ES_OUT_MODE_AUTO; if( p_input->p->p_sout ) { + char *prgms; + if( var_GetBool( p_input, "sout-all" ) ) { i_es_out_mode = ES_OUT_MODE_ALL; } else + if( (prgms = var_GetNonEmptyString( p_input, "programs" )) != NULL ) { - var_Get( p_input, "programs", &val ); - if( val.p_list && val.p_list->i_count ) + char *buf; + + TAB_INIT( list.i_count, list.p_values ); + for( const char *prgm = strtok_r( prgms, ",", &buf ); + prgm != NULL; + prgm = strtok_r( NULL, ",", &buf ) ) { + vlc_value_t val = { .i_int = atoi( prgm ) }; + INSERT_ELEM( list.p_values, list.i_count, list.i_count, val ); + } + + if( list.i_count > 0 ) i_es_out_mode = ES_OUT_MODE_PARTIAL; /* Note : we should remove the "program" callback. */ - } - else - { - var_FreeList( &val, NULL ); - } + + free( prgms ); } } es_out_SetMode( p_input->p->p_es_out, i_es_out_mode ); @@ -1185,12 +1188,13 @@ static void InitPrograms( input_thread_t * p_input ) else if( i_es_out_mode == ES_OUT_MODE_PARTIAL ) { demux_Control( p_input->p->input.p_demux, DEMUX_SET_GROUP, -1, - val.p_list ); + &list ); + TAB_CLEAN( list.i_count, list.p_values ); } else { demux_Control( p_input->p->input.p_demux, DEMUX_SET_GROUP, - (int) var_GetInteger( p_input, "program" ), NULL ); + es_out_GetGroupForced( p_input->p->p_es_out ), NULL ); } } @@ -1307,6 +1311,8 @@ error: input_resource_RequestSout( p_input->p->p_resource, p_input->p->p_sout, NULL ); input_resource_SetInput( p_input->p->p_resource, NULL ); + if( p_input->p->p_resource_private ) + input_resource_Terminate( p_input->p->p_resource_private ); } if( !p_input->b_preparsing && libvlc_stats( p_input ) ) @@ -1426,6 +1432,8 @@ static void End( input_thread_t * p_input ) input_resource_RequestSout( p_input->p->p_resource, p_input->p->p_sout, NULL ); input_resource_SetInput( p_input->p->p_resource, NULL ); + if( p_input->p->p_resource_private ) + input_resource_Terminate( p_input->p->p_resource_private ); } /***************************************************************************** @@ -1773,63 +1781,10 @@ static bool Control( 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 ) @@ -2181,7 +2136,7 @@ static bool Control( input_thread_t *p_input, if( bookmark.i_time_offset < 0 && bookmark.i_byte_offset < 0 ) { - msg_Err( p_input, "invalid bookmark %d", val.i_int ); + msg_Err( p_input, "invalid bookmark %"PRId64, val.i_int ); break; } @@ -2382,46 +2337,6 @@ static int InputSourceInit( input_thread_t *p_input, /* 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 ) @@ -3093,13 +3008,12 @@ void input_SplitMRL( const char **ppsz_access, const char **ppsz_demux, *psz_path = '\0'; psz_path += 3; /* skips "://" */ - /* Separate access from demux (/://) */ psz_access = psz_dup; - /* We really don't want module name substitution here! */ if( psz_access[0] == '$' ) psz_access++; + /* Separate access from demux (/://) */ char *p = strchr( psz_access, '/' ); if( p ) { @@ -3108,6 +3022,12 @@ void input_SplitMRL( const char **ppsz_access, const char **ppsz_demux, 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 { @@ -3248,14 +3168,19 @@ static void SubtitleAdd( input_thread_t *p_input, char *psz_subtitle, bool b_for free( psz_path ); } + char *url = make_URI( psz_subtitle, "file" ); + 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 */