FFmpeg
Loading...
Searching...
No Matches
af_adenorm.c
Go to the documentation of this file.
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/avassert.h"
21#include "libavutil/opt.h"
22#include "audio.h"
23#include "avfilter.h"
24#include "filters.h"
25
33
34typedef struct ADenormContext {
35 const AVClass *class;
36
37 double level;
38 double level_db;
39 int type;
41
43 const void *src, int nb_samples);
45
46static void dc_denorm_fltp(AVFilterContext *ctx, void *dstp,
47 const void *srcp, int nb_samples)
48{
49 ADenormContext *s = ctx->priv;
50 const float *src = (const float *)srcp;
51 float *dst = (float *)dstp;
52 const float dc = s->level;
53
54 for (int n = 0; n < nb_samples; n++) {
55 dst[n] = src[n] + dc;
56 }
57}
58
59static void dc_denorm_dblp(AVFilterContext *ctx, void *dstp,
60 const void *srcp, int nb_samples)
61{
62 ADenormContext *s = ctx->priv;
63 const double *src = (const double *)srcp;
64 double *dst = (double *)dstp;
65 const double dc = s->level;
66
67 for (int n = 0; n < nb_samples; n++) {
68 dst[n] = src[n] + dc;
69 }
70}
71
72static void ac_denorm_fltp(AVFilterContext *ctx, void *dstp,
73 const void *srcp, int nb_samples)
74{
75 ADenormContext *s = ctx->priv;
76 const float *src = (const float *)srcp;
77 float *dst = (float *)dstp;
78 const float dc = s->level;
79 const int64_t N = s->in_samples;
80
81 for (int n = 0; n < nb_samples; n++) {
82 dst[n] = src[n] + dc * (((N + n) & 1) ? -1.f : 1.f);
83 }
84}
85
86static void ac_denorm_dblp(AVFilterContext *ctx, void *dstp,
87 const void *srcp, int nb_samples)
88{
89 ADenormContext *s = ctx->priv;
90 const double *src = (const double *)srcp;
91 double *dst = (double *)dstp;
92 const double dc = s->level;
93 const int64_t N = s->in_samples;
94
95 for (int n = 0; n < nb_samples; n++) {
96 dst[n] = src[n] + dc * (((N + n) & 1) ? -1. : 1.);
97 }
98}
99
100static void sq_denorm_fltp(AVFilterContext *ctx, void *dstp,
101 const void *srcp, int nb_samples)
102{
103 ADenormContext *s = ctx->priv;
104 const float *src = (const float *)srcp;
105 float *dst = (float *)dstp;
106 const float dc = s->level;
107 const int64_t N = s->in_samples;
108
109 for (int n = 0; n < nb_samples; n++) {
110 dst[n] = src[n] + dc * ((((N + n) >> 8) & 1) ? -1.f : 1.f);
111 }
112}
113
114static void sq_denorm_dblp(AVFilterContext *ctx, void *dstp,
115 const void *srcp, int nb_samples)
116{
117 ADenormContext *s = ctx->priv;
118 const double *src = (const double *)srcp;
119 double *dst = (double *)dstp;
120 const double dc = s->level;
121 const int64_t N = s->in_samples;
122
123 for (int n = 0; n < nb_samples; n++) {
124 dst[n] = src[n] + dc * ((((N + n) >> 8) & 1) ? -1. : 1.);
125 }
126}
127
128static void ps_denorm_fltp(AVFilterContext *ctx, void *dstp,
129 const void *srcp, int nb_samples)
130{
131 ADenormContext *s = ctx->priv;
132 const float *src = (const float *)srcp;
133 float *dst = (float *)dstp;
134 const float dc = s->level;
135 const int64_t N = s->in_samples;
136
137 for (int n = 0; n < nb_samples; n++) {
138 dst[n] = src[n] + dc * (((N + n) & 255) ? 0.f : 1.f);
139 }
140}
141
142static void ps_denorm_dblp(AVFilterContext *ctx, void *dstp,
143 const void *srcp, int nb_samples)
144{
145 ADenormContext *s = ctx->priv;
146 const double *src = (const double *)srcp;
147 double *dst = (double *)dstp;
148 const double dc = s->level;
149 const int64_t N = s->in_samples;
150
151 for (int n = 0; n < nb_samples; n++) {
152 dst[n] = src[n] + dc * (((N + n) & 255) ? 0. : 1.);
153 }
154}
155
156static int config_output(AVFilterLink *outlink)
157{
158 AVFilterContext *ctx = outlink->src;
159 ADenormContext *s = ctx->priv;
160
161 switch (outlink->format) {
163 s->filter[DC_TYPE] = dc_denorm_fltp;
164 s->filter[AC_TYPE] = ac_denorm_fltp;
165 s->filter[SQ_TYPE] = sq_denorm_fltp;
166 s->filter[PS_TYPE] = ps_denorm_fltp;
167 break;
169 s->filter[DC_TYPE] = dc_denorm_dblp;
170 s->filter[AC_TYPE] = ac_denorm_dblp;
171 s->filter[SQ_TYPE] = sq_denorm_dblp;
172 s->filter[PS_TYPE] = ps_denorm_dblp;
173 break;
174 default:
175 av_assert0(0);
176 }
177
178 return 0;
179}
180
181typedef struct ThreadData {
182 AVFrame *in, *out;
183} ThreadData;
184
185static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
186{
187 ADenormContext *s = ctx->priv;
188 ThreadData *td = arg;
189 AVFrame *out = td->out;
190 AVFrame *in = td->in;
191 const int start = ff_slice_pos(in->ch_layout.nb_channels, jobnr, nb_jobs);
192 const int end = ff_slice_pos(in->ch_layout.nb_channels, jobnr + 1, nb_jobs);
193
194 for (int ch = start; ch < end; ch++) {
195 s->filter[s->type](ctx, out->extended_data[ch],
196 in->extended_data[ch],
197 in->nb_samples);
198 }
199
200 return 0;
201}
202
203static int filter_frame(AVFilterLink *inlink, AVFrame *in)
204{
205 AVFilterContext *ctx = inlink->dst;
206 ADenormContext *s = ctx->priv;
207 AVFilterLink *outlink = ctx->outputs[0];
208 ThreadData td;
209 AVFrame *out;
210
211 if (av_frame_is_writable(in)) {
212 out = in;
213 } else {
214 out = ff_get_audio_buffer(outlink, in->nb_samples);
215 if (!out) {
216 av_frame_free(&in);
217 return AVERROR(ENOMEM);
218 }
220 }
221
222 s->level = exp(s->level_db / 20. * M_LN10);
223 td.in = in; td.out = out;
226
227 s->in_samples += in->nb_samples;
228
229 if (out != in)
230 av_frame_free(&in);
231 return ff_filter_frame(outlink, out);
232}
233
234static const AVFilterPad adenorm_inputs[] = {
235 {
236 .name = "default",
237 .type = AVMEDIA_TYPE_AUDIO,
238 .filter_frame = filter_frame,
239 },
240};
241
242static const AVFilterPad adenorm_outputs[] = {
243 {
244 .name = "default",
245 .type = AVMEDIA_TYPE_AUDIO,
246 .config_props = config_output,
247 },
248};
249
250#define OFFSET(x) offsetof(ADenormContext, x)
251#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
252
253static const AVOption adenorm_options[] = {
254 { "level", "set level", OFFSET(level_db), AV_OPT_TYPE_DOUBLE, {.dbl=-351}, -451, -90, FLAGS },
255 { "type", "set type", OFFSET(type), AV_OPT_TYPE_INT, {.i64=DC_TYPE}, 0, NB_TYPES-1, FLAGS, .unit = "type" },
256 { "dc", NULL, 0, AV_OPT_TYPE_CONST, {.i64=DC_TYPE}, 0, 0, FLAGS, .unit = "type"},
257 { "ac", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AC_TYPE}, 0, 0, FLAGS, .unit = "type"},
258 { "square",NULL, 0, AV_OPT_TYPE_CONST, {.i64=SQ_TYPE}, 0, 0, FLAGS, .unit = "type"},
259 { "pulse", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PS_TYPE}, 0, 0, FLAGS, .unit = "type"},
260 { NULL }
261};
262
264
266 .p.name = "adenorm",
267 .p.description = NULL_IF_CONFIG_SMALL("Remedy denormals by adding extremely low-level noise."),
268 .p.priv_class = &adenorm_class,
271 .priv_size = sizeof(ADenormContext),
275 .process_command = ff_filter_process_command,
276};
static int fn filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static void sq_denorm_dblp(AVFilterContext *ctx, void *dstp, const void *srcp, int nb_samples)
Definition af_adenorm.c:114
static void sq_denorm_fltp(AVFilterContext *ctx, void *dstp, const void *srcp, int nb_samples)
Definition af_adenorm.c:100
static const AVOption adenorm_options[]
Definition af_adenorm.c:253
const FFFilter ff_af_adenorm
Definition af_adenorm.c:265
static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition af_adenorm.c:185
static void ac_denorm_dblp(AVFilterContext *ctx, void *dstp, const void *srcp, int nb_samples)
Definition af_adenorm.c:86
static void ps_denorm_fltp(AVFilterContext *ctx, void *dstp, const void *srcp, int nb_samples)
Definition af_adenorm.c:128
static const AVFilterPad adenorm_inputs[]
Definition af_adenorm.c:234
FilterType
Definition af_adenorm.c:26
@ AC_TYPE
Definition af_adenorm.c:28
@ PS_TYPE
Definition af_adenorm.c:30
@ SQ_TYPE
Definition af_adenorm.c:29
@ DC_TYPE
Definition af_adenorm.c:27
@ NB_TYPES
Definition af_adenorm.c:31
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition af_adenorm.c:203
static void dc_denorm_fltp(AVFilterContext *ctx, void *dstp, const void *srcp, int nb_samples)
Definition af_adenorm.c:46
static void dc_denorm_dblp(AVFilterContext *ctx, void *dstp, const void *srcp, int nb_samples)
Definition af_adenorm.c:59
static const AVFilterPad adenorm_outputs[]
Definition af_adenorm.c:242
static void ps_denorm_dblp(AVFilterContext *ctx, void *dstp, const void *srcp, int nb_samples)
Definition af_adenorm.c:142
#define OFFSET(x)
Definition af_adenorm.c:250
static int config_output(AVFilterLink *outlink)
Definition af_adenorm.c:156
static void ac_denorm_fltp(AVFilterContext *ctx, void *dstp, const void *srcp, int nb_samples)
Definition af_adenorm.c:72
#define N
Definition af_mcompand.c:54
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition audio.c:74
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
Definition avfilter.c:906
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition avfilter.c:1696
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition avfilter.c:846
Main libavfilter public API header.
#define s(width, name)
Definition cbs_vp9.c:198
Public libavutil channel layout APIs header.
#define FLAGS
Definition cmdutils.c:598
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
Definition dolby_e.c:1067
int8_t exp
Definition eval.c:76
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
Definition opt.h:266
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
Definition avfilter.h:196
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition avfilter.h:166
#define AVERROR(e)
Definition error.h:45
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition frame.c:535
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition frame.c:599
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition samplefmt.h:66
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition samplefmt.h:67
cl_device_type type
static int config_output(AVBitStreamFilterLink *outlink)
const char * arg
Definition jacosubdec.c:65
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_OUTPUTS(array)
Definition filters.h:265
#define FILTER_SAMPLEFMTS(...)
Definition filters.h:252
static int ff_slice_pos(int total, int jobnr, int nb_jobs)
Compute the boundary index for a slice when work of size total is split into nb_jobs slices.
Definition filters.h:763
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:478
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
#define FFMIN(a, b)
Definition macros.h:49
#define M_LN10
Definition mathematics.h:49
AVOptions.
void(* filter[NB_TYPES])(AVFilterContext *ctx, void *dst, const void *src, int nb_samples)
Definition af_adenorm.c:42
int64_t in_samples
Definition af_adenorm.c:40
double level_db
Definition af_adenorm.c:38
int nb_channels
Number of channels in this layout.
Describe the class of an AVClass context structure.
Definition log.h:76
An instance of a filter.
Definition avfilter.h:273
A filter pad used for either input or output.
Definition filters.h:40
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
int nb_samples
number of audio samples (per channel) described by this frame
Definition frame.h:552
AVChannelLayout ch_layout
Channel layout of the audio data.
Definition frame.h:815
uint8_t ** extended_data
pointers to the data planes/channels.
Definition frame.h:533
AVOption.
Definition opt.h:428
Used for passing data between threads.
Definition dsddec.c:71
AVFrame * out
#define src
Definition vp8dsp.c:248
static FILE * out
Definition movenc.c:55
static AVFormatContext * ctx
Definition movenc.c:49