Libav
|
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