FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/af_aderivative.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 0 49 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 "filters.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 av_frame_free(&out);
130 return AVERROR(ENOMEM);
131 }
132 }
133
134 s->filter((void **)out->extended_data, (void **)s->prev->extended_data, (const void **)in->extended_data,
135 in->nb_samples, in->ch_layout.nb_channels);
136
137 av_frame_free(&in);
138 return ff_filter_frame(outlink, out);
139 }
140
141 static av_cold void uninit(AVFilterContext *ctx)
142 {
143 ADerivativeContext *s = ctx->priv;
144
145 av_frame_free(&s->prev);
146 }
147
148 static const AVFilterPad aderivative_inputs[] = {
149 {
150 .name = "default",
151 .type = AVMEDIA_TYPE_AUDIO,
152 .filter_frame = filter_frame,
153 .config_props = config_input,
154 },
155 };
156
157 static const AVOption aderivative_options[] = {
158 { NULL }
159 };
160
161 AVFILTER_DEFINE_CLASS_EXT(aderivative, "aderivative/aintegral", aderivative_options);
162
163 const AVFilter ff_af_aderivative = {
164 .name = "aderivative",
165 .description = NULL_IF_CONFIG_SMALL("Compute derivative of input audio."),
166 .priv_size = sizeof(ADerivativeContext),
167 .priv_class = &aderivative_class,
168 .uninit = uninit,
169 FILTER_INPUTS(aderivative_inputs),
170 FILTER_OUTPUTS(ff_audio_default_filterpad),
171 FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_FLTP,
172 AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_DBLP),
173 .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
174 };
175
176 const AVFilter ff_af_aintegral = {
177 .name = "aintegral",
178 .description = NULL_IF_CONFIG_SMALL("Compute integral of input audio."),
179 .priv_size = sizeof(ADerivativeContext),
180 .priv_class = &aderivative_class,
181 .uninit = uninit,
182 FILTER_INPUTS(aderivative_inputs),
183 FILTER_OUTPUTS(ff_audio_default_filterpad),
184 FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_DBLP),
185 .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
186 };
187