From e4e9bad7b5e329c3e581314697acbf242e9d9ad3 Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Thu, 18 Sep 2008 20:15:29 +0200 Subject: [PATCH] Fixed broken input_AddSubtitles. It was a big race condition, please understand how multi-thread works before touching core files. Do not throw away the few first subtitles. --- src/input/input.c | 118 +++++++++++++++++++------------------ src/input/input_internal.h | 2 + 2 files changed, 64 insertions(+), 56 deletions(-) diff --git a/src/input/input.c b/src/input/input.c index c61e45fbfa..3623a7307c 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -94,6 +94,8 @@ static void AccessMeta( input_thread_t * p_input, vlc_meta_t *p_meta ); static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_attachment, int i_new, input_attachment_t **pp_new ); +static void SubtitleAdd( input_thread_t *p_input, char *psz_subtitle, bool b_forced ); + /***************************************************************************** * This function creates a new input, and returns a pointer * to its description. On error, it returns NULL. @@ -919,7 +921,7 @@ static void StartTitle( input_thread_t * p_input ) { double f_fps; vlc_value_t val; - int i, i_delay; + int i_delay; char *psz; char *psz_subtitle; int64_t i_length; @@ -1006,45 +1008,29 @@ static void StartTitle( input_thread_t * p_input ) if( psz_subtitle != NULL ) { msg_Dbg( p_input, "forced subtitle: %s", psz_subtitle ); - input_AddSubtitles( p_input, psz_subtitle, false ); + SubtitleAdd( p_input, psz_subtitle, true ); } var_Get( p_input, "sub-autodetect-file", &val ); if( val.b_bool ) { char *psz_autopath = var_GetNonEmptyString( p_input, "sub-autodetect-path" ); - char **subs = subtitles_Detect( p_input, psz_autopath, - p_input->p->input.p_item->psz_uri ); - input_source_t *sub; - i = 0; - if( psz_autopath == NULL ) - psz_autopath = strdup(""); + char **ppsz_subs = subtitles_Detect( p_input, psz_autopath, + p_input->p->input.p_item->psz_uri ); + free( psz_autopath ); - /* Try to autoselect the first autodetected subtitles file - * if no subtitles file was specified */ - if( ( psz_subtitle == NULL ) && subs && subs[0] ) + for( int i = 0; ppsz_subs && ppsz_subs[i]; i++ ) { - input_AddSubtitles( p_input, subs[0], false ); - free( subs[0] ); - i = 1; - } + /* Try to autoselect the first autodetected subtitles file + * if no subtitles file was specified */ + bool b_forced = i == 0 && !psz_subtitle; - /* Then, just add the following subtitles files */ - for( ; subs && subs[i]; i++ ) - { - if( !psz_subtitle || strcmp( psz_subtitle, subs[i] ) ) - { - sub = InputSourceNew( p_input ); - if( !InputSourceInit( p_input, sub, subs[i], "subtitle" ) ) - { - TAB_APPEND( p_input->p->i_slave, p_input->p->slave, sub ); - } - else free( sub ); - } - free( subs[i] ); + if( !psz_subtitle || strcmp( psz_subtitle, ppsz_subs[i] ) ) + SubtitleAdd( p_input, ppsz_subs[i], b_forced ); + + free( ppsz_subs[i] ); } - free( subs ); - free( psz_autopath ); + free( ppsz_subs ); } free( psz_subtitle ); @@ -1927,6 +1913,14 @@ static bool Control( input_thread_t *p_input, int i_type, } break; + case INPUT_CONTROL_ADD_SUBTITLE: + if( val.psz_string ) + { + SubtitleAdd( p_input, val.psz_string, true ); + free( val.psz_string ); + } + break; + case INPUT_CONTROL_ADD_SLAVE: if( val.psz_string ) { @@ -2583,7 +2577,8 @@ static void SlaveSeek( input_thread_t *p_input ) if( demux_Control( in->p_demux, DEMUX_SET_TIME, i_time ) ) { - msg_Err( p_input, "seek failed for slave %d -> EOF", i ); + if( !in->b_eof ) + msg_Err( p_input, "seek failed for slave %d -> EOF", i ); in->b_eof = true; } else @@ -2979,19 +2974,13 @@ static void MRLSections( input_thread_t *p_input, char *psz_source, /***************************************************************************** * input_AddSubtitles: add a subtitles file and enable it *****************************************************************************/ -bool input_AddSubtitles( input_thread_t *p_input, char *psz_subtitle, - bool b_check_extension ) +static void SubtitleAdd( input_thread_t *p_input, char *psz_subtitle, bool b_forced ) { input_source_t *sub; vlc_value_t count; vlc_value_t list; char *psz_path, *psz_extension; - if( b_check_extension && !subtitles_Filter( psz_subtitle ) ) - { - return false; - } - /* if we are provided a subtitle.sub file, * see if we don't have a subtitle.idx and use it instead */ psz_path = strdup( psz_subtitle ); @@ -3000,13 +2989,12 @@ bool input_AddSubtitles( input_thread_t *p_input, char *psz_subtitle, psz_extension = strrchr( psz_path, '.'); if( psz_extension && strcmp( psz_extension, ".sub" ) == 0 ) { - FILE *f; + struct stat st; strcpy( psz_extension, ".idx" ); - /* FIXME: a portable wrapper for stat() or access() would be more suited */ - if( ( f = utf8_fopen( psz_path, "rt" ) ) ) + + if( !utf8_stat( psz_path, &st ) ) { - fclose( f ); msg_Dbg( p_input, "using %s subtitles file instead of %s", psz_path, psz_subtitle ); strcpy( psz_subtitle, psz_path ); @@ -3018,27 +3006,45 @@ bool input_AddSubtitles( input_thread_t *p_input, char *psz_subtitle, var_Change( p_input, "spu-es", VLC_VAR_CHOICESCOUNT, &count, NULL ); sub = InputSourceNew( p_input ); - if( !InputSourceInit( p_input, sub, psz_subtitle, "subtitle" ) ) + if( InputSourceInit( p_input, sub, psz_subtitle, "subtitle" ) ) + { + free( sub ); + return; + } + TAB_APPEND( p_input->p->i_slave, p_input->p->slave, sub ); + + /* Select the ES */ + if( b_forced && !var_Change( p_input, "spu-es", VLC_VAR_GETLIST, &list, NULL ) ) { - TAB_APPEND( p_input->p->i_slave, p_input->p->slave, sub ); + if( count.i_int == 0 ) + count.i_int++; + /* if it was first one, there is disable too */ - /* Select the ES */ - if( !var_Change( p_input, "spu-es", VLC_VAR_GETLIST, &list, NULL ) ) + if( count.i_int < list.p_list->i_count ) { - if( count.i_int == 0 ) - count.i_int++; - /* if it was first one, there is disable too */ + int i_id = list.p_list->p_values[count.i_int].i_int; + es_out_id_t *p_es = input_EsOutGetFromID( p_input->p->p_es_out, i_id ); - if( count.i_int < list.p_list->i_count ) - { - input_ControlPush( p_input, INPUT_CONTROL_SET_ES, - &list.p_list->p_values[count.i_int] ); - } - var_Change( p_input, "spu-es", VLC_VAR_FREELIST, &list, NULL ); + es_out_Control( p_input->p->p_es_out, ES_OUT_SET_DEFAULT, p_es ); + es_out_Control( p_input->p->p_es_out, ES_OUT_SET_ES, p_es ); } + var_Change( p_input, "spu-es", VLC_VAR_FREELIST, &list, NULL ); } - else free( sub ); +} + +bool input_AddSubtitles( input_thread_t *p_input, char *psz_subtitle, + bool b_check_extension ) +{ + vlc_value_t val; + + if( b_check_extension && !subtitles_Filter( psz_subtitle ) ) + return false; + + assert( psz_subtitle != NULL ); + val.psz_string = strdup( psz_subtitle ); + if( val.psz_string ) + input_ControlPush( p_input, INPUT_CONTROL_ADD_SUBTITLE, &val ); return true; } diff --git a/src/input/input_internal.h b/src/input/input_internal.h index 0372f66cb9..c12b0b9c70 100644 --- a/src/input/input_internal.h +++ b/src/input/input_internal.h @@ -197,6 +197,8 @@ enum input_control_e INPUT_CONTROL_ADD_SLAVE, + INPUT_CONTROL_ADD_SUBTITLE, + INPUT_CONTROL_SET_RECORD_STATE, }; -- 2.39.2