2 * Delay Locked Loop based time filter
3 * Copyright (c) 2009 Samalyse
4 * Copyright (c) 2009 Michael Niedermayer
5 * Author: Olivier Guilyardi <olivier samalyse com>
6 * Michael Niedermayer <michaelni gmx at>
8 * This file is part of Libav.
10 * Libav is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * Libav is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with Libav; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "libavutil/common.h"
26 #include "libavutil/mem.h"
28 #include "timefilter.h"
31 // Delay Locked Loop data. These variables refer to mathematical
32 // concepts described in: http://www.kokkinizita.net/papers/usingdll.pdf
34 double feedback2_factor
;
35 double feedback3_factor
;
40 TimeFilter
*ff_timefilter_new(double clock_period
,
41 double feedback2_factor
,
42 double feedback3_factor
)
44 TimeFilter
*self
= av_mallocz(sizeof(TimeFilter
));
45 self
->clock_period
= clock_period
;
46 self
->feedback2_factor
= feedback2_factor
;
47 self
->feedback3_factor
= feedback3_factor
;
51 void ff_timefilter_destroy(TimeFilter
*self
)
56 void ff_timefilter_reset(TimeFilter
*self
)
61 double ff_timefilter_update(TimeFilter
*self
, double system_time
, double period
)
64 if (self
->count
== 1) {
65 self
->cycle_time
= system_time
;
68 self
->cycle_time
+= self
->clock_period
* period
;
69 loop_error
= system_time
- self
->cycle_time
;
71 self
->cycle_time
+= FFMAX(self
->feedback2_factor
, 1.0 / self
->count
) * loop_error
;
72 self
->clock_period
+= self
->feedback3_factor
* loop_error
/ period
;
74 return self
->cycle_time
;
78 #include "libavutil/lfg.h"
79 #define LFG_MAX ((1LL << 32) - 1)
86 double ideal
[SAMPLES
];
87 double samples
[SAMPLES
];
88 for (n0
= 0; n0
< 40; n0
= 2 * n0
+ 1) {
89 for (n1
= 0; n1
< 10; n1
= 2 * n1
+ 1) {
90 double best_error
= 1000000000;
92 double bestpar1
= 0.001;
95 av_lfg_init(&prng
, 123);
96 for (i
= 0; i
< SAMPLES
; i
++) {
97 ideal
[i
] = 10 + i
+ n1
* i
/ (1000);
98 samples
[i
] = ideal
[i
] + n0
* (av_lfg_get(&prng
) - LFG_MAX
/ 2) / (LFG_MAX
* 10LL);
104 for (par0
= bestpar0
* 0.8; par0
<= bestpar0
* 1.21; par0
+= bestpar0
* 0.05) {
105 for (par1
= bestpar1
* 0.8; par1
<= bestpar1
* 1.21; par1
+= bestpar1
* 0.05) {
107 TimeFilter
*tf
= ff_timefilter_new(1, par0
, par1
);
108 for (i
= 0; i
< SAMPLES
; i
++) {
110 filtered
= ff_timefilter_update(tf
, samples
[i
], 1);
111 error
+= (filtered
- ideal
[i
]) * (filtered
- ideal
[i
]);
113 ff_timefilter_destroy(tf
);
114 if (error
< best_error
) {
125 TimeFilter
*tf
= ff_timefilter_new(1, bestpar0
, bestpar1
);
126 for (i
= 0; i
< SAMPLES
; i
++) {
128 filtered
= ff_timefilter_update(tf
, samples
[i
], 1);
129 printf("%f %f %f %f\n", i
- samples
[i
] + 10, filtered
- samples
[i
],
130 samples
[FFMAX(i
, 1)] - samples
[FFMAX(i
- 1, 0)], filtered
- lastfil
);
133 ff_timefilter_destroy(tf
);
135 printf(" [%f %f %9f]", bestpar0
, bestpar1
, best_error
);