Libav 0.7.1
|
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 Libav. 00009 * 00010 * Libav 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 * Libav 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 Libav; 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 #undef printf 00083 00084 int main(void) 00085 { 00086 AVLFG prng; 00087 double n0,n1; 00088 #define SAMPLES 1000 00089 double ideal[SAMPLES]; 00090 double samples[SAMPLES]; 00091 #if 1 00092 for(n0= 0; n0<40; n0=2*n0+1){ 00093 for(n1= 0; n1<10; n1=2*n1+1){ 00094 #else 00095 {{ 00096 n0=7; 00097 n1=1; 00098 #endif 00099 double best_error= 1000000000; 00100 double bestpar0=1; 00101 double bestpar1=0.001; 00102 int better, i; 00103 00104 av_lfg_init(&prng, 123); 00105 for(i=0; i<SAMPLES; i++){ 00106 ideal[i] = 10 + i + n1*i/(1000); 00107 samples[i] = ideal[i] + n0 * (av_lfg_get(&prng) - LFG_MAX / 2) 00108 / (LFG_MAX * 10LL); 00109 } 00110 00111 do{ 00112 double par0, par1; 00113 better=0; 00114 for(par0= bestpar0*0.8; par0<=bestpar0*1.21; par0+=bestpar0*0.05){ 00115 for(par1= bestpar1*0.8; par1<=bestpar1*1.21; par1+=bestpar1*0.05){ 00116 double error=0; 00117 TimeFilter *tf= ff_timefilter_new(1, par0, par1); 00118 for(i=0; i<SAMPLES; i++){ 00119 double filtered; 00120 filtered= ff_timefilter_update(tf, samples[i], 1); 00121 error += (filtered - ideal[i]) * (filtered - ideal[i]); 00122 } 00123 ff_timefilter_destroy(tf); 00124 if(error < best_error){ 00125 best_error= error; 00126 bestpar0= par0; 00127 bestpar1= par1; 00128 better=1; 00129 } 00130 } 00131 } 00132 }while(better); 00133 #if 0 00134 double lastfil=9; 00135 TimeFilter *tf= ff_timefilter_new(1, bestpar0, bestpar1); 00136 for(i=0; i<SAMPLES; i++){ 00137 double filtered; 00138 filtered= ff_timefilter_update(tf, samples[i], 1); 00139 printf("%f %f %f %f\n", i - samples[i] + 10, filtered - samples[i], samples[FFMAX(i, 1)] - samples[FFMAX(i-1, 0)], filtered - lastfil); 00140 lastfil= filtered; 00141 } 00142 ff_timefilter_destroy(tf); 00143 #else 00144 printf(" [%f %f %9f]", bestpar0, bestpar1, best_error); 00145 #endif 00146 } 00147 printf("\n"); 00148 } 00149 return 0; 00150 } 00151 #endif