X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finput%2Finput.c;h=b43df74f2120254915aef9667467f07bbd77e015;hb=9d4515ac4873076af85af33270d126818c0e8639;hp=0094846a61eb8528179ca959415a9522e776e3b2;hpb=3756098af4a7256280536fde899a7c97316b7a3d;p=vlc diff --git a/src/input/input.c b/src/input/input.c index 0094846a61..b43df74f21 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -85,7 +85,7 @@ static void UpdateGenericFromAccess( input_thread_t * ); static int UpdateTitleSeekpointFromDemux( input_thread_t * ); static void UpdateGenericFromDemux( input_thread_t * ); -static void MRLSections( input_thread_t *, char *, int *, int *, int *, int *); +static void MRLSections( const char *, int *, int *, int *, int *); static input_source_t *InputSourceNew( input_thread_t *); static int InputSourceInit( input_thread_t *, input_source_t *, @@ -292,19 +292,15 @@ input_item_t *input_GetItem( input_thread_t *p_input ) static void ObjectKillChildrens( input_thread_t *p_input, vlc_object_t *p_obj ) { vlc_list_t *p_list; - int i; /* FIXME ObjectKillChildrens seems a very bad idea in fact */ - i = vlc_internals( p_obj )->i_object_type; - if( i == VLC_OBJECT_VOUT ||i == VLC_OBJECT_AOUT || - p_obj == VLC_OBJECT(p_input->p->p_sout) || - i == VLC_OBJECT_DECODER ) + if( p_obj == VLC_OBJECT(p_input->p->p_sout) ) return; vlc_object_kill( p_obj ); p_list = vlc_list_children( p_obj ); - for( i = 0; i < p_list->i_count; i++ ) + for( int i = 0; i < p_list->i_count; i++ ) ObjectKillChildrens( p_input, p_list->p_values[i].p_object ); vlc_list_release( p_list ); } @@ -319,13 +315,11 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, const char *psz_header, bool b_quick, input_resource_t *p_resource ) { - static const char input_name[] = "input"; input_thread_t *p_input = NULL; /* thread descriptor */ int i; /* Allocate descriptor */ - p_input = vlc_custom_create( p_parent, sizeof( *p_input ), - VLC_OBJECT_INPUT, input_name ); + p_input = vlc_custom_create( p_parent, sizeof( *p_input ), "input" ); if( p_input == NULL ) return NULL; @@ -623,6 +617,7 @@ static void MainLoopDemux( input_thread_t *p_input, bool *pb_changed, bool *pb_d { msg_Dbg( p_input, "EOF reached" ); p_input->p->input.b_eof = true; + es_out_Eos(p_input->p->p_es_out); } else if( i_ret < 0 ) { @@ -941,6 +936,7 @@ static void InitTitle( input_thread_t * p_input ) if( p_input->b_preparsing ) return; + vlc_mutex_lock( &p_input->p->p_item->lock ); /* Create global title (from master) */ p_input->p->i_title = p_master->i_title; p_input->p->title = p_master->title; @@ -957,6 +953,7 @@ static void InitTitle( input_thread_t * p_input ) p_input->p->b_can_pace_control = p_master->b_can_pace_control; p_input->p->b_can_pause = p_master->b_can_pause; p_input->p->b_can_rate_control = p_master->b_can_rate_control; + vlc_mutex_unlock( &p_input->p->p_item->lock ); } static void StartTitle( input_thread_t * p_input ) @@ -2359,9 +2356,7 @@ static int InputSourceInit( input_thread_t *p_input, input_source_t *in, const char *psz_mrl, const char *psz_forced_demux, bool b_in_can_fail ) { - const char *psz_access; - const char *psz_demux; - char *psz_path; + const char *psz_access, *psz_demux, *psz_path, *psz_anchor; char *psz_var_demux = NULL; double f_fps; @@ -2372,22 +2367,15 @@ static int InputSourceInit( input_thread_t *p_input, goto error; /* Split uri */ - input_SplitMRL( &psz_access, &psz_demux, &psz_path, psz_dup ); + input_SplitMRL( &psz_access, &psz_demux, &psz_path, &psz_anchor, psz_dup ); 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 ) { - /* Hack to allow udp://@:port syntax */ - if( !psz_access || - (strncmp( psz_access, "udp", 3 ) && - strncmp( psz_access, "rtp", 3 )) ) - { - /* Find optional titles and seekpoints */ - MRLSections( p_input, psz_path, &in->i_title_start, &in->i_title_end, + /* Find optional titles and seekpoints */ + MRLSections( psz_anchor, &in->i_title_start, &in->i_title_end, &in->i_seekpoint_start, &in->i_seekpoint_end ); - } - if( psz_forced_demux && *psz_forced_demux ) { psz_demux = psz_forced_demux; @@ -2744,8 +2732,7 @@ static void InputSourceMeta( input_thread_t *p_input, return; demux_meta_t *p_demux_meta = - vlc_custom_create( p_demux, sizeof( *p_demux_meta ), - VLC_OBJECT_GENERIC, "demux meta" ); + vlc_custom_create( p_demux, sizeof( *p_demux_meta ), "demux meta" ); if( !p_demux_meta ) return; p_demux_meta->p_demux = p_demux; @@ -3036,144 +3023,115 @@ static void input_ChangeState( input_thread_t *p_input, int i_state ) * 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 **access, const char **demux, + const char **path, const char **anchor, char *buf ) { char *p; /* Separate from [/]:// */ - p = strstr( psz_dup, "://" ); + p = strstr( buf, "://" ); if( p != NULL ) { *p = '\0'; p += 3; /* skips "://" */ - *ppsz_path = p; + *path = p; /* Remove HTML anchor if present (not supported). * The hash symbol itself should be URI-encoded. */ p = strchr( p, '#' ); - if( p ) - *p = '\0'; + if( p != NULL ) + { + *(p++) = '\0'; + *anchor = p; + } + else + *anchor = ""; } else { #ifndef NDEBUG fprintf( stderr, "%s(\"%s\") probably not a valid URI!\n", __func__, - psz_dup ); + buf ); #endif /* Note: this is a valid non const pointer to "": */ - *ppsz_path = psz_dup + strlen( psz_dup ); + *path = buf + strlen( buf ); } /* Separate access from demux */ - p = strchr( psz_dup, '/' ); + p = strchr( buf, '/' ); if( p != NULL ) { *(p++) = '\0'; if( p[0] == '$' ) p++; - *ppsz_demux = p; + *demux = p; } else - *ppsz_demux = ""; + *demux = ""; /* We really don't want module name substitution here! */ - p = psz_dup; + p = buf; if( p[0] == '$' ) p++; - *ppsz_access = p; + *access = p; } -static inline bool next(char ** src) +static const char *MRLSeekPoint( const char *str, int *title, int *chapter ) { char *end; - errno = 0; - long result = strtol( *src, &end, 0 ); - if( errno != 0 || result >= LONG_MAX || result <= LONG_MIN || - end == *src ) + unsigned long u; + + /* Look for the title */ + u = strtoul( str, &end, 0 ); + *title = (str == end || u > (unsigned long)INT_MAX) ? -1 : (int)u; + str = end; + + /* Look for the chapter */ + if( *str == ':' ) { - return false; + str++; + u = strtoul( str, &end, 0 ); + *chapter = (str == end || u > (unsigned long)INT_MAX) ? -1 : (int)u; + str = end; } - *src = end; - return true; + else + *chapter = -1; + + return str; } + /***************************************************************************** * MRLSections: parse title and seekpoint info from the Media Resource Locator. * * Syntax: - * [url][@[title-start][:chapter-start][-[title-end][:chapter-end]]] + * [url][@[title_start][:chapter_start][-[title_end][:chapter_end]]] *****************************************************************************/ -static void MRLSections( input_thread_t *p_input, char *psz_source, +static void MRLSections( const char *p, int *pi_title_start, int *pi_title_end, int *pi_chapter_start, int *pi_chapter_end ) { - char *psz, *psz_end, *psz_next, *psz_check; - - *pi_title_start = *pi_title_end = -1; - *pi_chapter_start = *pi_chapter_end = -1; + *pi_title_start = *pi_title_end = *pi_chapter_start = *pi_chapter_end = -1; - /* Start by parsing titles and chapters */ - if( !psz_source || !( psz = strrchr( psz_source, '@' ) ) ) return; + int title_start, chapter_start, title_end, chapter_end; + if( *p != '-' ) + p = MRLSeekPoint( p, &title_start, &chapter_start ); + else + title_start = chapter_start = -1; - /* Check we are really dealing with a title/chapter section */ - psz_check = psz + 1; - if( !*psz_check ) return; - if( isdigit(*psz_check) ) - if(!next(&psz_check)) return; - if( *psz_check != ':' && *psz_check != '-' && *psz_check ) return; - if( *psz_check == ':' && ++psz_check ) - { - if( isdigit(*psz_check) ) - if(!next(&psz_check)) return; - } - if( *psz_check != '-' && *psz_check ) return; - if( *psz_check == '-' && ++psz_check ) - { - if( isdigit(*psz_check) ) - if(!next(&psz_check)) return; - } - if( *psz_check != ':' && *psz_check ) return; - if( *psz_check == ':' && ++psz_check ) - { - if( isdigit(*psz_check) ) - if(!next(&psz_check)) return; - } - if( *psz_check ) return; - - /* Separate start and end */ - *psz++ = 0; - if( ( psz_end = strchr( psz, '-' ) ) ) *psz_end++ = 0; - - /* Look for the start title */ - *pi_title_start = strtol( psz, &psz_next, 0 ); - if( !*pi_title_start && psz == psz_next ) *pi_title_start = -1; - *pi_title_end = *pi_title_start; - psz = psz_next; - - /* Look for the start chapter */ - if( *psz ) psz++; - *pi_chapter_start = strtol( psz, &psz_next, 0 ); - if( !*pi_chapter_start && psz == psz_next ) *pi_chapter_start = -1; - *pi_chapter_end = *pi_chapter_start; - - if( psz_end ) - { - /* Look for the end title */ - *pi_title_end = strtol( psz_end, &psz_next, 0 ); - if( !*pi_title_end && psz_end == psz_next ) *pi_title_end = -1; - psz_end = psz_next; + if( *p == '-' ) + p = MRLSeekPoint( p + 1, &title_end, &chapter_end ); + else + title_end = chapter_end = -1; - /* Look for the end chapter */ - if( *psz_end ) psz_end++; - *pi_chapter_end = strtol( psz_end, &psz_next, 0 ); - if( !*pi_chapter_end && psz_end == psz_next ) *pi_chapter_end = -1; - } + if( *p ) /* syntax error */ + return; - msg_Dbg( p_input, "source=`%s' title=%d/%d seekpoint=%d/%d", - psz_source, *pi_title_start, *pi_chapter_start, - *pi_title_end, *pi_chapter_end ); + *pi_title_start = title_start; + *pi_title_end = title_end; + *pi_chapter_start = chapter_start; + *pi_chapter_end = chapter_end; } /*****************************************************************************