FFmpeg
af_join.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 /**
20  * @file
21  * Audio join filter
22  *
23  * Join multiple audio inputs as different channels in
24  * a single output
25  */
26 
27 #include "libavutil/avstring.h"
29 #include "libavutil/common.h"
30 #include "libavutil/opt.h"
31 
32 #include "audio.h"
33 #include "avfilter.h"
34 #include "formats.h"
35 #include "filters.h"
36 #include "internal.h"
37 
38 typedef struct ChannelMap {
39  int input; ///< input stream index
40  int in_channel_idx; ///< index of in_channel in the input stream data
41  uint64_t in_channel; ///< layout describing the input channel
42  uint64_t out_channel; ///< layout describing the output channel
43 } ChannelMap;
44 
45 typedef struct JoinContext {
46  const AVClass *class;
47 
48  int inputs;
49  char *map;
51  uint64_t channel_layout;
52 
53  int64_t eof_pts;
54 
57 
58  /**
59  * Temporary storage for input frames, until we get one on each input.
60  */
62 
63  /**
64  * Temporary storage for buffer references, for assembling the output frame.
65  */
67 } JoinContext;
68 
69 #define OFFSET(x) offsetof(JoinContext, x)
70 #define A AV_OPT_FLAG_AUDIO_PARAM
71 #define F AV_OPT_FLAG_FILTERING_PARAM
72 static const AVOption join_options[] = {
73  { "inputs", "Number of input streams.", OFFSET(inputs), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, INT_MAX, A|F },
74  { "channel_layout", "Channel layout of the "
75  "output stream.", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, {.str = "stereo"}, 0, 0, A|F },
76  { "map", "A comma-separated list of channels maps in the format "
77  "'input_stream.input_channel-output_channel.",
78  OFFSET(map), AV_OPT_TYPE_STRING, .flags = A|F },
79  { NULL }
80 };
81 
83 
85 {
86  JoinContext *s = ctx->priv;
87  char separator = '|';
88  char *cur = s->map;
89 
90  while (cur && *cur) {
91  char *sep, *next, *p;
92  uint64_t in_channel = 0, out_channel = 0;
93  int input_idx, out_ch_idx, in_ch_idx;
94 
95  next = strchr(cur, separator);
96  if (next)
97  *next++ = 0;
98 
99  /* split the map into input and output parts */
100  if (!(sep = strchr(cur, '-'))) {
101  av_log(ctx, AV_LOG_ERROR, "Missing separator '-' in channel "
102  "map '%s'\n", cur);
103  return AVERROR(EINVAL);
104  }
105  *sep++ = 0;
106 
107 #define PARSE_CHANNEL(str, var, inout) \
108  if (!(var = av_get_channel_layout(str))) { \
109  av_log(ctx, AV_LOG_ERROR, "Invalid " inout " channel: %s.\n", str);\
110  return AVERROR(EINVAL); \
111  } \
112  if (av_get_channel_layout_nb_channels(var) != 1) { \
113  av_log(ctx, AV_LOG_ERROR, "Channel map describes more than one " \
114  inout " channel.\n"); \
115  return AVERROR(EINVAL); \
116  }
117 
118  /* parse output channel */
119  PARSE_CHANNEL(sep, out_channel, "output");
120  if (!(out_channel & s->channel_layout)) {
121  av_log(ctx, AV_LOG_ERROR, "Output channel '%s' is not present in "
122  "requested channel layout.\n", sep);
123  return AVERROR(EINVAL);
124  }
125 
126  out_ch_idx = av_get_channel_layout_channel_index(s->channel_layout,
127  out_channel);
128  if (s->channels[out_ch_idx].input >= 0) {
129  av_log(ctx, AV_LOG_ERROR, "Multiple maps for output channel "
130  "'%s'.\n", sep);
131  return AVERROR(EINVAL);
132  }
133 
134  /* parse input channel */
135  input_idx = strtol(cur, &cur, 0);
136  if (input_idx < 0 || input_idx >= s->inputs) {
137  av_log(ctx, AV_LOG_ERROR, "Invalid input stream index: %d.\n",
138  input_idx);
139  return AVERROR(EINVAL);
140  }
141 
142  if (*cur)
143  cur++;
144 
145  in_ch_idx = strtol(cur, &p, 0);
146  if (p == cur) {
147  /* channel specifier is not a number,
148  * try to parse as channel name */
149  PARSE_CHANNEL(cur, in_channel, "input");
150  }
151 
152  s->channels[out_ch_idx].input = input_idx;
153  if (in_channel)
154  s->channels[out_ch_idx].in_channel = in_channel;
155  else
156  s->channels[out_ch_idx].in_channel_idx = in_ch_idx;
157 
158  cur = next;
159  }
160  return 0;
161 }
162 
164 {
165  JoinContext *s = ctx->priv;
166  int ret, i;
167 
168  if (!(s->channel_layout = av_get_channel_layout(s->channel_layout_str))) {
169  av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout '%s'.\n",
170  s->channel_layout_str);
171  return AVERROR(EINVAL);
172  }
173 
174  s->nb_channels = av_get_channel_layout_nb_channels(s->channel_layout);
175  s->channels = av_calloc(s->nb_channels, sizeof(*s->channels));
176  s->buffers = av_calloc(s->nb_channels, sizeof(*s->buffers));
177  s->input_frames = av_calloc(s->inputs, sizeof(*s->input_frames));
178  if (!s->channels || !s->buffers|| !s->input_frames)
179  return AVERROR(ENOMEM);
180 
181  for (i = 0; i < s->nb_channels; i++) {
182  s->channels[i].out_channel = av_channel_layout_extract_channel(s->channel_layout, i);
183  s->channels[i].input = -1;
184  }
185 
186  if ((ret = parse_maps(ctx)) < 0)
187  return ret;
188 
189  for (i = 0; i < s->inputs; i++) {
190  AVFilterPad pad = { 0 };
191 
192  pad.type = AVMEDIA_TYPE_AUDIO;
193  pad.name = av_asprintf("input%d", i);
194  if (!pad.name)
195  return AVERROR(ENOMEM);
196 
197  if ((ret = ff_append_inpad_free_name(ctx, &pad)) < 0)
198  return ret;
199  }
200 
201  return 0;
202 }
203 
205 {
206  JoinContext *s = ctx->priv;
207  int i;
208 
209  for (i = 0; i < s->inputs && s->input_frames; i++) {
210  av_frame_free(&s->input_frames[i]);
211  }
212 
213  av_freep(&s->channels);
214  av_freep(&s->buffers);
215  av_freep(&s->input_frames);
216 }
217 
219 {
220  JoinContext *s = ctx->priv;
222  int i, ret;
223 
224  if ((ret = ff_add_channel_layout(&layouts, s->channel_layout)) < 0 ||
225  (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0)
226  return ret;
227 
228  for (i = 0; i < ctx->nb_inputs; i++) {
230  if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->outcfg.channel_layouts)) < 0)
231  return ret;
232  }
233 
236  return ret;
237 
238  return 0;
239 }
240 
242  uint64_t *inputs)
243 {
244  int i;
245 
246  for (i = 0; i < ctx->nb_inputs; i++) {
247  AVFilterLink *link = ctx->inputs[i];
248 
249  if (ch->out_channel & link->channel_layout &&
250  !(ch->out_channel & inputs[i])) {
251  ch->input = i;
252  ch->in_channel = ch->out_channel;
253  inputs[i] |= ch->out_channel;
254  return;
255  }
256  }
257 }
258 
260  uint64_t *inputs)
261 {
262  int i;
263 
264  for (i = 0; i < ctx->nb_inputs; i++) {
265  AVFilterLink *link = ctx->inputs[i];
266 
267  if ((inputs[i] & link->channel_layout) != link->channel_layout) {
268  uint64_t unused = link->channel_layout & ~inputs[i];
269 
270  ch->input = i;
272  inputs[i] |= ch->in_channel;
273  return;
274  }
275  }
276 }
277 
278 static int join_config_output(AVFilterLink *outlink)
279 {
280  AVFilterContext *ctx = outlink->src;
281  JoinContext *s = ctx->priv;
282  uint64_t *inputs; // nth element tracks which channels are used from nth input
283  int i, ret = 0;
284 
285  /* initialize inputs to user-specified mappings */
286  if (!(inputs = av_calloc(ctx->nb_inputs, sizeof(*inputs))))
287  return AVERROR(ENOMEM);
288  for (i = 0; i < s->nb_channels; i++) {
289  ChannelMap *ch = &s->channels[i];
291 
292  if (ch->input < 0)
293  continue;
294 
295  inlink = ctx->inputs[ch->input];
296 
297  if (!ch->in_channel)
299  ch->in_channel_idx);
300 
301  if (!(ch->in_channel & inlink->channel_layout)) {
302  av_log(ctx, AV_LOG_ERROR, "Requested channel %s is not present in "
303  "input stream #%d.\n", av_get_channel_name(ch->in_channel),
304  ch->input);
305  ret = AVERROR(EINVAL);
306  goto fail;
307  }
308 
309  inputs[ch->input] |= ch->in_channel;
310  }
311 
312  /* guess channel maps when not explicitly defined */
313  /* first try unused matching channels */
314  for (i = 0; i < s->nb_channels; i++) {
315  ChannelMap *ch = &s->channels[i];
316 
317  if (ch->input < 0)
319  }
320 
321  /* if the above failed, try to find _any_ unused input channel */
322  for (i = 0; i < s->nb_channels; i++) {
323  ChannelMap *ch = &s->channels[i];
324 
325  if (ch->input < 0)
326  guess_map_any(ctx, ch, inputs);
327 
328  if (ch->input < 0) {
329  av_log(ctx, AV_LOG_ERROR, "Could not find input channel for "
330  "output channel '%s'.\n",
332  goto fail;
333  }
334 
335  ch->in_channel_idx = av_get_channel_layout_channel_index(ctx->inputs[ch->input]->channel_layout,
336  ch->in_channel);
337  }
338 
339  /* print mappings */
340  av_log(ctx, AV_LOG_VERBOSE, "mappings: ");
341  for (i = 0; i < s->nb_channels; i++) {
342  ChannelMap *ch = &s->channels[i];
343  av_log(ctx, AV_LOG_VERBOSE, "%d.%s => %s ", ch->input,
346  }
347  av_log(ctx, AV_LOG_VERBOSE, "\n");
348 
349  for (i = 0; i < ctx->nb_inputs; i++) {
350  if (!inputs[i])
351  av_log(ctx, AV_LOG_WARNING, "No channels are used from input "
352  "stream %d.\n", i);
353  }
354 
355 fail:
356  av_freep(&inputs);
357  return ret;
358 }
359 
361 {
362  AVFilterLink *outlink = ctx->outputs[0];
363  JoinContext *s = ctx->priv;
364  AVFrame *frame;
365  int linesize = INT_MAX;
366  int nb_samples = INT_MAX;
367  int nb_buffers = 0;
368  int i, j, ret;
369 
370  for (i = 0; i < ctx->nb_inputs; i++) {
371  if (!s->input_frames[i]) {
372  nb_samples = 0;
373  break;
374  } else {
375  nb_samples = FFMIN(nb_samples, s->input_frames[i]->nb_samples);
376  }
377  }
378  if (!nb_samples)
379  goto eof;
380 
381  /* setup the output frame */
382  frame = av_frame_alloc();
383  if (!frame)
384  return AVERROR(ENOMEM);
385  if (s->nb_channels > FF_ARRAY_ELEMS(frame->data)) {
386  frame->extended_data = av_calloc(s->nb_channels,
387  sizeof(*frame->extended_data));
388  if (!frame->extended_data) {
389  ret = AVERROR(ENOMEM);
390  goto fail;
391  }
392  }
393 
394  /* copy the data pointers */
395  for (i = 0; i < s->nb_channels; i++) {
396  ChannelMap *ch = &s->channels[i];
397  AVFrame *cur = s->input_frames[ch->input];
398  AVBufferRef *buf;
399 
400  frame->extended_data[i] = cur->extended_data[ch->in_channel_idx];
401  linesize = FFMIN(linesize, cur->linesize[0]);
402 
403  /* add the buffer where this plan is stored to the list if it's
404  * not already there */
406  if (!buf) {
407  ret = AVERROR(EINVAL);
408  goto fail;
409  }
410  for (j = 0; j < nb_buffers; j++)
411  if (s->buffers[j]->buffer == buf->buffer)
412  break;
413  if (j == i)
414  s->buffers[nb_buffers++] = buf;
415  }
416 
417  /* create references to the buffers we copied to output */
418  if (nb_buffers > FF_ARRAY_ELEMS(frame->buf)) {
419  frame->nb_extended_buf = nb_buffers - FF_ARRAY_ELEMS(frame->buf);
420  frame->extended_buf = av_calloc(frame->nb_extended_buf,
421  sizeof(*frame->extended_buf));
422  if (!frame->extended_buf) {
423  frame->nb_extended_buf = 0;
424  ret = AVERROR(ENOMEM);
425  goto fail;
426  }
427  }
428  for (i = 0; i < FFMIN(FF_ARRAY_ELEMS(frame->buf), nb_buffers); i++) {
429  frame->buf[i] = av_buffer_ref(s->buffers[i]);
430  if (!frame->buf[i]) {
431  ret = AVERROR(ENOMEM);
432  goto fail;
433  }
434  }
435  for (i = 0; i < frame->nb_extended_buf; i++) {
436  frame->extended_buf[i] = av_buffer_ref(s->buffers[i +
437  FF_ARRAY_ELEMS(frame->buf)]);
438  if (!frame->extended_buf[i]) {
439  ret = AVERROR(ENOMEM);
440  goto fail;
441  }
442  }
443 
444  frame->nb_samples = nb_samples;
445  frame->channel_layout = outlink->channel_layout;
446  frame->channels = outlink->channels;
447  frame->sample_rate = outlink->sample_rate;
448  frame->format = outlink->format;
449  frame->pts = s->input_frames[0]->pts;
450  frame->linesize[0] = linesize;
451  if (frame->data != frame->extended_data) {
452  memcpy(frame->data, frame->extended_data, sizeof(*frame->data) *
453  FFMIN(FF_ARRAY_ELEMS(frame->data), s->nb_channels));
454  }
455 
456  s->eof_pts = frame->pts + av_rescale_q(frame->nb_samples,
457  av_make_q(1, outlink->sample_rate),
458  outlink->time_base);
459  ret = ff_filter_frame(outlink, frame);
460 
461  for (i = 0; i < ctx->nb_inputs; i++)
462  av_frame_free(&s->input_frames[i]);
463 
464  return ret;
465 
466 fail:
468  return ret;
469 eof:
470  for (i = 0; i < ctx->nb_inputs; i++) {
471  if (ff_outlink_get_status(ctx->inputs[i]) &&
472  ff_inlink_queued_samples(ctx->inputs[i]) <= 0 &&
473  !s->input_frames[i]) {
474  ff_outlink_set_status(outlink, AVERROR_EOF, s->eof_pts);
475  }
476  }
477 
478  return 0;
479 }
480 
482 {
483  JoinContext *s = ctx->priv;
484  int i, ret, status;
485  int nb_samples = 0;
486  int64_t pts;
487 
489 
490  if (!s->input_frames[0]) {
491  ret = ff_inlink_consume_frame(ctx->inputs[0], &s->input_frames[0]);
492  if (ret < 0) {
493  return ret;
494  } else if (ret == 0 && ff_inlink_acknowledge_status(ctx->inputs[0], &status, &pts)) {
495  ff_outlink_set_status(ctx->outputs[0], status, s->eof_pts);
496  return 0;
497  }
498 
499  if (!s->input_frames[0] && ff_outlink_frame_wanted(ctx->outputs[0])) {
500  ff_inlink_request_frame(ctx->inputs[0]);
501  return 0;
502  }
503  }
504 
505  nb_samples = s->input_frames[0]->nb_samples;
506 
507  for (i = 1; i < ctx->nb_inputs && nb_samples > 0; i++) {
508  if (s->input_frames[i])
509  continue;
510  ret = ff_inlink_consume_samples(ctx->inputs[i], nb_samples, nb_samples, &s->input_frames[i]);
511  if (ret < 0) {
512  return ret;
513  } else if (ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts)) {
514  ff_outlink_set_status(ctx->outputs[0], status, pts);
515  return 0;
516  }
517 
518  if (!s->input_frames[i]) {
519  ff_inlink_request_frame(ctx->inputs[i]);
520  return 0;
521  }
522  }
523 
524  return try_push_frame(ctx);
525 }
526 
528  {
529  .name = "default",
530  .type = AVMEDIA_TYPE_AUDIO,
531  .config_props = join_config_output,
532  },
533 };
534 
536  .name = "join",
537  .description = NULL_IF_CONFIG_SMALL("Join multiple audio streams into "
538  "multi-channel output."),
539  .priv_size = sizeof(JoinContext),
540  .priv_class = &join_class,
541  .init = join_init,
542  .uninit = join_uninit,
543  .activate = activate,
544  .inputs = NULL,
548 };
ChannelMap::in_channel
uint64_t in_channel
layout describing the input channel
Definition: af_channelmap.c:41
AVFilterChannelLayouts
A list of supported channel layouts.
Definition: formats.h:85
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
status
they must not be accessed directly The fifo field contains the frames that are queued in the input for processing by the filter The status_in and status_out fields contains the queued status(EOF or error) of the link
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1018
ff_channel_layouts_ref
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:550
layouts
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
guess_map_matching
static void guess_map_matching(AVFilterContext *ctx, ChannelMap *ch, uint64_t *inputs)
Definition: af_join.c:241
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
av_asprintf
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:113
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:109
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:317
AVOption
AVOption.
Definition: opt.h:247
FILTER_QUERY_FUNC
#define FILTER_QUERY_FUNC(func)
Definition: internal.h:168
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
ff_set_common_all_samplerates
int ff_set_common_all_samplerates(AVFilterContext *ctx)
Equivalent to ff_set_common_samplerates(ctx, ff_all_samplerates())
Definition: formats.c:689
av_get_channel_layout
uint64_t av_get_channel_layout(const char *name)
Return a channel layout id that matches name, or 0 if no match is found.
Definition: channel_layout.c:145
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:169
formats.h
init
static int init
Definition: av_tx.c:47
ff_inlink_consume_frame
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
Definition: avfilter.c:1417
FF_FILTER_FORWARD_STATUS_BACK_ALL
#define FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, filter)
Forward the status on an output link to all input links.
Definition: filters.h:212
fail
#define fail()
Definition: checkasm.h:127
ChannelMap::input
int input
input stream index
Definition: af_join.c:39
join_query_formats
static int join_query_formats(AVFilterContext *ctx)
Definition: af_join.c:218
pts
static int64_t pts
Definition: transcode_aac.c:653
AVFILTER_FLAG_DYNAMIC_INPUTS
#define AVFILTER_FLAG_DYNAMIC_INPUTS
The number of the filter inputs is not determined just by AVFilter.inputs.
Definition: avfilter.h:110
JoinContext::buffers
AVBufferRef ** buffers
Temporary storage for buffer references, for assembling the output frame.
Definition: af_join.c:66
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:50
JoinContext::input_frames
AVFrame ** input_frames
Temporary storage for input frames, until we get one on each input.
Definition: af_join.c:61
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:97
parse_maps
static int parse_maps(AVFilterContext *ctx)
Definition: af_join.c:84
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
ff_set_common_formats
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:699
ff_outlink_set_status
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
ff_add_channel_layout
int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
Definition: formats.c:426
ff_inlink_request_frame
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition: avfilter.c:1534
s
#define s(width, name)
Definition: cbs_vp9.c:257
JoinContext::nb_channels
int nb_channels
Definition: af_join.c:55
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
filters.h
av_get_channel_name
const char * av_get_channel_name(uint64_t channel)
Get the name of a given channel.
Definition: channel_layout.c:249
ctx
AVFormatContext * ctx
Definition: movenc.c:48
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:141
link
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a link
Definition: filter_design.txt:23
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
ff_inlink_consume_samples
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:1436
NULL
#define NULL
Definition: coverity.c:32
ff_append_inpad_free_name
int ff_append_inpad_free_name(AVFilterContext *f, AVFilterPad *p)
Definition: avfilter.c:144
inputs
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
Definition: filter_design.txt:243
join_options
static const AVOption join_options[]
Definition: af_join.c:72
ff_inlink_acknowledge_status
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:1371
av_get_channel_layout_nb_channels
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
Definition: channel_layout.c:226
JoinContext::channel_layout_str
char * channel_layout_str
Definition: af_join.c:50
F
#define F
Definition: af_join.c:71
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
ChannelMap::out_channel
uint64_t out_channel
layout describing the output channel
Definition: af_channelmap.c:42
PARSE_CHANNEL
#define PARSE_CHANNEL(str, var, inout)
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
A
#define A
Definition: af_join.c:70
AVFrame::channel_layout
uint64_t channel_layout
Channel layout of the audio data.
Definition: frame.h:499
AVBufferRef::buffer
AVBuffer * buffer
Definition: buffer.h:83
ChannelMap::in_channel_idx
int in_channel_idx
index of in_channel in the input stream data
Definition: af_channelmap.c:43
ff_all_channel_layouts
AVFilterChannelLayouts * ff_all_channel_layouts(void)
Construct an empty AVFilterChannelLayouts/AVFilterFormats struct – representing any channel layout (w...
Definition: formats.c:516
JoinContext
Definition: af_join.c:45
internal.h
join_uninit
static av_cold void join_uninit(AVFilterContext *ctx)
Definition: af_join.c:204
OFFSET
#define OFFSET(x)
Definition: af_join.c:69
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
av_channel_layout_extract_channel
uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
Get the channel with the given index in channel_layout.
Definition: channel_layout.c:271
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:378
common.h
av_get_channel_layout_channel_index
int av_get_channel_layout_channel_index(uint64_t channel_layout, uint64_t channel)
Get the index of a channel in channel_layout.
Definition: channel_layout.c:239
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
ff_planar_sample_fmts
AVFilterFormats * ff_planar_sample_fmts(void)
Construct a formats list containing all planar sample formats.
Definition: formats.c:497
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:56
ff_inlink_queued_samples
int ff_inlink_queued_samples(AVFilterLink *link)
Definition: avfilter.c:1396
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:271
activate
static int activate(AVFilterContext *ctx)
Definition: af_join.c:481
AVFilter
Filter definition.
Definition: avfilter.h:165
avfilter_af_join_outputs
static const AVFilterPad avfilter_af_join_outputs[]
Definition: af_join.c:527
ret
ret
Definition: filter_design.txt:187
AVFilterPad::type
enum AVMediaType type
AVFilterPad type.
Definition: internal.h:61
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
JoinContext::inputs
int inputs
Definition: af_join.c:48
JoinContext::eof_pts
int64_t eof_pts
Definition: af_join.c:53
channel_layout.h
JoinContext::map
char * map
Definition: af_join.c:49
JoinContext::channels
ChannelMap * channels
Definition: af_join.c:56
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:224
avfilter.h
guess_map_any
static void guess_map_any(AVFilterContext *ctx, ChannelMap *ch, uint64_t *inputs)
Definition: af_join.c:259
ChannelMap
Definition: opus.h:147
ff_outlink_get_status
int ff_outlink_get_status(AVFilterLink *link)
Get the status on an output link.
Definition: avfilter.c:1557
AVFilterContext
An instance of a filter.
Definition: avfilter.h:402
audio.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
join_config_output
static int join_config_output(AVFilterLink *outlink)
Definition: af_join.c:278
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:192
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
join_init
static av_cold int join_init(AVFilterContext *ctx)
Definition: af_join.c:163
ff_af_join
const AVFilter ff_af_join
Definition: af_join.c:535
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:362
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
av_frame_get_plane_buffer
AVBufferRef * av_frame_get_plane_buffer(AVFrame *frame, int plane)
Get the buffer reference a given data plane is stored in.
Definition: frame.c:542
uninit
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:282
ff_outlink_frame_wanted
the definition of that something depends on the semantic of the filter The callback must examine the status of the filter s links and proceed accordingly The status of output links is stored in the status_in and status_out fields and tested by the ff_outlink_frame_wanted() function. If this function returns true
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:228
try_push_frame
static int try_push_frame(AVFilterContext *ctx)
Definition: af_join.c:360
JoinContext::channel_layout
uint64_t channel_layout
Definition: af_join.c:51
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(join)