FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/af_acontrast.c
Date: 2024-04-27 00:58:15
Exec Total Coverage
Lines: 0 61 0.0%
Functions: 0 6 0.0%
Branches: 0 27 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2008 Rob Sykes
3 * Copyright (c) 2017 Paul B Mahol
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "libavutil/channel_layout.h"
23 #include "libavutil/opt.h"
24 #include "avfilter.h"
25 #include "audio.h"
26
27 typedef struct AudioContrastContext {
28 const AVClass *class;
29 float contrast;
30 void (*filter)(void **dst, const void **src,
31 int nb_samples, int channels, float contrast);
32 } AudioContrastContext;
33
34 #define OFFSET(x) offsetof(AudioContrastContext, x)
35 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
36
37 static const AVOption acontrast_options[] = {
38 { "contrast", "set contrast", OFFSET(contrast), AV_OPT_TYPE_FLOAT, {.dbl=33}, 0, 100, A },
39 { NULL }
40 };
41
42 AVFILTER_DEFINE_CLASS(acontrast);
43
44 static void filter_flt(void **d, const void **s,
45 int nb_samples, int channels,
46 float contrast)
47 {
48 const float *src = s[0];
49 float *dst = d[0];
50 int n, c;
51
52 for (n = 0; n < nb_samples; n++) {
53 for (c = 0; c < channels; c++) {
54 float d = src[c] * M_PI_2;
55
56 dst[c] = sinf(d + contrast * sinf(d * 4));
57 }
58
59 dst += c;
60 src += c;
61 }
62 }
63
64 static void filter_dbl(void **d, const void **s,
65 int nb_samples, int channels,
66 float contrast)
67 {
68 const double *src = s[0];
69 double *dst = d[0];
70 int n, c;
71
72 for (n = 0; n < nb_samples; n++) {
73 for (c = 0; c < channels; c++) {
74 double d = src[c] * M_PI_2;
75
76 dst[c] = sin(d + contrast * sin(d * 4));
77 }
78
79 dst += c;
80 src += c;
81 }
82 }
83
84 static void filter_fltp(void **d, const void **s,
85 int nb_samples, int channels,
86 float contrast)
87 {
88 int n, c;
89
90 for (c = 0; c < channels; c++) {
91 const float *src = s[c];
92 float *dst = d[c];
93
94 for (n = 0; n < nb_samples; n++) {
95 float d = src[n] * M_PI_2;
96
97 dst[n] = sinf(d + contrast * sinf(d * 4));
98 }
99 }
100 }
101
102 static void filter_dblp(void **d, const void **s,
103 int nb_samples, int channels,
104 float contrast)
105 {
106 int n, c;
107
108 for (c = 0; c < channels; c++) {
109 const double *src = s[c];
110 double *dst = d[c];
111
112 for (n = 0; n < nb_samples; n++) {
113 double d = src[n] * M_PI_2;
114
115 dst[n] = sin(d + contrast * sin(d * 4));
116 }
117 }
118 }
119
120 static int config_input(AVFilterLink *inlink)
121 {
122 AVFilterContext *ctx = inlink->dst;
123 AudioContrastContext *s = ctx->priv;
124
125 switch (inlink->format) {
126 case AV_SAMPLE_FMT_FLT: s->filter = filter_flt; break;
127 case AV_SAMPLE_FMT_DBL: s->filter = filter_dbl; break;
128 case AV_SAMPLE_FMT_FLTP: s->filter = filter_fltp; break;
129 case AV_SAMPLE_FMT_DBLP: s->filter = filter_dblp; break;
130 }
131
132 return 0;
133 }
134
135 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
136 {
137 AVFilterContext *ctx = inlink->dst;
138 AVFilterLink *outlink = ctx->outputs[0];
139 AudioContrastContext *s = ctx->priv;
140 AVFrame *out;
141
142 if (av_frame_is_writable(in)) {
143 out = in;
144 } else {
145 out = ff_get_audio_buffer(outlink, in->nb_samples);
146 if (!out) {
147 av_frame_free(&in);
148 return AVERROR(ENOMEM);
149 }
150 av_frame_copy_props(out, in);
151 }
152
153 s->filter((void **)out->extended_data, (const void **)in->extended_data,
154 in->nb_samples, in->ch_layout.nb_channels, s->contrast / 750);
155
156 if (out != in)
157 av_frame_free(&in);
158
159 return ff_filter_frame(outlink, out);
160 }
161
162 static const AVFilterPad inputs[] = {
163 {
164 .name = "default",
165 .type = AVMEDIA_TYPE_AUDIO,
166 .filter_frame = filter_frame,
167 .config_props = config_input,
168 },
169 };
170
171 const AVFilter ff_af_acontrast = {
172 .name = "acontrast",
173 .description = NULL_IF_CONFIG_SMALL("Simple audio dynamic range compression/expansion filter."),
174 .priv_size = sizeof(AudioContrastContext),
175 .priv_class = &acontrast_class,
176 FILTER_INPUTS(inputs),
177 FILTER_OUTPUTS(ff_audio_default_filterpad),
178 FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
179 AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBLP),
180 };
181