[vlc-devel] commit: Modularize drift algo by introducing a long term average helper. ( Laurent Aimar )
git version control
git at videolan.org
Sun Sep 28 13:35:58 CEST 2008
vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Thu Sep 25 20:39:56 2008 +0200| [cbcd0db85d4d2b4d0b893f46810db6ba5a85e4c0] | committer: Laurent Aimar
Modularize drift algo by introducing a long term average helper.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=cbcd0db85d4d2b4d0b893f46810db6ba5a85e4c0
---
src/input/clock.c | 101 +++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 75 insertions(+), 26 deletions(-)
diff --git a/src/input/clock.c b/src/input/clock.c
index dd07adb..999ed1f 100644
--- a/src/input/clock.c
+++ b/src/input/clock.c
@@ -81,6 +81,26 @@
/*****************************************************************************
* Structures
*****************************************************************************/
+
+/**
+ * This structure holds long term average
+ */
+typedef struct
+{
+ mtime_t i_value;
+ int i_residue;
+
+ int i_count;
+ int i_divider;
+} average_t;
+static void AverageInit( average_t *, int i_divider );
+static void AverageClean( average_t * );
+
+static void AverageReset( average_t * );
+static void AverageUpdate( average_t *, mtime_t i_value );
+static mtime_t AverageGet( average_t * );
+
+/* */
struct input_clock_t
{
/* Reference point */
@@ -99,20 +119,16 @@ struct input_clock_t
mtime_t i_system;
} last;
- /* Maixmal timestamp returned by input_clock_GetTS (in system unit) */
+ /* Maximal timestamp returned by input_clock_GetTS (in system unit) */
mtime_t i_ts_max;
/* Clock drift */
- mtime_t i_delta_update; /* System time to wait for drift update */
- mtime_t i_delta;
- int i_delta_residue;
+ mtime_t i_next_drift_update;
+ average_t drift;
/* Current modifiers */
bool b_master;
int i_rate;
-
- /* Static configuration */
- int i_cr_average;
};
static mtime_t ClockStreamToSystem( input_clock_t *, mtime_t i_clock );
@@ -137,14 +153,12 @@ input_clock_t *input_clock_New( bool b_master, int i_cr_average, int i_rate )
cl->i_ts_max = 0;
- cl->i_delta = 0;
- cl->i_delta_residue = 0;
+ cl->i_next_drift_update = 0;
+ AverageInit( &cl->drift, i_cr_average );
cl->b_master = b_master;
cl->i_rate = i_rate;
- cl->i_cr_average = i_cr_average;
-
return cl;
}
@@ -153,6 +167,7 @@ input_clock_t *input_clock_New( bool b_master, int i_cr_average, int i_rate )
*****************************************************************************/
void input_clock_Delete( input_clock_t *cl )
{
+ AverageClean( &cl->drift );
free( cl );
}
@@ -172,8 +187,6 @@ void input_clock_SetPCR( input_clock_t *cl,
if( ( !cl->b_has_reference ) ||
( i_ck_stream == 0 && cl->last.i_clock != 0 ) )
{
- cl->i_delta_update = 0;
-
/* */
b_reset_reference= true;
}
@@ -193,8 +206,8 @@ void input_clock_SetPCR( input_clock_t *cl,
}
if( b_reset_reference )
{
- cl->i_delta = 0;
- cl->i_delta_residue = 0;
+ cl->i_next_drift_update = 0;
+ AverageReset( &cl->drift );
/* Feed synchro with a new reference point. */
ClockSetReference( cl, i_ck_stream,
@@ -204,19 +217,13 @@ void input_clock_SetPCR( input_clock_t *cl,
cl->last.i_clock = i_ck_stream;
cl->last.i_system = i_ck_system;
- if( !b_synchronize && i_ck_system - cl->i_delta_update > 200000 )
+ if( !b_synchronize && cl->i_next_drift_update < i_ck_system )
{
- /* Smooth clock reference variations. */
- const mtime_t i_extrapoled_clock = ClockSystemToStream( cl, i_ck_system );
- /* Bresenham algorithm to smooth variations. */
- const mtime_t i_tmp = cl->i_delta * (cl->i_cr_average - 1) +
- ( i_extrapoled_clock - i_ck_stream ) * 1 +
- cl->i_delta_residue;
+ const mtime_t i_converted = ClockSystemToStream( cl, i_ck_system );
- cl->i_delta_residue = i_tmp % cl->i_cr_average;
- cl->i_delta = i_tmp / cl->i_cr_average;
+ AverageUpdate( &cl->drift, i_converted - i_ck_stream );
- cl->i_delta_update = i_ck_system;
+ cl->i_next_drift_update = i_ck_system + CLOCK_FREQ/5; /* FIXME why that */
}
}
@@ -241,7 +248,7 @@ mtime_t input_clock_GetTS( input_clock_t *cl,
return 0;
/* */
- i_converted_ts = ClockStreamToSystem( cl, i_ts + cl->i_delta );
+ i_converted_ts = ClockStreamToSystem( cl, i_ts + AverageGet( &cl->drift ) );
if( i_converted_ts > cl->i_ts_max )
cl->i_ts_max = i_converted_ts;
@@ -320,4 +327,46 @@ static void ClockSetReference( input_clock_t *cl,
cl->ref.i_system = i_system;
}
+/*****************************************************************************
+ * Long term average helpers
+ *****************************************************************************/
+typedef struct
+{
+ mtime_t i_value;
+ int i_residue;
+
+ int i_count;
+ int i_divider;
+} averager_t;
+static void AverageInit( average_t *p_avg, int i_divider )
+{
+ p_avg->i_divider = i_divider;
+ AverageReset( p_avg );
+}
+static void AverageClean( average_t *p_avg )
+{
+ VLC_UNUSED(p_avg);
+}
+static void AverageReset( average_t *p_avg )
+{
+ p_avg->i_value = 0;
+ p_avg->i_residue = 0;
+ p_avg->i_count = 0;
+}
+static void AverageUpdate( 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 AverageGet( average_t *p_avg )
+{
+ return p_avg->i_value;
+}
More information about the vlc-devel
mailing list