FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/af_acontrast.c
Date: 2024-11-20 23:03:26
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 #include "filters.h"
27
28 typedef struct AudioContrastContext {
29 const AVClass *class;
30 float contrast;
31 void (*filter)(void **dst, const void **src,
32 int nb_samples, int channels, float contrast);
33 } AudioContrastContext;
34
35 #define OFFSET(x) offsetof(AudioContrastContext, x)
36 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
37
38 static const AVOption acontrast_options[] = {
39 { "contrast", "set contrast", OFFSET(contrast), AV_OPT_TYPE_FLOAT, {.dbl=33}, 0, 100, A },
40 { NULL }
41 };
42
43 AVFILTER_DEFINE_CLASS(acontrast);
44
45 static void filter_flt(void **d, const void **s,
46 int nb_samples, int channels,
47 float contrast)
48 {
49 const float *src = s[0];
50 float *dst = d[0];
51 int n, c;
52
53 for (n = 0; n < nb_samples; n++) {
54 for (c = 0; c < channels; c++) {
55 float d = src[c] * M_PI_2;
56
57 dst[c] = sinf(d + contrast * sinf(d * 4));
58 }
59
60 dst += c;
61 src += c;
62 }
63 }
64
65 static void filter_dbl(void **d, const void **s,
66 int nb_samples, int channels,
67 float contrast)
68 {
69 const double *src = s[0];
70 double *dst = d[0];
71 int n, c;
72
73 for (n = 0; n < nb_samples; n++) {
74 for (c = 0; c < channels; c++) {
75 double d = src[c] * M_PI_2;
76
77 dst[c] = sin(d + contrast * sin(d * 4));
78 }
79
80 dst += c;
81 src += c;
82 }
83 }
84
85 static void filter_fltp(void **d, const void **s,
86 int nb_samples, int channels,
87 float contrast)
88 {
89 int n, c;
90
91 for (c = 0; c < channels; c++) {
92 const float *src = s[c];
93 float *dst = d[c];
94
95 for (n = 0; n < nb_samples; n++) {
96 float d = src[n] * M_PI_2;
97
98 dst[n] = sinf(d + contrast * sinf(d * 4));
99 }
100 }
101 }
102
103 static void filter_dblp(void **d, const void **s,
104 int nb_samples, int channels,
105 float contrast)
106 {
107 int n, c;
108
109 for (c = 0; c < channels; c++) {
110 const double *src = s[c];
111 double *dst = d[c];
112
113 for (n = 0; n < nb_samples; n++) {
114 double d = src[n] * M_PI_2;
115
116 dst[n] = sin(d + contrast * sin(d * 4));
117 }
118 }
119 }
120
121 static int config_input(AVFilterLink *inlink)
122 {
123 AVFilterContext *ctx = inlink->dst;
124 AudioContrastContext *s = ctx->priv;
125
126 switch (inlink->format) {
127 case AV_SAMPLE_FMT_FLT: s->filter = filter_flt; break;
128 case AV_SAMPLE_FMT_DBL: s->filter = filter_dbl; break;
129 case AV_SAMPLE_FMT_FLTP: s->filter = filter_fltp; break;
130 case AV_SAMPLE_FMT_DBLP: s->filter = filter_dblp; break;
131 }
132
133 return 0;
134 }
135
136 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
137 {
138 AVFilterContext *ctx = inlink->dst;
139 AVFilterLink *outlink = ctx->outputs[0];
140 AudioContrastContext *s = ctx->priv;
141 AVFrame *out;
142
143 if (av_frame_is_writable(in)) {
144 out = in;
145 } else {
146 out = ff_get_audio_buffer(outlink, in->nb_samples);
147 if (!out) {
148 av_frame_free(&in);
149 return AVERROR(ENOMEM);
150 }
151 av_frame_copy_props(out, in);
152 }
153
154 s->filter((void **)out->extended_data, (const void **)in->extended_data,
155 in->nb_samples, in->ch_layout.nb_channels, s->contrast / 750);
156
157 if (out != in)
158 av_frame_free(&in);
159
160 return ff_filter_frame(outlink, out);
161 }
162
163 static const AVFilterPad inputs[] = {
164 {
165 .name = "default",
166 .type = AVMEDIA_TYPE_AUDIO,
167 .filter_frame = filter_frame,
168 .config_props = config_input,
169 },
170 };
171
172 const AVFilter ff_af_acontrast = {
173 .name = "acontrast",
174 .description = NULL_IF_CONFIG_SMALL("Simple audio dynamic range compression/expansion filter."),
175 .priv_size = sizeof(AudioContrastContext),
176 .priv_class = &acontrast_class,
177 FILTER_INPUTS(inputs),
178 FILTER_OUTPUTS(ff_audio_default_filterpad),
179 FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
180 AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBLP),
181 };
182