00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "libavutil/common.h"
00026 #include "libavutil/mem.h"
00027 #include "config.h"
00028 #include "timefilter.h"
00029
00030 struct TimeFilter {
00033 double cycle_time;
00034 double feedback2_factor;
00035 double feedback3_factor;
00036 double clock_period;
00037 int count;
00038 };
00039
00040
00041 static double qexpneg(double x)
00042 {
00043 return 1 - 1 / (1 + x * (1 + x / 2 * (1 + x / 3)));
00044 }
00045
00046 TimeFilter *ff_timefilter_new(double time_base,
00047 double period,
00048 double bandwidth)
00049 {
00050 TimeFilter *self = av_mallocz(sizeof(TimeFilter));
00051 double o = 2 * M_PI * bandwidth * period * time_base;
00052 self->clock_period = time_base;
00053 self->feedback2_factor = qexpneg(M_SQRT2 * o);
00054 self->feedback3_factor = qexpneg(o * o) / period;
00055 return self;
00056 }
00057
00058 void ff_timefilter_destroy(TimeFilter *self)
00059 {
00060 av_freep(&self);
00061 }
00062
00063 void ff_timefilter_reset(TimeFilter *self)
00064 {
00065 self->count = 0;
00066 }
00067
00068 double ff_timefilter_update(TimeFilter *self, double system_time, double period)
00069 {
00070 self->count++;
00071 if (self->count == 1) {
00073 self->cycle_time = system_time;
00074 } else {
00075 double loop_error;
00076 self->cycle_time += self->clock_period * period;
00078 loop_error = system_time - self->cycle_time;
00079
00081 self->cycle_time += FFMAX(self->feedback2_factor, 1.0 / self->count) * loop_error;
00082 self->clock_period += self->feedback3_factor * loop_error;
00083 }
00084 return self->cycle_time;
00085 }
00086
00087 double ff_timefilter_eval(TimeFilter *self, double delta)
00088 {
00089 return self->cycle_time + self->clock_period * delta;
00090 }
00091
00092 #ifdef TEST
00093 #include "libavutil/lfg.h"
00094 #define LFG_MAX ((1LL << 32) - 1)
00095
00096 #undef printf
00097
00098 int main(void)
00099 {
00100 AVLFG prng;
00101 double n0, n1;
00102 #define SAMPLES 1000
00103 double ideal[SAMPLES];
00104 double samples[SAMPLES];
00105 double samplet[SAMPLES];
00106 #if 1
00107 for (n0 = 0; n0 < 40; n0 = 2 * n0 + 1) {
00108 for (n1 = 0; n1 < 10; n1 = 2 * n1 + 1) {
00109 #else
00110 {
00111 {
00112 n0 = 7;
00113 n1 = 1;
00114 #endif
00115 double best_error = 1000000000;
00116 double bestpar0 = 1;
00117 double bestpar1 = 1;
00118 int better, i;
00119
00120 av_lfg_init(&prng, 123);
00121 for (i = 0; i < SAMPLES; i++) {
00122 samplet[i] = 10 + i + (av_lfg_get(&prng) < LFG_MAX/2 ? 0 : 0.999);
00123 ideal[i] = samplet[i] + n1 * i / (1000);
00124 samples[i] = ideal[i] + n0 * (av_lfg_get(&prng) - LFG_MAX / 2) / (LFG_MAX * 10LL);
00125 if(i && samples[i]<samples[i-1])
00126 samples[i]=samples[i-1]+0.001;
00127 }
00128
00129 do {
00130 double par0, par1;
00131 better = 0;
00132 for (par0 = bestpar0 * 0.8; par0 <= bestpar0 * 1.21; par0 += bestpar0 * 0.05) {
00133 for (par1 = bestpar1 * 0.8; par1 <= bestpar1 * 1.21; par1 += bestpar1 * 0.05) {
00134 double error = 0;
00135 TimeFilter *tf = ff_timefilter_new(1, par0, par1);
00136 for (i = 0; i < SAMPLES; i++) {
00137 double filtered;
00138 filtered = ff_timefilter_update(tf, samples[i], i ? (samplet[i] - samplet[i-1]) : 1);
00139 if(filtered < 0 || filtered > 1000000000)
00140 printf("filter is unstable\n");
00141 error += (filtered - ideal[i]) * (filtered - ideal[i]);
00142 }
00143 ff_timefilter_destroy(tf);
00144 if (error < best_error) {
00145 best_error = error;
00146 bestpar0 = par0;
00147 bestpar1 = par1;
00148 better = 1;
00149 }
00150 }
00151 }
00152 } while (better);
00153 #if 0
00154 double lastfil = 9;
00155 TimeFilter *tf = ff_timefilter_new(1, bestpar0, bestpar1);
00156 for (i = 0; i < SAMPLES; i++) {
00157 double filtered;
00158 filtered = ff_timefilter_update(tf, samples[i], 1);
00159 printf("%f %f %f %f\n", i - samples[i] + 10, filtered - samples[i],
00160 samples[FFMAX(i, 1)] - samples[FFMAX(i - 1, 0)], filtered - lastfil);
00161 lastfil = filtered;
00162 }
00163 ff_timefilter_destroy(tf);
00164 #else
00165 printf(" [%f %f %9f]", bestpar0, bestpar1, best_error);
00166 #endif
00167 }
00168 printf("\n");
00169 }
00170 return 0;
00171 }
00172 #endif