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 FFmpeg.
10 * FFmpeg 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 * FFmpeg 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 FFmpeg; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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
, 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)
87 double ideal
[SAMPLES
];
88 double samples
[SAMPLES
];
90 for(n0
= 0; n0
<40; n0
=2*n0
+1){
91 for(n1
= 0; n1
<10; n1
=2*n1
+1){
97 double best_error
= 1000000000;
99 double bestpar1
=0.001;
102 av_lfg_init(&prng
, 123);
103 for(i
=0; i
<SAMPLES
; i
++){
104 ideal
[i
] = 10 + i
+ n1
*i
/(1000);
105 samples
[i
] = ideal
[i
] + n0
* (av_lfg_get(&prng
) - LFG_MAX
/ 2)
112 for(par0
= bestpar0
*0.8; par0
<=bestpar0
*1.21; par0
+=bestpar0
*0.05){
113 for(par1
= bestpar1
*0.8; par1
<=bestpar1
*1.21; par1
+=bestpar1
*0.05){
115 TimeFilter
*tf
= ff_timefilter_new(1, par0
, par1
);
116 for(i
=0; i
<SAMPLES
; i
++){
118 filtered
= ff_timefilter_update(tf
, samples
[i
], 1);
119 error
+= (filtered
- ideal
[i
]) * (filtered
- ideal
[i
]);
121 ff_timefilter_destroy(tf
);
122 if(error
< best_error
){
133 TimeFilter
*tf
= ff_timefilter_new(1, bestpar0
, bestpar1
);
134 for(i
=0; i
<SAMPLES
; i
++){
136 filtered
= ff_timefilter_update(tf
, samples
[i
], 1);
137 printf("%f %f %f %f\n", i
- samples
[i
] + 10, filtered
- samples
[i
], samples
[FFMAX(i
, 1)] - samples
[FFMAX(i
-1, 0)], filtered
- lastfil
);
140 ff_timefilter_destroy(tf
);
142 printf(" [%f %f %9f]", bestpar0
, bestpar1
, best_error
);