FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/af_asetrate.c
Date: 2024-04-19 07:31:02
Exec Total Coverage
Lines: 26 35 74.3%
Functions: 3 3 100.0%
Branches: 6 16 37.5%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2013 Nicolas George
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "libavutil/opt.h"
22 #include "avfilter.h"
23 #include "formats.h"
24 #include "internal.h"
25
26 typedef struct ASetRateContext {
27 const AVClass *class;
28 int sample_rate;
29 int rescale_pts;
30 } ASetRateContext;
31
32 #define CONTEXT ASetRateContext
33 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
34
35 #define OPT_GENERIC(name, field, def, min, max, descr, type, deffield, ...) \
36 { name, descr, offsetof(CONTEXT, field), AV_OPT_TYPE_ ## type, \
37 { .deffield = def }, min, max, FLAGS, __VA_ARGS__ }
38
39 #define OPT_INT(name, field, def, min, max, descr, ...) \
40 OPT_GENERIC(name, field, def, min, max, descr, INT, i64, __VA_ARGS__)
41
42 static const AVOption asetrate_options[] = {
43 OPT_INT("sample_rate", sample_rate, 44100, 1, INT_MAX, "set the sample rate",),
44 OPT_INT("r", sample_rate, 44100, 1, INT_MAX, "set the sample rate",),
45 {NULL},
46 };
47
48 AVFILTER_DEFINE_CLASS(asetrate);
49
50 1 static av_cold int query_formats(AVFilterContext *ctx)
51 {
52 1 ASetRateContext *sr = ctx->priv;
53 1 int ret, sample_rates[] = { sr->sample_rate, -1 };
54
55
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if ((ret = ff_set_common_formats(ctx, ff_all_formats(AVMEDIA_TYPE_AUDIO))) < 0)
56 return ret;
57
58
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if ((ret = ff_set_common_all_channel_counts(ctx)) < 0)
59 return ret;
60
61
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if ((ret = ff_formats_ref(ff_all_samplerates(),
62 1 &ctx->inputs[0]->outcfg.samplerates)) < 0)
63 return ret;
64
65 1 return ff_formats_ref(ff_make_format_list(sample_rates),
66 1 &ctx->outputs[0]->incfg.samplerates);
67 }
68
69 1 static av_cold int config_props(AVFilterLink *outlink)
70 {
71 1 AVFilterContext *ctx = outlink->src;
72 1 ASetRateContext *sr = ctx->priv;
73 1 AVFilterLink *inlink = ctx->inputs[0];
74 1 AVRational intb = ctx->inputs[0]->time_base;
75 1 int inrate = inlink->sample_rate;
76
77
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if (intb.num == 1 && intb.den == inrate) {
78 1 outlink->time_base.num = 1;
79 1 outlink->time_base.den = outlink->sample_rate;
80 } else {
81 outlink->time_base = intb;
82 sr->rescale_pts = 1;
83 if (av_q2d(intb) > 1.0 / FFMAX(inrate, outlink->sample_rate))
84 av_log(ctx, AV_LOG_WARNING, "Time base is inaccurate\n");
85 }
86 1 return 0;
87 }
88
89 20 static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
90 {
91 20 AVFilterContext *ctx = inlink->dst;
92 20 ASetRateContext *sr = ctx->priv;
93 20 AVFilterLink *outlink = ctx->outputs[0];
94
95 20 frame->sample_rate = outlink->sample_rate;
96
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 if (sr->rescale_pts)
97 frame->pts = av_rescale(frame->pts, inlink->sample_rate,
98 outlink->sample_rate);
99 20 return ff_filter_frame(outlink, frame);
100 }
101
102 static const AVFilterPad asetrate_inputs[] = {
103 {
104 .name = "default",
105 .type = AVMEDIA_TYPE_AUDIO,
106 .filter_frame = filter_frame,
107 },
108 };
109
110 static const AVFilterPad asetrate_outputs[] = {
111 {
112 .name = "default",
113 .type = AVMEDIA_TYPE_AUDIO,
114 .config_props = config_props,
115 },
116 };
117
118 const AVFilter ff_af_asetrate = {
119 .name = "asetrate",
120 .description = NULL_IF_CONFIG_SMALL("Change the sample rate without "
121 "altering the data."),
122 .priv_size = sizeof(ASetRateContext),
123 FILTER_INPUTS(asetrate_inputs),
124 FILTER_OUTPUTS(asetrate_outputs),
125 FILTER_QUERY_FUNC(query_formats),
126 .priv_class = &asetrate_class,
127 .flags = AVFILTER_FLAG_METADATA_ONLY,
128 };
129