GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavdevice/timefilter.c Lines: 0 26 0.0 %
Date: 2020-09-25 23:16:12 Branches: 0 6 0.0 %

Line Branch Exec Source
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 FFmpeg.
9
 *
10
 * FFmpeg 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
 * FFmpeg 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 FFmpeg; if not, write to the Free Software
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
 */
24
25
#include "libavutil/common.h"
26
#include "libavutil/mem.h"
27
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
/* 1 - exp(-x) using a 3-order power series */
41
static double qexpneg(double x)
42
{
43
    return 1 - 1 / (1 + x * (1 + x / 2 * (1 + x / 3)));
44
}
45
46
TimeFilter *ff_timefilter_new(double time_base,
47
                              double period,
48
                              double bandwidth)
49
{
50
    TimeFilter *self       = av_mallocz(sizeof(TimeFilter));
51
    double o               = 2 * M_PI * bandwidth * period * time_base;
52
53
    if (!self)
54
        return NULL;
55
56
    self->clock_period     = time_base;
57
    self->feedback2_factor = qexpneg(M_SQRT2 * o);
58
    self->feedback3_factor = qexpneg(o * o) / period;
59
    return self;
60
}
61
62
void ff_timefilter_destroy(TimeFilter *self)
63
{
64
    av_freep(&self);
65
}
66
67
void ff_timefilter_reset(TimeFilter *self)
68
{
69
    self->count = 0;
70
}
71
72
double ff_timefilter_update(TimeFilter *self, double system_time, double period)
73
{
74
    self->count++;
75
    if (self->count == 1) {
76
        self->cycle_time = system_time;
77
    } else {
78
        double loop_error;
79
        self->cycle_time += self->clock_period * period;
80
        loop_error = system_time - self->cycle_time;
81
82
        self->cycle_time   += FFMAX(self->feedback2_factor, 1.0 / self->count) * loop_error;
83
        self->clock_period += self->feedback3_factor * loop_error;
84
    }
85
    return self->cycle_time;
86
}
87
88
double ff_timefilter_eval(TimeFilter *self, double delta)
89
{
90
    return self->cycle_time + self->clock_period * delta;
91
}