X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finput%2Finput.c;h=dcdf564644bad109b4c8616db08127e6ebbb9ad6;hb=2ecc8ed4e1ded5290fdcfd3226c768fcbfdd48e8;hp=c9b2ef6b5d76e5385fce1e4ad83e64fb1bc9e404;hpb=56aa04bd7e0d414afd2c076d64ba3d407fa0c686;p=vlc diff --git a/src/input/input.c b/src/input/input.c index c9b2ef6b5d..dcdf564644 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -162,7 +162,6 @@ input_thread_t *__input_CreateThread( vlc_object_t *p_parent, vlc_mutex_lock( &p_item->lock ); for( i = 0; i < p_item->i_options; i++ ) { -// msg_Dbg( p_input, "option: %s", p_item->ppsz_options[i] ); ParseOption( p_input, p_item->ppsz_options[i] ); } vlc_mutex_unlock( &p_item->lock ); @@ -183,7 +182,7 @@ input_thread_t *__input_CreateThread( vlc_object_t *p_parent, psz_parser = val.psz_string; while( (psz_start = strchr( psz_parser, '{' ) ) ) { - seekpoint_t seekpoint; + seekpoint_t *p_seekpoint = vlc_seekpoint_New(); char backup; psz_start++; psz_end = strchr( psz_start, '}' ); @@ -193,30 +192,28 @@ input_thread_t *__input_CreateThread( vlc_object_t *p_parent, *psz_parser = 0; *psz_end = ','; - seekpoint.psz_name = 0; - seekpoint.i_byte_offset = 0; - seekpoint.i_time_offset = 0; while( (psz_end = strchr( psz_start, ',' ) ) ) { *psz_end = 0; if( !strncmp( psz_start, "name=", 5 ) ) { - seekpoint.psz_name = psz_start + 5; + p_seekpoint->psz_name = psz_start + 5; } else if( !strncmp( psz_start, "bytes=", 6 ) ) { - seekpoint.i_byte_offset = atoll(psz_start + 6); + p_seekpoint->i_byte_offset = atoll(psz_start + 6); } else if( !strncmp( psz_start, "time=", 5 ) ) { - seekpoint.i_time_offset = atoll(psz_start + 5) * 1000000; + p_seekpoint->i_time_offset = atoll(psz_start + 5) * 1000000; } psz_start = psz_end + 1; } msg_Dbg( p_input, "adding bookmark: %s, bytes="I64Fd", time="I64Fd, - seekpoint.psz_name, seekpoint.i_byte_offset, - seekpoint.i_time_offset ); - input_Control( p_input, INPUT_ADD_BOOKMARK, &seekpoint ); + p_seekpoint->psz_name, p_seekpoint->i_byte_offset, + p_seekpoint->i_time_offset ); + input_Control( p_input, INPUT_ADD_BOOKMARK, p_seekpoint ); + vlc_seekpoint_Delete( p_seekpoint ); *psz_parser = backup; } free( val.psz_string ); @@ -611,16 +608,22 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick ) int i_es_out_mode; int i, i_delay; - /* Initialize optional stream output. (before access/demuxer) */ + /* Initialize optional stream output. (before access/demuxer) + * XXX: we add a special case if the uri starts by vlc. + * else 'vlc in.file --sout "" vlc:quit' cannot work (the output will + * be destroyed in case of a file). + * (this will break playing of file starting by 'vlc:' but I don't + * want to add more logic, just force file by file:// or code it ;) + */ if( !b_quick ) { psz = var_GetString( p_input, "sout" ); - if( *psz ) + if( *psz && strncasecmp( p_input->input.p_item->psz_uri, "vlc:", 4 ) ) { p_input->p_sout = sout_NewInstance( p_input, psz ); if( p_input->p_sout == NULL ) { - msg_Err( p_input, "cannot start stream output instance," \ + msg_Err( p_input, "cannot start stream output instance, " \ "aborting" ); free( psz ); return VLC_EGENERIC; @@ -712,7 +715,7 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick ) { vlc_value_t s; - msg_Dbg( p_input, "start-time: %ds", + msg_Dbg( p_input, "starting at time: %ds", (int)( p_input->i_start / I64C(1000000) ) ); s.i_time = p_input->i_start; @@ -837,7 +840,7 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick ) break; } - msg_Dbg( p_input, "adding slave '%s'", psz ); + msg_Dbg( p_input, "adding slave input '%s'", psz ); slave = InputSourceNew( p_input ); if( !InputSourceInit( p_input, slave, psz, NULL, VLC_FALSE ) ) { @@ -909,6 +912,14 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick ) { p_input->b_out_pace_control = VLC_TRUE; } + + if( p_input->b_can_pace_control && p_input->b_out_pace_control ) + { + /* We don't want a high input priority here or we'll + * end-up sucking up all the CPU time */ + vlc_thread_set_priority( p_input, VLC_THREAD_PRIORITY_LOW ); + } + msg_Dbg( p_input, "starting in %s mode", p_input->b_out_pace_control ? "asynch" : "synch" ); } @@ -1143,8 +1154,9 @@ static void ControlReduce( input_thread_t *p_input ) const int i_ct = p_input->control[i].i_type; /* XXX We can't merge INPUT_CONTROL_SET_ES */ - msg_Dbg( p_input, "[%d/%d] l=%d c=%d", i, p_input->i_control, +/* msg_Dbg( p_input, "[%d/%d] l=%d c=%d", i, p_input->i_control, i_lt, i_ct ); +*/ if( i_lt == i_ct && ( i_ct == INPUT_CONTROL_SET_STATE || i_ct == INPUT_CONTROL_SET_RATE || @@ -1156,7 +1168,7 @@ static void ControlReduce( input_thread_t *p_input ) i_ct == INPUT_CONTROL_SET_BOOKMARK ) ) { int j; - msg_Dbg( p_input, "merged at %d", i ); +// msg_Dbg( p_input, "merged at %d", i ); /* Remove the i-1 */ for( j = i; j < p_input->i_control; j++ ) p_input->control[j-1] = p_input->control[j]; @@ -1182,7 +1194,7 @@ static vlc_bool_t Control( input_thread_t *p_input, int i_type, switch( i_type ) { case INPUT_CONTROL_SET_DIE: - msg_Dbg( p_input, "control: INPUT_CONTROL_SET_DIE proceed" ); + msg_Dbg( p_input, "control: stopping input" ); /* Mark all submodules to die */ if( p_input->input.p_access ) p_input->input.p_access->b_die = VLC_TRUE; @@ -1210,6 +1222,9 @@ static vlc_bool_t Control( input_thread_t *p_input, int i_type, } if( f_pos < 0.0 ) f_pos = 0.0; if( f_pos > 1.0 ) f_pos = 1.0; + /* Reset the decoders states and clock synch (before calling the demuxer */ + es_out_Control( p_input->p_es_out, ES_OUT_RESET_PCR ); + input_EsOutDiscontinuity( p_input->p_es_out, VLC_FALSE ); if( demux2_Control( p_input->input.p_demux, DEMUX_SET_POSITION, f_pos ) ) { @@ -1221,8 +1236,8 @@ static vlc_bool_t Control( input_thread_t *p_input, int i_type, if( p_input->i_slave > 0 ) SlaveSeek( p_input ); - input_EsOutDiscontinuity( p_input->p_es_out, VLC_FALSE ); - es_out_Control( p_input->p_es_out, ES_OUT_RESET_PCR ); + //input_EsOutDiscontinuity( p_input->p_es_out, VLC_FALSE ); + //es_out_Control( p_input->p_es_out, ES_OUT_RESET_PCR ); b_force_update = VLC_TRUE; } break; @@ -1246,6 +1261,11 @@ static vlc_bool_t Control( input_thread_t *p_input, int i_type, i_time += val.i_time; } if( i_time < 0 ) i_time = 0; + + /* Reset the decoders states and clock synch (before calling the demuxer */ + es_out_Control( p_input->p_es_out, ES_OUT_RESET_PCR ); + input_EsOutDiscontinuity( p_input->p_es_out, VLC_FALSE ); + i_ret = demux2_Control( p_input->input.p_demux, DEMUX_SET_TIME, i_time ); if( i_ret ) @@ -1272,9 +1292,8 @@ static vlc_bool_t Control( input_thread_t *p_input, int i_type, if( p_input->i_slave > 0 ) SlaveSeek( p_input ); - input_EsOutDiscontinuity( p_input->p_es_out, VLC_FALSE ); - - es_out_Control( p_input->p_es_out, ES_OUT_RESET_PCR ); + //input_EsOutDiscontinuity( p_input->p_es_out, VLC_FALSE ); + //es_out_Control( p_input->p_es_out, ES_OUT_RESET_PCR ); b_force_update = VLC_TRUE; } break; @@ -1486,9 +1505,23 @@ static vlc_bool_t Control( input_thread_t *p_input, int i_type, { demux_t *p_demux = p_input->input.p_demux; int i_seekpoint; + int64_t i_input_time; + int64_t i_seekpoint_time; if( i_type == INPUT_CONTROL_SET_SEEKPOINT_PREV ) - i_seekpoint = p_demux->info.i_seekpoint - 1; + { + i_seekpoint = p_demux->info.i_seekpoint; + i_seekpoint_time = p_input->input.title[p_demux->info.i_title]->seekpoint[i_seekpoint]->i_time_offset; + if( i_seekpoint_time >= 0 && + !demux2_Control( p_demux, + DEMUX_GET_TIME, &i_input_time ) ) + { + if ( i_input_time < i_seekpoint_time + 3000000 ) + i_seekpoint--; + } + else + i_seekpoint--; + } else if( i_type == INPUT_CONTROL_SET_SEEKPOINT_NEXT ) i_seekpoint = p_demux->info.i_seekpoint + 1; else @@ -1505,12 +1538,27 @@ static vlc_bool_t Control( input_thread_t *p_input, int i_type, } else if( p_input->input.i_title > 0 ) { + demux_t *p_demux = p_input->input.p_demux; access_t *p_access = p_input->input.p_access; int i_seekpoint; + int64_t i_input_time; + int64_t i_seekpoint_time; if( i_type == INPUT_CONTROL_SET_SEEKPOINT_PREV ) - i_seekpoint = p_access->info.i_seekpoint - 1; - else if( i_type == INPUT_CONTROL_SET_TITLE_NEXT ) + { + i_seekpoint = p_access->info.i_seekpoint; + i_seekpoint_time = p_input->input.title[p_access->info.i_title]->seekpoint[i_seekpoint]->i_time_offset; + if( i_seekpoint_time >= 0 && + demux2_Control( p_demux, + DEMUX_GET_TIME, &i_input_time ) ) + { + if ( i_input_time < i_seekpoint_time + 3000000 ) + i_seekpoint--; + } + else + i_seekpoint--; + } + else if( i_type == INPUT_CONTROL_SET_SEEKPOINT_NEXT ) i_seekpoint = p_access->info.i_seekpoint + 1; else i_seekpoint = val.i_int; @@ -1864,6 +1912,7 @@ static int InputSourceInit( input_thread_t *p_input, char *psz_access; char *psz_demux; char *psz_path; + char *psz; vlc_value_t val; /* Split uri */ @@ -1973,6 +2022,23 @@ static int InputSourceInit( input_thread_t *p_input, goto error; } + /* */ + psz = var_GetString( p_input, "access-filter" ); + if( *psz ) + { + access_t *p_access = in->p_access; + + /* TODO support chained access-filter */ + in->p_access = access2_FilterNew( in->p_access, psz ); + if( in->p_access == NULL ) + { + in->p_access = p_access; + msg_Warn( p_input, "failed to insert access filter %s", + psz ); + } + } + free( psz ); + /* Get infos from access */ if( !b_quick ) { @@ -2036,6 +2102,10 @@ static int InputSourceInit( input_thread_t *p_input, } } } + + if( var_GetInteger( p_input, "clock-synchro" ) != -1 ) + in->b_can_pace_control = !var_GetInteger( p_input, "clock-synchro" ); + free( psz_dup ); return VLC_SUCCESS; @@ -2311,7 +2381,8 @@ static void ParseOption( input_thread_t *p_input, const char *psz_option ) var_Set( p_input, psz_name, val ); - msg_Dbg( p_input, "set input option: %s to %s", psz_name, psz_value ? psz_value : ( val.b_bool ? "true" : "false") ); + msg_Dbg( p_input, "set input option: %s to %s", psz_name, + psz_value ? psz_value : ( val.b_bool ? "true" : "false") ); cleanup: if( psz_name ) free( psz_name ); @@ -2442,3 +2513,114 @@ static void MRLSections( input_thread_t *p_input, char *psz_source, psz_source, *pi_title_start, *pi_chapter_start, *pi_title_end, *pi_chapter_end ); } + + +/*********************************************************************** + * Info management functions + ***********************************************************************/ +/** + * Get a info item from a given category in a given input item. + * + * \param p_i The input item to get info from + * \param psz_cat String representing the category for the info + * \param psz_name String representing the name of the desired info + * \return A pointer to the string with the given info if found, or an + * empty string otherwise. The caller should free the returned + * pointer. + */ +char *vlc_input_item_GetInfo( input_item_t *p_i, + const char *psz_cat, + const char *psz_name ) +{ + int i,j; + + vlc_mutex_lock( &p_i->lock ); + + for( i = 0 ; i< p_i->i_categories ; i++ ) + { + info_category_t *p_cat = p_i->pp_categories[i]; + + if( !psz_cat || strcmp( p_cat->psz_name, psz_cat ) ) + continue; + + for( j = 0; j < p_cat->i_infos ; j++ ) + { + if( !strcmp( p_cat->pp_infos[j]->psz_name, psz_name ) ) + { + char *psz_ret = strdup( p_cat->pp_infos[j]->psz_value ); + vlc_mutex_unlock( &p_i->lock ); + return psz_ret; + } + } + } + vlc_mutex_unlock( &p_i->lock ); + return strdup( "" ); +} + +int vlc_input_item_AddInfo( input_item_t *p_i, + const char *psz_cat, + const char *psz_name, + const char *psz_format, ... ) +{ + va_list args; + int i; + info_t *p_info = NULL; + info_category_t *p_cat = NULL ; + + vlc_mutex_lock( &p_i->lock ); + + for( i = 0 ; i < p_i->i_categories ; i ++ ) + { + if( !strcmp( p_i->pp_categories[i]->psz_name, psz_cat ) ) + { + p_cat = p_i->pp_categories[i]; + break; + } + } + if( !p_cat ) + { + if( !(p_cat = (info_category_t *)malloc( sizeof(info_category_t) )) ) + { + vlc_mutex_unlock( &p_i->lock ); + return VLC_EGENERIC; + } + p_cat->psz_name = strdup( psz_cat ); + p_cat->i_infos = 0; + p_cat->pp_infos = 0; + INSERT_ELEM( p_i->pp_categories, p_i->i_categories, p_i->i_categories, + p_cat ); + } + + for( i = 0; i< p_cat->i_infos; i++ ) + { + if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) ) + { + p_info = p_cat->pp_infos[i]; + break; + } + } + + if( !p_info ) + { + if( ( p_info = (info_t *)malloc( sizeof( info_t ) ) ) == NULL ) + { + vlc_mutex_unlock( &p_i->lock ); + return VLC_EGENERIC; + } + INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos, p_cat->i_infos, p_info ); + p_info->psz_name = strdup( psz_name ); + } + else + { + if( p_info->psz_value ) free( p_info->psz_value ); + } + + va_start( args, psz_format ); + vasprintf( &p_info->psz_value, psz_format, args); + va_end( args ); + + vlc_mutex_unlock( &p_i->lock ); + + return VLC_SUCCESS; +} +