FFmpeg  4.4.5
af_amultiply.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 Paul B Mahol
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/avassert.h"
23 #include "libavutil/common.h"
24 #include "libavutil/float_dsp.h"
25 #include "libavutil/opt.h"
26 
27 #include "audio.h"
28 #include "avfilter.h"
29 #include "formats.h"
30 #include "filters.h"
31 #include "internal.h"
32 
33 typedef struct AudioMultiplyContext {
34  const AVClass *class;
35 
37  int planes;
38  int channels;
40 
43 
45 {
48  static const enum AVSampleFormat sample_fmts[] = {
52  };
53  int ret;
54 
56  if (!layouts)
57  return AVERROR(ENOMEM);
59  if (ret < 0)
60  return ret;
61 
63  if (!formats)
64  return AVERROR(ENOMEM);
66  if (ret < 0)
67  return ret;
68 
70  if (!formats)
71  return AVERROR(ENOMEM);
73 }
74 
76 {
77  AudioMultiplyContext *s = ctx->priv;
78  int i, ret, status;
79  int nb_samples;
80  int64_t pts;
81 
83 
84  nb_samples = FFMIN(ff_inlink_queued_samples(ctx->inputs[0]),
85  ff_inlink_queued_samples(ctx->inputs[1]));
86  for (i = 0; i < ctx->nb_inputs && nb_samples > 0; i++) {
87  if (s->frames[i])
88  continue;
89 
90  if (ff_inlink_check_available_samples(ctx->inputs[i], nb_samples) > 0) {
91  ret = ff_inlink_consume_samples(ctx->inputs[i], nb_samples, nb_samples, &s->frames[i]);
92  if (ret < 0)
93  return ret;
94  }
95  }
96 
97  if (s->frames[0] && s->frames[1]) {
98  AVFrame *out;
99  int plane_samples;
100 
101  if (av_sample_fmt_is_planar(ctx->inputs[0]->format))
102  plane_samples = FFALIGN(s->frames[0]->nb_samples, s->samples_align);
103  else
104  plane_samples = FFALIGN(s->frames[0]->nb_samples * s->channels, s->samples_align);
105 
106  out = ff_get_audio_buffer(ctx->outputs[0], s->frames[0]->nb_samples);
107  if (!out)
108  return AVERROR(ENOMEM);
109 
110  out->pts = s->frames[0]->pts;
111 
112  if (av_get_packed_sample_fmt(ctx->inputs[0]->format) == AV_SAMPLE_FMT_FLT) {
113  for (i = 0; i < s->planes; i++) {
114  s->fdsp->vector_fmul((float *)out->extended_data[i],
115  (const float *)s->frames[0]->extended_data[i],
116  (const float *)s->frames[1]->extended_data[i],
117  plane_samples);
118  }
119  } else {
120  for (i = 0; i < s->planes; i++) {
121  s->fdsp->vector_dmul((double *)out->extended_data[i],
122  (const double *)s->frames[0]->extended_data[i],
123  (const double *)s->frames[1]->extended_data[i],
124  plane_samples);
125  }
126  }
127  emms_c();
128 
129  av_frame_free(&s->frames[0]);
130  av_frame_free(&s->frames[1]);
131 
132  ret = ff_filter_frame(ctx->outputs[0], out);
133  if (ret < 0)
134  return ret;
135  }
136 
137  if (!nb_samples) {
138  for (i = 0; i < 2; i++) {
139  if (ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts)) {
140  ff_outlink_set_status(ctx->outputs[0], status, pts);
141  return 0;
142  }
143  }
144  }
145 
146  if (ff_outlink_frame_wanted(ctx->outputs[0])) {
147  for (i = 0; i < 2; i++) {
148  if (ff_inlink_queued_samples(ctx->inputs[i]) > 0)
149  continue;
150  ff_inlink_request_frame(ctx->inputs[i]);
151  return 0;
152  }
153  }
154  return 0;
155 }
156 
157 static int config_output(AVFilterLink *outlink)
158 {
159  AVFilterContext *ctx = outlink->src;
160  AudioMultiplyContext *s = ctx->priv;
161  AVFilterLink *inlink = ctx->inputs[0];
162 
163  s->channels = inlink->channels;
164  s->planes = av_sample_fmt_is_planar(inlink->format) ? inlink->channels : 1;
165  s->samples_align = 16;
166 
167  return 0;
168 }
169 
171 {
172  AudioMultiplyContext *s = ctx->priv;
173 
174  s->fdsp = avpriv_float_dsp_alloc(0);
175  if (!s->fdsp)
176  return AVERROR(ENOMEM);
177 
178  return 0;
179 }
180 
182 {
183  AudioMultiplyContext *s = ctx->priv;
184  av_freep(&s->fdsp);
185 }
186 
187 static const AVFilterPad inputs[] = {
188  {
189  .name = "multiply0",
190  .type = AVMEDIA_TYPE_AUDIO,
191  },
192  {
193  .name = "multiply1",
194  .type = AVMEDIA_TYPE_AUDIO,
195  },
196  { NULL }
197 };
198 
199 static const AVFilterPad outputs[] = {
200  {
201  .name = "default",
202  .type = AVMEDIA_TYPE_AUDIO,
203  .config_props = config_output,
204  },
205  { NULL }
206 };
207 
209  .name = "amultiply",
210  .description = NULL_IF_CONFIG_SMALL("Multiply two audio streams."),
211  .priv_size = sizeof(AudioMultiplyContext),
212  .init = init,
213  .uninit = uninit,
214  .activate = activate,
216  .inputs = inputs,
217  .outputs = outputs,
218 };
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:925
static int query_formats(AVFilterContext *ctx)
Definition: af_amultiply.c:44
static const AVFilterPad inputs[]
Definition: af_amultiply.c:187
static const AVFilterPad outputs[]
Definition: af_amultiply.c:199
static int activate(AVFilterContext *ctx)
Definition: af_amultiply.c:75
static av_cold int init(AVFilterContext *ctx)
Definition: af_amultiply.c:170
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_amultiply.c:181
static int config_output(AVFilterLink *outlink)
Definition: af_amultiply.c:157
AVFilter ff_af_amultiply
Definition: af_amultiply.c:208
#define av_cold
Definition: attributes.h:88
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:86
simple assert() macros that are a bit more flexible than ISO C assert().
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
Definition: avfilter.c:1449
int ff_inlink_check_available_samples(AVFilterLink *link, unsigned min)
Test if enough samples are available on the link.
Definition: avfilter.c:1479
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1096
int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe)
Take samples from the link's FIFO and update the link's stats.
Definition: avfilter.c:1513
int ff_inlink_queued_samples(AVFilterLink *link)
Definition: avfilter.c:1474
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition: avfilter.c:1620
Main libavfilter public API header.
#define s(width, name)
Definition: cbs_vp9.c:257
audio channel layout utility functions
common internal and external API header
#define FFMIN(a, b)
Definition: common.h:105
#define NULL
Definition: coverity.c:32
long long int64_t
Definition: coverity.c:34
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
Definition: filters.h:189
#define FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, filter)
Forward the status on an output link to all input links.
Definition: filters.h:212
static int ff_outlink_frame_wanted(AVFilterLink *link)
Test if a frame is wanted on an output link.
Definition: filters.h:172
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition.
Definition: formats.c:436
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:587
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:286
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:575
int ff_set_common_channel_layouts(AVFilterContext *ctx, AVFilterChannelLayouts *channel_layouts)
A helper for query_formats() which sets all links to the same list of channel layouts/sample rates.
Definition: formats.c:568
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:421
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
Check if the sample format is planar.
Definition: samplefmt.c:112
enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
Get the packed alternative form of the given sample format.
Definition: samplefmt.c:75
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:69
@ AV_SAMPLE_FMT_FLT
float
Definition: samplefmt.h:63
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition: samplefmt.h:70
@ AV_SAMPLE_FMT_DBL
double
Definition: samplefmt.h:64
int i
Definition: input.c:407
av_cold AVFloatDSPContext * avpriv_float_dsp_alloc(int bit_exact)
Allocate a float DSP context.
Definition: float_dsp.c:135
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
#define emms_c()
Definition: internal.h:54
#define FFALIGN(x, a)
Definition: macros.h:48
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVOptions.
formats
Definition: signature.h:48
Describe the class of an AVClass context structure.
Definition: log.h:67
A list of supported channel layouts.
Definition: formats.h:86
An instance of a filter.
Definition: avfilter.h:341
A list of supported formats for one end of a filter link.
Definition: formats.h:65
A filter pad used for either input or output.
Definition: internal.h:54
const char * name
Pad name.
Definition: internal.h:60
Filter definition.
Definition: avfilter.h:145
const char * name
Filter name.
Definition: avfilter.h:149
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
AVFrame * frames[2]
Definition: af_amultiply.c:36
AVFloatDSPContext * fdsp
Definition: af_amultiply.c:41
#define av_freep(p)
FILE * out
Definition: movenc.c:54
AVFormatContext * ctx
Definition: movenc.c:48
static int64_t pts