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 );
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, '}' );
*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 );
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;
{
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;
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 ) )
{
{
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" );
}
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 ||
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];
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;
}
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 ) )
{
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;
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 )
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;
{
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
}
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;
char *psz_access;
char *psz_demux;
char *psz_path;
+ char *psz;
vlc_value_t val;
/* Split uri */
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 )
{
}
}
}
+
+ 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;
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 );
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;
+}
+