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