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
27
#include "timefilter.h"
28
#include "libavutil/mem.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, double feedback2_factor, double feedback3_factor)
42
TimeFilter *self = av_mallocz(sizeof(TimeFilter));
43
self->clock_period = clock_period;
44
self->feedback2_factor = feedback2_factor;
45
self->feedback3_factor = feedback3_factor;
49
void ff_timefilter_destroy(TimeFilter *self)
54
void ff_timefilter_reset(TimeFilter *self)
59
double ff_timefilter_update(TimeFilter *self, double system_time, double period)
64
self->cycle_time = system_time;
67
self->cycle_time += self->clock_period * period;
68
/// calculate loop error
69
loop_error = system_time - self->cycle_time;
72
self->cycle_time += FFMAX(self->feedback2_factor, 1.0 / self->count) * loop_error;
73
self->clock_period += self->feedback3_factor * loop_error / period;
75
return self->cycle_time;
79
#include "libavutil/lfg.h"
80
#define LFG_MAX ((1LL << 32) - 1)
89
double ideal[SAMPLES];
90
double samples[SAMPLES];
92
for(n0= 0; n0<40; n0=2*n0+1){
93
for(n1= 0; n1<10; n1=2*n1+1){
99
double best_error= 1000000000;
101
double bestpar1=0.001;
104
av_lfg_init(&prng, 123);
105
for(i=0; i<SAMPLES; i++){
106
ideal[i] = 10 + i + n1*i/(1000);
107
samples[i] = ideal[i] + n0 * (av_lfg_get(&prng) - LFG_MAX / 2)
114
for(par0= bestpar0*0.8; par0<=bestpar0*1.21; par0+=bestpar0*0.05){
115
for(par1= bestpar1*0.8; par1<=bestpar1*1.21; par1+=bestpar1*0.05){
117
TimeFilter *tf= ff_timefilter_new(1, par0, par1);
118
for(i=0; i<SAMPLES; i++){
120
filtered= ff_timefilter_update(tf, samples[i], 1);
121
error += (filtered - ideal[i]) * (filtered - ideal[i]);
123
ff_timefilter_destroy(tf);
124
if(error < best_error){
135
TimeFilter *tf= ff_timefilter_new(1, bestpar0, bestpar1);
136
for(i=0; i<SAMPLES; i++){
138
filtered= ff_timefilter_update(tf, samples[i], 1);
139
printf("%f %f %f %f\n", i - samples[i] + 10, filtered - samples[i], samples[FFMAX(i, 1)] - samples[FFMAX(i-1, 0)], filtered - lastfil);
142
ff_timefilter_destroy(tf);
144
printf(" [%f %f %9f]", bestpar0, bestpar1, best_error);