GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavfilter/f_bench.c Lines: 0 27 0.0 %
Date: 2020-08-14 10:39:37 Branches: 0 8 0.0 %

Line Branch Exec Source
1
/*
2
 * This file is part of FFmpeg.
3
 *
4
 * FFmpeg is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2.1 of the License, or (at your option) any later version.
8
 *
9
 * FFmpeg is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15
 * License along with FFmpeg; if not, write to the Free Software
16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
 */
18
19
#include "libavutil/opt.h"
20
#include "libavutil/time.h"
21
#include "avfilter.h"
22
#include "formats.h"
23
#include "internal.h"
24
25
enum BenchAction {
26
    ACTION_START,
27
    ACTION_STOP,
28
    NB_ACTION
29
};
30
31
typedef struct BenchContext {
32
    const AVClass *class;
33
    int action;
34
    int64_t max, min;
35
    int64_t sum;
36
    int n;
37
} BenchContext;
38
39
#define OFFSET(x) offsetof(BenchContext, x)
40
#define DEFINE_OPTIONS(filt_name, FLAGS)                                                                                \
41
static const AVOption filt_name##_options[] = {                                                                         \
42
    { "action", "set action", OFFSET(action), AV_OPT_TYPE_INT, {.i64=ACTION_START}, 0, NB_ACTION-1, FLAGS, "action" },  \
43
        { "start", "start timer",  0, AV_OPT_TYPE_CONST, {.i64=ACTION_START}, INT_MIN, INT_MAX, FLAGS, "action" },      \
44
        { "stop",  "stop timer",   0, AV_OPT_TYPE_CONST, {.i64=ACTION_STOP},  INT_MIN, INT_MAX, FLAGS, "action" },      \
45
    { NULL }                                                                                                            \
46
}
47
48
#define START_TIME_KEY "lavfi.bench.start_time"
49
#define T2F(v) ((v) / 1000000.)
50
51
static av_cold int init(AVFilterContext *ctx)
52
{
53
    BenchContext *s = ctx->priv;
54
    s->min = INT64_MAX;
55
    s->max = INT64_MIN;
56
    return 0;
57
}
58
59
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
60
{
61
    AVFilterContext *ctx = inlink->dst;
62
    BenchContext *s = ctx->priv;
63
    AVFilterLink *outlink = ctx->outputs[0];
64
    const int64_t t = av_gettime();
65
66
    if (t < 0)
67
        return ff_filter_frame(outlink, in);
68
69
    if (s->action == ACTION_START) {
70
        av_dict_set_int(&in->metadata, START_TIME_KEY, t, 0);
71
    } else if (s->action == ACTION_STOP) {
72
        AVDictionaryEntry *e = av_dict_get(in->metadata, START_TIME_KEY, NULL, 0);
73
        if (e) {
74
            const int64_t start = strtoll(e->value, NULL, 0);
75
            const int64_t diff = t - start;
76
            s->sum += diff;
77
            s->n++;
78
            s->min = FFMIN(s->min, diff);
79
            s->max = FFMAX(s->max, diff);
80
            av_log(s, AV_LOG_INFO, "t:%f avg:%f max:%f min:%f\n",
81
                   T2F(diff), T2F(s->sum / s->n), T2F(s->max), T2F(s->min));
82
        }
83
        av_dict_set(&in->metadata, START_TIME_KEY, NULL, 0);
84
    }
85
86
    return ff_filter_frame(outlink, in);
87
}
88
89
#if CONFIG_BENCH_FILTER
90
DEFINE_OPTIONS(bench, AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM);
91
AVFILTER_DEFINE_CLASS(bench);
92
93
static const AVFilterPad bench_inputs[] = {
94
    {
95
        .name         = "default",
96
        .type         = AVMEDIA_TYPE_VIDEO,
97
        .filter_frame = filter_frame,
98
    },
99
    { NULL }
100
};
101
102
static const AVFilterPad bench_outputs[] = {
103
    {
104
        .name = "default",
105
        .type = AVMEDIA_TYPE_VIDEO,
106
    },
107
    { NULL }
108
};
109
110
AVFilter ff_vf_bench = {
111
    .name          = "bench",
112
    .description   = NULL_IF_CONFIG_SMALL("Benchmark part of a filtergraph."),
113
    .priv_size     = sizeof(BenchContext),
114
    .init          = init,
115
    .inputs        = bench_inputs,
116
    .outputs       = bench_outputs,
117
    .priv_class    = &bench_class,
118
};
119
#endif /* CONFIG_BENCH_FILTER */
120
121
#if CONFIG_ABENCH_FILTER
122
DEFINE_OPTIONS(abench, AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM);
123
AVFILTER_DEFINE_CLASS(abench);
124
125
static const AVFilterPad abench_inputs[] = {
126
    {
127
        .name         = "default",
128
        .type         = AVMEDIA_TYPE_AUDIO,
129
        .filter_frame = filter_frame,
130
    },
131
    { NULL }
132
};
133
134
static const AVFilterPad abench_outputs[] = {
135
    {
136
        .name = "default",
137
        .type = AVMEDIA_TYPE_AUDIO,
138
    },
139
    { NULL }
140
};
141
142
AVFilter ff_af_abench = {
143
    .name          = "abench",
144
    .description   = NULL_IF_CONFIG_SMALL("Benchmark part of a filtergraph."),
145
    .priv_size     = sizeof(BenchContext),
146
    .init          = init,
147
    .inputs        = abench_inputs,
148
    .outputs       = abench_outputs,
149
    .priv_class    = &abench_class,
150
};
151
#endif /* CONFIG_ABENCH_FILTER */