FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/af_aderivative.c
Date: 2024-04-24 02:45:42
Exec Total Coverage
Lines: 0 48 0.0%
Functions: 0 9 0.0%
Branches: 0 44 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 "audio.h"
21 #include "avfilter.h"
22 #include "internal.h"
23
24 typedef struct ADerivativeContext {
25 const AVClass *class;
26 AVFrame *prev;
27 void (*filter)(void **dst, void **prv, const void **src,
28 int nb_samples, int channels);
29 } ADerivativeContext;
30
31 #define DERIVATIVE(name, type) \
32 static void aderivative_## name ##p(void **d, void **p, const void **s, \
33 int nb_samples, int channels) \
34 { \
35 int n, c; \
36 \
37 for (c = 0; c < channels; c++) { \
38 const type *src = s[c]; \
39 type *dst = d[c]; \
40 type *prv = p[c]; \
41 \
42 for (n = 0; n < nb_samples; n++) { \
43 const type current = src[n]; \
44 \
45 dst[n] = current - prv[0]; \
46 prv[0] = current; \
47 } \
48 } \
49 }
50
51 DERIVATIVE(flt, float)
52 DERIVATIVE(dbl, double)
53 DERIVATIVE(s16, int16_t)
54 DERIVATIVE(s32, int32_t)
55
56 #define INTEGRAL(name, type) \
57 static void aintegral_## name ##p(void **d, void **p, const void **s, \
58 int nb_samples, int channels) \
59 { \
60 int n, c; \
61 \
62 for (c = 0; c < channels; c++) { \
63 const type *src = s[c]; \
64 type *dst = d[c]; \
65 type *prv = p[c]; \
66 \
67 for (n = 0; n < nb_samples; n++) { \
68 const type current = src[n]; \
69 \
70 dst[n] = current + prv[0]; \
71 prv[0] = dst[n]; \
72 } \
73 } \
74 }
75
76 INTEGRAL(flt, float)
77 INTEGRAL(dbl, double)
78
79 static int config_input(AVFilterLink *inlink)
80 {
81 AVFilterContext *ctx = inlink->dst;
82 ADerivativeContext *s = ctx->priv;
83
84 switch (inlink->format) {
85 case AV_SAMPLE_FMT_FLTP: s->filter = aderivative_fltp; break;
86 case AV_SAMPLE_FMT_DBLP: s->filter = aderivative_dblp; break;
87 case AV_SAMPLE_FMT_S32P: s->filter = aderivative_s32p; break;
88 case AV_SAMPLE_FMT_S16P: s->filter = aderivative_s16p; break;
89 }
90
91 if (strcmp(ctx->filter->name, "aintegral"))
92 return 0;
93
94 switch (inlink->format) {
95 case AV_SAMPLE_FMT_FLTP: s->filter = aintegral_fltp; break;
96 case AV_SAMPLE_FMT_DBLP: s->filter = aintegral_dblp; break;
97 }
98
99 return 0;
100 }
101
102 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
103 {
104 AVFilterContext *ctx = inlink->dst;
105 ADerivativeContext *s = ctx->priv;
106 AVFilterLink *outlink = ctx->outputs[0];
107 AVFrame *out;
108
109 if (ctx->is_disabled) {
110 if (s->prev)
111 av_samples_set_silence(s->prev->extended_data, 0, 1,
112 s->prev->ch_layout.nb_channels,
113 s->prev->format);
114
115 return ff_filter_frame(outlink, in);
116 }
117
118 out = ff_get_audio_buffer(outlink, in->nb_samples);
119 if (!out) {
120 av_frame_free(&in);
121 return AVERROR(ENOMEM);
122 }
123 av_frame_copy_props(out, in);
124
125 if (!s->prev) {
126 s->prev = ff_get_audio_buffer(inlink, 1);
127 if (!s->prev) {
128 av_frame_free(&in);
129 return AVERROR(ENOMEM);
130 }
131 }
132
133 s->filter((void **)out->extended_data, (void **)s->prev->extended_data, (const void **)in->extended_data,
134 in->nb_samples, in->ch_layout.nb_channels);
135
136 av_frame_free(&in);
137 return ff_filter_frame(outlink, out);
138 }
139
140 static av_cold void uninit(AVFilterContext *ctx)
141 {
142 ADerivativeContext *s = ctx->priv;
143
144 av_frame_free(&s->prev);
145 }
146
147 static const AVFilterPad aderivative_inputs[] = {
148 {
149 .name = "default",
150 .type = AVMEDIA_TYPE_AUDIO,
151 .filter_frame = filter_frame,
152 .config_props = config_input,
153 },
154 };
155
156 static const AVOption aderivative_options[] = {
157 { NULL }
158 };
159
160 AVFILTER_DEFINE_CLASS_EXT(aderivative, "aderivative/aintegral", aderivative_options);
161
162 const AVFilter ff_af_aderivative = {
163 .name = "aderivative",
164 .description = NULL_IF_CONFIG_SMALL("Compute derivative of input audio."),
165 .priv_size = sizeof(ADerivativeContext),
166 .priv_class = &aderivative_class,
167 .uninit = uninit,
168 FILTER_INPUTS(aderivative_inputs),
169 FILTER_OUTPUTS(ff_audio_default_filterpad),
170 FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_FLTP,
171 AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_DBLP),
172 .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
173 };
174
175 const AVFilter ff_af_aintegral = {
176 .name = "aintegral",
177 .description = NULL_IF_CONFIG_SMALL("Compute integral of input audio."),
178 .priv_size = sizeof(ADerivativeContext),
179 .priv_class = &aderivative_class,
180 .uninit = uninit,
181 FILTER_INPUTS(aderivative_inputs),
182 FILTER_OUTPUTS(ff_audio_default_filterpad),
183 FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_DBLP),
184 .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
185 };
186