+ i_converted_ts = ClockStreamToSystem( cl, i_ts + AvgGet( &cl->drift ) );
+ if( i_converted_ts > cl->i_ts_max )
+ cl->i_ts_max = i_converted_ts;
+
+ vlc_mutex_unlock( &cl->lock );
+
+ return i_converted_ts + i_pts_delay;
+}
+/*****************************************************************************
+ * input_clock_GetRate: Return current rate
+ *****************************************************************************/
+int input_clock_GetRate( input_clock_t *cl )
+{
+ int i_rate;
+
+ vlc_mutex_lock( &cl->lock );
+ i_rate = cl->i_rate;
+ vlc_mutex_unlock( &cl->lock );
+
+ return i_rate;
+}
+
+/*****************************************************************************
+ * ClockStreamToSystem: converts a movie clock to system date
+ *****************************************************************************/
+static mtime_t ClockStreamToSystem( input_clock_t *cl, mtime_t i_stream )
+{
+ if( !cl->b_has_reference )
+ return 0;
+
+ return ( i_stream - cl->ref.i_stream ) * cl->i_rate / INPUT_RATE_DEFAULT +
+ cl->ref.i_system;
+}
+
+/*****************************************************************************
+ * ClockSystemToStream: converts a system date to movie clock
+ *****************************************************************************
+ * Caution : a valid reference point is needed for this to operate.
+ *****************************************************************************/
+static mtime_t ClockSystemToStream( input_clock_t *cl, mtime_t i_system )
+{
+ assert( cl->b_has_reference );
+ return ( i_system - cl->ref.i_system ) * INPUT_RATE_DEFAULT / cl->i_rate +
+ cl->ref.i_stream;
+}
+
+/*****************************************************************************
+ * Long term average helpers
+ *****************************************************************************/
+static void AvgInit( average_t *p_avg, int i_divider )
+{
+ p_avg->i_divider = i_divider;
+ AvgReset( p_avg );
+}
+static void AvgClean( average_t *p_avg )
+{
+ VLC_UNUSED(p_avg);
+}
+static void AvgReset( average_t *p_avg )
+{
+ p_avg->i_value = 0;
+ p_avg->i_residue = 0;
+ p_avg->i_count = 0;
+}
+static void AvgUpdate( average_t *p_avg, mtime_t i_value )
+{
+ const int i_f0 = __MIN( p_avg->i_divider - 1, p_avg->i_count );
+ const int i_f1 = p_avg->i_divider - i_f0;
+
+ const mtime_t i_tmp = i_f0 * p_avg->i_value + i_f1 * i_value + p_avg->i_residue;
+
+ p_avg->i_value = i_tmp / p_avg->i_divider;
+ p_avg->i_residue = i_tmp % p_avg->i_divider;
+
+ p_avg->i_count++;
+}
+static mtime_t AvgGet( average_t *p_avg )
+{
+ return p_avg->i_value;