Browse code

Move timefilter code from lavf to lavd.

It's only used in the JACK device.

Fixes linking shared lavd with JACK enabled.

Anton Khirnov authored on 2011/10/21 18:47:39
Showing 7 changed files
... ...
@@ -13,7 +13,7 @@ OBJS-$(CONFIG_ALSA_OUTDEV)               += alsa-audio-common.o \
13 13
 OBJS-$(CONFIG_BKTR_INDEV)                += bktr.o
14 14
 OBJS-$(CONFIG_DV1394_INDEV)              += dv1394.o
15 15
 OBJS-$(CONFIG_FBDEV_INDEV)               += fbdev.o
16
-OBJS-$(CONFIG_JACK_INDEV)                += jack_audio.o
16
+OBJS-$(CONFIG_JACK_INDEV)                += jack_audio.o timefilter.o
17 17
 OBJS-$(CONFIG_OSS_INDEV)                 += oss_audio.o
18 18
 OBJS-$(CONFIG_OSS_OUTDEV)                += oss_audio.o
19 19
 OBJS-$(CONFIG_SNDIO_INDEV)               += sndio_common.o sndio_dec.o
... ...
@@ -30,4 +30,6 @@ OBJS-$(CONFIG_LIBDC1394_INDEV)           += libdc1394.o
30 30
 SKIPHEADERS-$(HAVE_ALSA_ASOUNDLIB_H)     += alsa-audio.h
31 31
 SKIPHEADERS-$(HAVE_SNDIO_H)              += sndio_common.h
32 32
 
33
+TESTPROGS = timefilter
34
+
33 35
 include $(SRC_PATH)/subdir.mak
... ...
@@ -29,7 +29,7 @@
29 29
 #include "libavutil/opt.h"
30 30
 #include "libavcodec/avcodec.h"
31 31
 #include "libavformat/avformat.h"
32
-#include "libavformat/timefilter.h"
32
+#include "timefilter.h"
33 33
 
34 34
 /**
35 35
  * Size of the internal FIFO buffers as a number of audio packets
36 36
new file mode 100644
... ...
@@ -0,0 +1,151 @@
0
+/*
1
+ * Delay Locked Loop based time filter
2
+ * Copyright (c) 2009 Samalyse
3
+ * Copyright (c) 2009 Michael Niedermayer
4
+ * Author: Olivier Guilyardi <olivier samalyse com>
5
+ *         Michael Niedermayer <michaelni gmx at>
6
+ *
7
+ * This file is part of Libav.
8
+ *
9
+ * Libav is free software; you can redistribute it and/or
10
+ * modify it under the terms of the GNU Lesser General Public
11
+ * License as published by the Free Software Foundation; either
12
+ * version 2.1 of the License, or (at your option) any later version.
13
+ *
14
+ * Libav is distributed in the hope that it will be useful,
15
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
+ * Lesser General Public License for more details.
18
+ *
19
+ * You should have received a copy of the GNU Lesser General Public
20
+ * License along with Libav; if not, write to the Free Software
21
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
+ */
23
+
24
+
25
+#include "config.h"
26
+#include "timefilter.h"
27
+#include "libavutil/mem.h"
28
+
29
+struct TimeFilter {
30
+    /// Delay Locked Loop data. These variables refer to mathematical
31
+    /// concepts described in: http://www.kokkinizita.net/papers/usingdll.pdf
32
+    double cycle_time;
33
+    double feedback2_factor;
34
+    double feedback3_factor;
35
+    double clock_period;
36
+    int count;
37
+};
38
+
39
+TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor)
40
+{
41
+    TimeFilter *self        = av_mallocz(sizeof(TimeFilter));
42
+    self->clock_period      = clock_period;
43
+    self->feedback2_factor  = feedback2_factor;
44
+    self->feedback3_factor  = feedback3_factor;
45
+    return self;
46
+}
47
+
48
+void ff_timefilter_destroy(TimeFilter *self)
49
+{
50
+    av_freep(&self);
51
+}
52
+
53
+void ff_timefilter_reset(TimeFilter *self)
54
+{
55
+    self->count      = 0;
56
+}
57
+
58
+double ff_timefilter_update(TimeFilter *self, double system_time, double period)
59
+{
60
+    self->count++;
61
+    if (self->count==1) {
62
+        /// init loop
63
+        self->cycle_time    = system_time;
64
+    } else {
65
+        double loop_error;
66
+        self->cycle_time   += self->clock_period * period;
67
+        /// calculate loop error
68
+        loop_error          = system_time - self->cycle_time;
69
+
70
+        /// update loop
71
+        self->cycle_time   += FFMAX(self->feedback2_factor, 1.0/(self->count)) * loop_error;
72
+        self->clock_period += self->feedback3_factor * loop_error / period;
73
+    }
74
+    return self->cycle_time;
75
+}
76
+
77
+#ifdef TEST
78
+#include "libavutil/lfg.h"
79
+#define LFG_MAX ((1LL << 32) - 1)
80
+
81
+#undef printf
82
+
83
+int main(void)
84
+{
85
+    AVLFG prng;
86
+    double n0,n1;
87
+#define SAMPLES 1000
88
+    double ideal[SAMPLES];
89
+    double samples[SAMPLES];
90
+#if 1
91
+    for(n0= 0; n0<40; n0=2*n0+1){
92
+        for(n1= 0; n1<10; n1=2*n1+1){
93
+#else
94
+    {{
95
+        n0=7;
96
+        n1=1;
97
+#endif
98
+            double best_error= 1000000000;
99
+            double bestpar0=1;
100
+            double bestpar1=0.001;
101
+            int better, i;
102
+
103
+            av_lfg_init(&prng, 123);
104
+            for(i=0; i<SAMPLES; i++){
105
+                ideal[i]  = 10 + i + n1*i/(1000);
106
+                samples[i] = ideal[i] + n0 * (av_lfg_get(&prng) - LFG_MAX / 2)
107
+                                           / (LFG_MAX * 10LL);
108
+            }
109
+
110
+            do{
111
+                double par0, par1;
112
+                better=0;
113
+                for(par0= bestpar0*0.8; par0<=bestpar0*1.21; par0+=bestpar0*0.05){
114
+                    for(par1= bestpar1*0.8; par1<=bestpar1*1.21; par1+=bestpar1*0.05){
115
+                        double error=0;
116
+                        TimeFilter *tf= ff_timefilter_new(1, par0, par1);
117
+                        for(i=0; i<SAMPLES; i++){
118
+                            double filtered;
119
+                            filtered=  ff_timefilter_update(tf, samples[i], 1);
120
+                            error += (filtered - ideal[i]) * (filtered - ideal[i]);
121
+                        }
122
+                        ff_timefilter_destroy(tf);
123
+                        if(error < best_error){
124
+                            best_error= error;
125
+                            bestpar0= par0;
126
+                            bestpar1= par1;
127
+                            better=1;
128
+                        }
129
+                    }
130
+                }
131
+            }while(better);
132
+#if 0
133
+            double lastfil=9;
134
+            TimeFilter *tf= ff_timefilter_new(1, bestpar0, bestpar1);
135
+            for(i=0; i<SAMPLES; i++){
136
+                double filtered;
137
+                filtered=  ff_timefilter_update(tf, samples[i], 1);
138
+                printf("%f %f %f %f\n", i - samples[i] + 10, filtered - samples[i], samples[FFMAX(i, 1)] - samples[FFMAX(i-1, 0)], filtered - lastfil);
139
+                lastfil= filtered;
140
+            }
141
+            ff_timefilter_destroy(tf);
142
+#else
143
+            printf(" [%f %f %9f]", bestpar0, bestpar1, best_error);
144
+#endif
145
+        }
146
+        printf("\n");
147
+    }
148
+    return 0;
149
+}
150
+#endif
0 151
new file mode 100644
... ...
@@ -0,0 +1,97 @@
0
+/*
1
+ * Delay Locked Loop based time filter prototypes and declarations
2
+ * Copyright (c) 2009 Samalyse
3
+ * Copyright (c) 2009 Michael Niedermayer
4
+ * Author: Olivier Guilyardi <olivier samalyse com>
5
+ *         Michael Niedermayer <michaelni gmx at>
6
+ *
7
+ * This file is part of Libav.
8
+ *
9
+ * Libav is free software; you can redistribute it and/or
10
+ * modify it under the terms of the GNU Lesser General Public
11
+ * License as published by the Free Software Foundation; either
12
+ * version 2.1 of the License, or (at your option) any later version.
13
+ *
14
+ * Libav is distributed in the hope that it will be useful,
15
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
+ * Lesser General Public License for more details.
18
+ *
19
+ * You should have received a copy of the GNU Lesser General Public
20
+ * License along with Libav; if not, write to the Free Software
21
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
+ */
23
+
24
+#ifndef AVDEVICE_TIMEFILTER_H
25
+#define AVDEVICE_TIMEFILTER_H
26
+
27
+/**
28
+ * Opaque type representing a time filter state
29
+ *
30
+ * The purpose of this filter is to provide a way to compute accurate time
31
+ * stamps that can be compared to wall clock time, especially when dealing
32
+ * with two clocks: the system clock and a hardware device clock, such as
33
+ * a soundcard.
34
+ */
35
+typedef struct TimeFilter TimeFilter;
36
+
37
+
38
+/**
39
+ * Create a new Delay Locked Loop time filter
40
+ *
41
+ * feedback2_factor and feedback3_factor are the factors used for the
42
+ * multiplications that are respectively performed in the second and third
43
+ * feedback paths of the loop.
44
+ *
45
+ * Unless you know what you are doing, you should set these as follow:
46
+ *
47
+ * o = 2 * M_PI * bandwidth * period
48
+ * feedback2_factor = sqrt(2 * o)
49
+ * feedback3_factor = o * o
50
+ *
51
+ * Where bandwidth is up to you to choose. Smaller values will filter out more
52
+ * of the jitter, but also take a longer time for the loop to settle. A good
53
+ * starting point is something between 0.3 and 3 Hz.
54
+ *
55
+ * @param clock_period period of the hardware clock in seconds
56
+ *        (for example 1.0/44100)
57
+ *
58
+ * For more details about these parameters and background concepts please see:
59
+ * http://www.kokkinizita.net/papers/usingdll.pdf
60
+ */
61
+TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor);
62
+
63
+/**
64
+ * Update the filter
65
+ *
66
+ * This function must be called in real time, at each process cycle.
67
+ *
68
+ * @param period the device cycle duration in clock_periods. For example, at
69
+ * 44.1kHz and a buffer size of 512 frames, period = 512 when clock_period
70
+ * was 1.0/44100, or 512/44100 if clock_period was 1.
71
+ *
72
+ * system_time, in seconds, should be the value of the system clock time,
73
+ * at (or as close as possible to) the moment the device hardware interrupt
74
+ * occured (or any other event the device clock raises at the beginning of a
75
+ * cycle).
76
+ *
77
+ * @return the filtered time, in seconds
78
+ */
79
+double ff_timefilter_update(TimeFilter *self, double system_time, double period);
80
+
81
+/**
82
+ * Reset the filter
83
+ *
84
+ * This function should mainly be called in case of XRUN.
85
+ *
86
+ * Warning: after calling this, the filter is in an undetermined state until
87
+ * the next call to ff_timefilter_update()
88
+ */
89
+void ff_timefilter_reset(TimeFilter *);
90
+
91
+/**
92
+ * Free all resources associated with the filter
93
+ */
94
+void ff_timefilter_destroy(TimeFilter *);
95
+
96
+#endif /* AVDEVICE_TIMEFILTER_H */
... ...
@@ -334,11 +334,8 @@ OBJS-$(CONFIG_RTP_PROTOCOL)              += rtpproto.o
334 334
 OBJS-$(CONFIG_TCP_PROTOCOL)              += tcp.o
335 335
 OBJS-$(CONFIG_UDP_PROTOCOL)              += udp.o
336 336
 
337
-# libavdevice dependencies
338
-OBJS-$(CONFIG_JACK_INDEV)                += timefilter.o
339
-
340 337
 EXAMPLES  = metadata output
341
-TESTPROGS = seek timefilter
338
+TESTPROGS = seek
342 339
 TOOLS     = pktdumper probetest
343 340
 
344 341
 include $(SRC_PATH)/subdir.mak
345 342
deleted file mode 100644
... ...
@@ -1,151 +0,0 @@
1
-/*
2
- * Delay Locked Loop based time filter
3
- * Copyright (c) 2009 Samalyse
4
- * Copyright (c) 2009 Michael Niedermayer
5
- * Author: Olivier Guilyardi <olivier samalyse com>
6
- *         Michael Niedermayer <michaelni gmx at>
7
- *
8
- * This file is part of Libav.
9
- *
10
- * Libav is free software; you can redistribute it and/or
11
- * modify it under the terms of the GNU Lesser General Public
12
- * License as published by the Free Software Foundation; either
13
- * version 2.1 of the License, or (at your option) any later version.
14
- *
15
- * Libav is distributed in the hope that it will be useful,
16
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
- * Lesser General Public License for more details.
19
- *
20
- * You should have received a copy of the GNU Lesser General Public
21
- * License along with Libav; if not, write to the Free Software
22
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
- */
24
-
25
-
26
-#include "config.h"
27
-#include "avformat.h"
28
-#include "timefilter.h"
29
-
30
-struct TimeFilter {
31
-    /// Delay Locked Loop data. These variables refer to mathematical
32
-    /// concepts described in: http://www.kokkinizita.net/papers/usingdll.pdf
33
-    double cycle_time;
34
-    double feedback2_factor;
35
-    double feedback3_factor;
36
-    double clock_period;
37
-    int count;
38
-};
39
-
40
-TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor)
41
-{
42
-    TimeFilter *self        = av_mallocz(sizeof(TimeFilter));
43
-    self->clock_period      = clock_period;
44
-    self->feedback2_factor  = feedback2_factor;
45
-    self->feedback3_factor  = feedback3_factor;
46
-    return self;
47
-}
48
-
49
-void ff_timefilter_destroy(TimeFilter *self)
50
-{
51
-    av_freep(&self);
52
-}
53
-
54
-void ff_timefilter_reset(TimeFilter *self)
55
-{
56
-    self->count      = 0;
57
-}
58
-
59
-double ff_timefilter_update(TimeFilter *self, double system_time, double period)
60
-{
61
-    self->count++;
62
-    if (self->count==1) {
63
-        /// init loop
64
-        self->cycle_time    = system_time;
65
-    } else {
66
-        double loop_error;
67
-        self->cycle_time   += self->clock_period * period;
68
-        /// calculate loop error
69
-        loop_error          = system_time - self->cycle_time;
70
-
71
-        /// update loop
72
-        self->cycle_time   += FFMAX(self->feedback2_factor, 1.0/(self->count)) * loop_error;
73
-        self->clock_period += self->feedback3_factor * loop_error / period;
74
-    }
75
-    return self->cycle_time;
76
-}
77
-
78
-#ifdef TEST
79
-#include "libavutil/lfg.h"
80
-#define LFG_MAX ((1LL << 32) - 1)
81
-
82
-#undef printf
83
-
84
-int main(void)
85
-{
86
-    AVLFG prng;
87
-    double n0,n1;
88
-#define SAMPLES 1000
89
-    double ideal[SAMPLES];
90
-    double samples[SAMPLES];
91
-#if 1
92
-    for(n0= 0; n0<40; n0=2*n0+1){
93
-        for(n1= 0; n1<10; n1=2*n1+1){
94
-#else
95
-    {{
96
-        n0=7;
97
-        n1=1;
98
-#endif
99
-            double best_error= 1000000000;
100
-            double bestpar0=1;
101
-            double bestpar1=0.001;
102
-            int better, i;
103
-
104
-            av_lfg_init(&prng, 123);
105
-            for(i=0; i<SAMPLES; i++){
106
-                ideal[i]  = 10 + i + n1*i/(1000);
107
-                samples[i] = ideal[i] + n0 * (av_lfg_get(&prng) - LFG_MAX / 2)
108
-                                           / (LFG_MAX * 10LL);
109
-            }
110
-
111
-            do{
112
-                double par0, par1;
113
-                better=0;
114
-                for(par0= bestpar0*0.8; par0<=bestpar0*1.21; par0+=bestpar0*0.05){
115
-                    for(par1= bestpar1*0.8; par1<=bestpar1*1.21; par1+=bestpar1*0.05){
116
-                        double error=0;
117
-                        TimeFilter *tf= ff_timefilter_new(1, par0, par1);
118
-                        for(i=0; i<SAMPLES; i++){
119
-                            double filtered;
120
-                            filtered=  ff_timefilter_update(tf, samples[i], 1);
121
-                            error += (filtered - ideal[i]) * (filtered - ideal[i]);
122
-                        }
123
-                        ff_timefilter_destroy(tf);
124
-                        if(error < best_error){
125
-                            best_error= error;
126
-                            bestpar0= par0;
127
-                            bestpar1= par1;
128
-                            better=1;
129
-                        }
130
-                    }
131
-                }
132
-            }while(better);
133
-#if 0
134
-            double lastfil=9;
135
-            TimeFilter *tf= ff_timefilter_new(1, bestpar0, bestpar1);
136
-            for(i=0; i<SAMPLES; i++){
137
-                double filtered;
138
-                filtered=  ff_timefilter_update(tf, samples[i], 1);
139
-                printf("%f %f %f %f\n", i - samples[i] + 10, filtered - samples[i], samples[FFMAX(i, 1)] - samples[FFMAX(i-1, 0)], filtered - lastfil);
140
-                lastfil= filtered;
141
-            }
142
-            ff_timefilter_destroy(tf);
143
-#else
144
-            printf(" [%f %f %9f]", bestpar0, bestpar1, best_error);
145
-#endif
146
-        }
147
-        printf("\n");
148
-    }
149
-    return 0;
150
-}
151
-#endif
152 1
deleted file mode 100644
... ...
@@ -1,97 +0,0 @@
1
-/*
2
- * Delay Locked Loop based time filter prototypes and declarations
3
- * Copyright (c) 2009 Samalyse
4
- * Copyright (c) 2009 Michael Niedermayer
5
- * Author: Olivier Guilyardi <olivier samalyse com>
6
- *         Michael Niedermayer <michaelni gmx at>
7
- *
8
- * This file is part of Libav.
9
- *
10
- * Libav is free software; you can redistribute it and/or
11
- * modify it under the terms of the GNU Lesser General Public
12
- * License as published by the Free Software Foundation; either
13
- * version 2.1 of the License, or (at your option) any later version.
14
- *
15
- * Libav is distributed in the hope that it will be useful,
16
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
- * Lesser General Public License for more details.
19
- *
20
- * You should have received a copy of the GNU Lesser General Public
21
- * License along with Libav; if not, write to the Free Software
22
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
- */
24
-
25
-#ifndef AVFORMAT_TIMEFILTER_H
26
-#define AVFORMAT_TIMEFILTER_H
27
-
28
-/**
29
- * Opaque type representing a time filter state
30
- *
31
- * The purpose of this filter is to provide a way to compute accurate time
32
- * stamps that can be compared to wall clock time, especially when dealing
33
- * with two clocks: the system clock and a hardware device clock, such as
34
- * a soundcard.
35
- */
36
-typedef struct TimeFilter TimeFilter;
37
-
38
-
39
-/**
40
- * Create a new Delay Locked Loop time filter
41
- *
42
- * feedback2_factor and feedback3_factor are the factors used for the
43
- * multiplications that are respectively performed in the second and third
44
- * feedback paths of the loop.
45
- *
46
- * Unless you know what you are doing, you should set these as follow:
47
- *
48
- * o = 2 * M_PI * bandwidth * period
49
- * feedback2_factor = sqrt(2 * o)
50
- * feedback3_factor = o * o
51
- *
52
- * Where bandwidth is up to you to choose. Smaller values will filter out more
53
- * of the jitter, but also take a longer time for the loop to settle. A good
54
- * starting point is something between 0.3 and 3 Hz.
55
- *
56
- * @param clock_period period of the hardware clock in seconds
57
- *        (for example 1.0/44100)
58
- *
59
- * For more details about these parameters and background concepts please see:
60
- * http://www.kokkinizita.net/papers/usingdll.pdf
61
- */
62
-TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor);
63
-
64
-/**
65
- * Update the filter
66
- *
67
- * This function must be called in real time, at each process cycle.
68
- *
69
- * @param period the device cycle duration in clock_periods. For example, at
70
- * 44.1kHz and a buffer size of 512 frames, period = 512 when clock_period
71
- * was 1.0/44100, or 512/44100 if clock_period was 1.
72
- *
73
- * system_time, in seconds, should be the value of the system clock time,
74
- * at (or as close as possible to) the moment the device hardware interrupt
75
- * occured (or any other event the device clock raises at the beginning of a
76
- * cycle).
77
- *
78
- * @return the filtered time, in seconds
79
- */
80
-double ff_timefilter_update(TimeFilter *self, double system_time, double period);
81
-
82
-/**
83
- * Reset the filter
84
- *
85
- * This function should mainly be called in case of XRUN.
86
- *
87
- * Warning: after calling this, the filter is in an undetermined state until
88
- * the next call to ff_timefilter_update()
89
- */
90
-void ff_timefilter_reset(TimeFilter *);
91
-
92
-/**
93
- * Free all resources associated with the filter
94
- */
95
-void ff_timefilter_destroy(TimeFilter *);
96
-
97
-#endif /* AVFORMAT_TIMEFILTER_H */