• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavformat/timefilter.c

Go to the documentation of this file.
00001 /*
00002  * Delay Locked Loop based time filter
00003  * Copyright (c) 2009 Samalyse
00004  * Copyright (c) 2009 Michael Niedermayer
00005  * Author: Olivier Guilyardi <olivier samalyse com>
00006  *         Michael Niedermayer <michaelni gmx at>
00007  *
00008  * This file is part of FFmpeg.
00009  *
00010  * FFmpeg is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or (at your option) any later version.
00014  *
00015  * FFmpeg is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with FFmpeg; if not, write to the Free Software
00022  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00023  */
00024 
00025 
00026 #include "config.h"
00027 #include "avformat.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 TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor)
00041 {
00042     TimeFilter *self        = av_mallocz(sizeof(TimeFilter));
00043     self->clock_period      = clock_period;
00044     self->feedback2_factor  = feedback2_factor;
00045     self->feedback3_factor  = feedback3_factor;
00046     return self;
00047 }
00048 
00049 void ff_timefilter_destroy(TimeFilter *self)
00050 {
00051     av_freep(&self);
00052 }
00053 
00054 void ff_timefilter_reset(TimeFilter *self)
00055 {
00056     self->count      = 0;
00057 }
00058 
00059 double ff_timefilter_update(TimeFilter *self, double system_time, double period)
00060 {
00061     self->count++;
00062     if (self->count==1) {
00064         self->cycle_time    = system_time;
00065     } else {
00066         double loop_error;
00067         self->cycle_time   += self->clock_period * period;
00069         loop_error          = system_time - self->cycle_time;
00070 
00072         self->cycle_time   += FFMAX(self->feedback2_factor, 1.0/(self->count)) * loop_error;
00073         self->clock_period += self->feedback3_factor * loop_error / period;
00074     }
00075     return self->cycle_time;
00076 }
00077 
00078 #ifdef TEST
00079 #include "libavutil/lfg.h"
00080 #define LFG_MAX ((1LL << 32) - 1)
00081 
00082 int main(void)
00083 {
00084     AVLFG prng;
00085     double n0,n1;
00086 #define SAMPLES 1000
00087     double ideal[SAMPLES];
00088     double samples[SAMPLES];
00089 #if 1
00090     for(n0= 0; n0<40; n0=2*n0+1){
00091         for(n1= 0; n1<10; n1=2*n1+1){
00092 #else
00093     {{
00094         n0=7;
00095         n1=1;
00096 #endif
00097             double best_error= 1000000000;
00098             double bestpar0=1;
00099             double bestpar1=0.001;
00100             int better, i;
00101 
00102             av_lfg_init(&prng, 123);
00103             for(i=0; i<SAMPLES; i++){
00104                 ideal[i]  = 10 + i + n1*i/(1000);
00105                 samples[i] = ideal[i] + n0 * (av_lfg_get(&prng) - LFG_MAX / 2)
00106                                            / (LFG_MAX * 10LL);
00107             }
00108 
00109             do{
00110                 double par0, par1;
00111                 better=0;
00112                 for(par0= bestpar0*0.8; par0<=bestpar0*1.21; par0+=bestpar0*0.05){
00113                     for(par1= bestpar1*0.8; par1<=bestpar1*1.21; par1+=bestpar1*0.05){
00114                         double error=0;
00115                         TimeFilter *tf= ff_timefilter_new(1, par0, par1);
00116                         for(i=0; i<SAMPLES; i++){
00117                             double filtered;
00118                             filtered=  ff_timefilter_update(tf, samples[i], 1);
00119                             error += (filtered - ideal[i]) * (filtered - ideal[i]);
00120                         }
00121                         ff_timefilter_destroy(tf);
00122                         if(error < best_error){
00123                             best_error= error;
00124                             bestpar0= par0;
00125                             bestpar1= par1;
00126                             better=1;
00127                         }
00128                     }
00129                 }
00130             }while(better);
00131 #if 0
00132             double lastfil=9;
00133             TimeFilter *tf= ff_timefilter_new(1, bestpar0, bestpar1);
00134             for(i=0; i<SAMPLES; i++){
00135                 double filtered;
00136                 filtered=  ff_timefilter_update(tf, samples[i], 1);
00137                 printf("%f %f %f %f\n", i - samples[i] + 10, filtered - samples[i], samples[FFMAX(i, 1)] - samples[FFMAX(i-1, 0)], filtered - lastfil);
00138                 lastfil= filtered;
00139             }
00140             ff_timefilter_destroy(tf);
00141 #else
00142             printf(" [%f %f %9f]", bestpar0, bestpar1, best_error);
00143 #endif
00144         }
00145         printf("\n");
00146     }
00147     return 0;
00148 }
00149 #endif

Generated on Fri Sep 16 2011 17:17:51 for FFmpeg by  doxygen 1.7.1