# [FFmpeg-devel] [PATCH] timefilter: partially explain the theory.

Nicolas George nicolas.george at normalesup.org
Sat Dec 24 14:25:14 CET 2011

```This commit also fixes the URL of the longer documentation.

Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
---

I must say that I am still baffled by the formulas used to compute the
feedback factors. If someone has some insight about that, I would be happy
to see it.

Regards,

--
Nicolas George

libavdevice/timefilter.c |   42 +++++++++++++++++++++++++++++++++++++++++-
1 files changed, 41 insertions(+), 1 deletions(-)

diff --git a/libavdevice/timefilter.c b/libavdevice/timefilter.c
index 3c67a59..57a1bec 100644
--- a/libavdevice/timefilter.c
+++ b/libavdevice/timefilter.c
@@ -29,7 +29,8 @@

struct TimeFilter {
/// Delay Locked Loop data. These variables refer to mathematical
-    /// concepts described in: http://www.kokkinizita.net/papers/usingdll.pdf
+    /// concepts described in:
+    /// http://kokkinizita.linuxaudio.org/papers/usingdll.pdf
double cycle_time;
double feedback2_factor;
double feedback3_factor;
@@ -37,6 +38,45 @@ struct TimeFilter {
int count;
};

+/*
+
+Let t(n) be the experimental timestamp at step n.
+Let p(n) be the theoretical time between t(n-1) and t(n)
+            (in other words, nb_samples / sample_rate).
+
+Let f and g be the feedback factors.
+
+Let T(n) be the filtered timestamp at step n.
+Let A(n) be the speed factor at step n (in other words, estimated dT/dt).
+
+Then:
+
+T(0) = t(0)
+A(0) = 1
+T(n) = (1-f) * (T(n-1) + A(n-1) p(n)) + f * t(n)
+A(n) = (1-g) * A(n-1) + g * (t(n) - T(n-1)) / p(n)
+
+T(t) is an average between:
+  - the estimated time using the previous filtered time and
+                             the estimated interval;
+  - the actual time.
+
+A(n) is an exponential moving average of the ratio between:
+  - the actual period (starting from the previous filtered time) and
+  - the theoretical period.
+
+In the implementation below:
+  - feedback2_factor = f;
+  - feedback2_factor = g;
+  - clock_period     = A(n) multiplied by an unit conversion constant;
+  - cycle_time       = T(n);
+  - the average for T is biased in the few first steps.
+
+    o = 2 * M_PI * s->period_size / s->sample_rate * 1.5; // bandwidth: 1.5Hz
+    s->timefilter = ff_timefilter_new(1000000.0 / s->sample_rate,
+                                      sqrt(2 * o), o * o);
+*/
+
TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor)
{
TimeFilter *self        = av_mallocz(sizeof(TimeFilter));
--
1.7.2.5

```