p_sys->i_preroll_end = -1;
}
+static mtime_t EsOutGetBuffering( es_out_t *out )
+{
+ es_out_sys_t *p_sys = out->p_sys;
+
+ if( !p_sys->p_pgrm )
+ return 0;
+
+ int i_ret;
+ mtime_t i_stream_start;
+ mtime_t i_system_start;
+ mtime_t i_stream_duration;
+ mtime_t i_system_duration;
+ i_ret = input_clock_GetState( p_sys->p_pgrm->p_clock,
+ &i_stream_start, &i_system_start,
+ &i_stream_duration, &i_system_duration );
+
+ if( i_ret )
+ return 0;
+ mtime_t i_delay;
+ if( p_sys->b_buffering && p_sys->i_buffering_extra_initial <= 0 )
+ {
+ i_delay = i_stream_duration;
+ }
+ else
+ {
+ mtime_t i_system_duration;
+ if( p_sys->b_paused )
+ {
+ i_system_duration = p_sys->i_pause_date - i_system_start;
+ if( p_sys->i_buffering_extra_initial > 0 )
+ i_system_duration += p_sys->i_buffering_extra_system - p_sys->i_buffering_extra_initial;
+ }
+ else
+ {
+ i_system_duration = mdate() - i_system_start;
+ }
+
+ const mtime_t i_consumed = i_system_duration * INPUT_RATE_DEFAULT / p_sys->i_rate - i_stream_duration;
+ i_delay = p_sys->p_input->i_pts_delay - i_consumed;
+ }
+ if( i_delay < 0 )
+ return 0;
+ return i_delay;
+}
static void EsOutESVarUpdateGeneric( es_out_t *out, int i_id, es_format_t *fmt, const char *psz_language,
bool b_delete )
mtime_t i_time = (mtime_t)va_arg( args, mtime_t );
mtime_t i_length = (mtime_t)va_arg( args, mtime_t );
- /* TODO handle es_out buffering */
+ /* Fix for buffering delay */
+ const mtime_t i_delay = EsOutGetBuffering( out );
+
+ i_time -= i_delay;
+ if( i_time < 0 )
+ i_time = 0;
+
+ if( i_length > 0 )
+ f_position -= (double)i_delay / i_length;
+ if( f_position < 0 )
+ f_position = 0;
+
input_SendEventTimes( p_sys->p_input, f_position, i_time, i_length );
return VLC_SUCCESS;
}
msg_Err( p_input, "INPUT_CONTROL_SET_POSITION(_OFFSET) ignored while recording" );
break;
}
- if( i_type == INPUT_CONTROL_SET_POSITION )
- {
- f_pos = val.f_float;
- }
- else
- {
- /* Should not fail */
- demux_Control( p_input->p->input.p_demux,
- DEMUX_GET_POSITION, &f_pos );
- f_pos += val.f_float;
- }
- if( f_pos < 0.0 ) f_pos = 0.0;
- if( f_pos > 1.0 ) f_pos = 1.0;
+ f_pos = val.f_float;
+ if( i_type != INPUT_CONTROL_SET_POSITION )
+ f_pos += var_GetFloat( p_input, "position" );
+ if( f_pos < 0.0 )
+ f_pos = 0.0;
+ else if( f_pos > 1.0 )
+ f_pos = 1.0;
/* Reset the decoders states and clock sync (before calling the demuxer */
es_out_SetTime( p_input->p->p_es_out, -1 );
if( demux_Control( p_input->p->input.p_demux, DEMUX_SET_POSITION,
break;
}
- if( i_type == INPUT_CONTROL_SET_TIME )
- {
- i_time = val.i_time;
- }
- else
- {
- /* Should not fail */
- demux_Control( p_input->p->input.p_demux,
- DEMUX_GET_TIME, &i_time );
- i_time += val.i_time;
- }
- if( i_time < 0 ) i_time = 0;
+ i_time = val.i_time;
+ if( i_type != INPUT_CONTROL_SET_TIME )
+ i_time += var_GetTime( p_input, "time" );
+
+ if( i_time < 0 )
+ i_time = 0;
/* Reset the decoders states and clock sync (before calling the demuxer */
es_out_SetTime( p_input->p->p_es_out, -1 );
{
i_seekpoint = p_demux->info.i_seekpoint;
i_seekpoint_time = p_input->p->input.title[p_demux->info.i_title]->seekpoint[i_seekpoint]->i_time_offset;
- if( i_seekpoint_time >= 0 &&
- !demux_Control( p_demux,
- DEMUX_GET_TIME, &i_input_time ) )
+ i_input_time = var_GetTime( p_input, "time" );
+ if( i_seekpoint_time >= 0 && i_input_time >= 0 )
{
if( i_input_time < i_seekpoint_time + 3000000 )
i_seekpoint--;
{
i_seekpoint = p_access->info.i_seekpoint;
i_seekpoint_time = p_input->p->input.title[p_access->info.i_title]->seekpoint[i_seekpoint]->i_time_offset;
- if( i_seekpoint_time >= 0 &&
- demux_Control( p_demux,
- DEMUX_GET_TIME, &i_input_time ) )
+ i_input_time = var_GetTime( p_input, "time" );
+ if( i_seekpoint_time >= 0 && i_input_time >= 0 )
{
if( i_input_time < i_seekpoint_time + 3000000 )
i_seekpoint--;