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/avassert.h"
28 #include "libavutil/avstring.h"
30 #include "libavutil/common.h"
31 #include "libavutil/opt.h"
32 
33 #include "audio.h"
34 #include "avfilter.h"
35 #include "formats.h"
36 #include "filters.h"
37 #include "internal.h"
38 
39 typedef struct ChannelMap {
40  int input; ///< input stream index
41  int in_channel_idx; ///< index of in_channel in the input stream data
44 } ChannelMap;
45 
46 typedef struct JoinContext {
47  const AVClass *class;
48 
49  int inputs;
50  char *map;
53 
54  int64_t eof_pts;
55  int eof;
56 
58 
59  /**
60  * Temporary storage for input frames, until we get one on each input.
61  */
63 
64  /**
65  * Temporary storage for buffer references, for assembling the output frame.
66  */
68 } JoinContext;
69 
70 #define OFFSET(x) offsetof(JoinContext, x)
71 #define A AV_OPT_FLAG_AUDIO_PARAM
72 #define F AV_OPT_FLAG_FILTERING_PARAM
73 static const AVOption join_options[] = {
74  { "inputs", "Number of input streams.", OFFSET(inputs), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, INT_MAX, A|F },
75  { "channel_layout", "Channel layout of the "
76  "output stream.", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, {.str = "stereo"}, 0, 0, A|F },
77  { "map", "A comma-separated list of channels maps in the format "
78  "'input_stream.input_channel-output_channel.",
79  OFFSET(map), AV_OPT_TYPE_STRING, .flags = A|F },
80  { NULL }
81 };
82 
83 #define MAP_SEPARATOR '|'
84 
86 
88 {
89  JoinContext *s = ctx->priv;
90  char *cur = s->map;
91 
92  while (cur && *cur) {
93  ChannelMap *map;
94  char *sep, *next, *p;
95  int input_idx, out_ch_idx;
96 
97  next = strchr(cur, MAP_SEPARATOR);
98  if (next)
99  *next++ = 0;
100 
101  /* split the map into input and output parts */
102  if (!(sep = strchr(cur, '-'))) {
103  av_log(ctx, AV_LOG_ERROR, "Missing separator '-' in channel "
104  "map '%s'\n", cur);
105  return AVERROR(EINVAL);
106  }
107  *sep++ = 0;
108 
109  /* parse output channel */
110  out_ch_idx = av_channel_layout_index_from_string(&s->ch_layout, sep);
111  if (out_ch_idx < 0) {
112  av_log(ctx, AV_LOG_ERROR, "Invalid output channel: %s.\n", sep);
113  return AVERROR(EINVAL);
114  }
115 
116  map = &s->channels[out_ch_idx];
117 
118  if (map->input >= 0) {
119  av_log(ctx, AV_LOG_ERROR, "Multiple maps for output channel "
120  "'%s'.\n", sep);
121  return AVERROR(EINVAL);
122  }
123 
124  /* parse input channel */
125  input_idx = strtol(cur, &cur, 0);
126  if (input_idx < 0 || input_idx >= s->inputs) {
127  av_log(ctx, AV_LOG_ERROR, "Invalid input stream index: %d.\n",
128  input_idx);
129  return AVERROR(EINVAL);
130  }
131 
132  if (*cur)
133  cur++;
134 
135  map->input = input_idx;
136  map->in_channel = AV_CHAN_NONE;
137  map->in_channel_idx = strtol(cur, &p, 0);
138  if (p == cur) {
139  /* channel specifier is not a number, handle as channel name */
140  map->in_channel = av_channel_from_string(cur);
141  if (map->in_channel < 0) {
142  av_log(ctx, AV_LOG_ERROR, "Invalid input channel: %s.\n", cur);
143  return AVERROR(EINVAL);
144  }
145  } else if (map->in_channel_idx < 0) {
146  av_log(ctx, AV_LOG_ERROR, "Invalid input channel index: %d\n", map->in_channel_idx);
147  return AVERROR(EINVAL);
148  }
149 
150  cur = next;
151  }
152  return 0;
153 }
154 
156 {
157  JoinContext *s = ctx->priv;
158  int ret, i;
159 
160  ret = av_channel_layout_from_string(&s->ch_layout, s->channel_layout_str);
161  if (ret < 0) {
162 #if FF_API_OLD_CHANNEL_LAYOUT
163  uint64_t mask;
165  mask = av_get_channel_layout(s->channel_layout_str);
166  if (!mask) {
167 #endif
168  av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout '%s'.\n",
169  s->channel_layout_str);
170  return AVERROR(EINVAL);
171 #if FF_API_OLD_CHANNEL_LAYOUT
172  }
174  av_log(ctx, AV_LOG_WARNING, "Channel layout '%s' uses a deprecated syntax.\n",
175  s->channel_layout_str);
176  av_channel_layout_from_mask(&s->ch_layout, mask);
177 #endif
178  }
179 
180  s->channels = av_calloc(s->ch_layout.nb_channels, sizeof(*s->channels));
181  s->buffers = av_calloc(s->ch_layout.nb_channels, sizeof(*s->buffers));
182  s->input_frames = av_calloc(s->inputs, sizeof(*s->input_frames));
183  if (!s->channels || !s->buffers|| !s->input_frames)
184  return AVERROR(ENOMEM);
185 
186  for (i = 0; i < s->ch_layout.nb_channels; i++) {
187  s->channels[i].out_channel = av_channel_layout_channel_from_index(&s->ch_layout, i);
188  s->channels[i].input = -1;
189  s->channels[i].in_channel_idx = -1;
190  s->channels[i].in_channel = AV_CHAN_NONE;
191  }
192 
193  if ((ret = parse_maps(ctx)) < 0)
194  return ret;
195 
196  for (i = 0; i < s->inputs; i++) {
197  AVFilterPad pad = { 0 };
198 
199  pad.type = AVMEDIA_TYPE_AUDIO;
200  pad.name = av_asprintf("input%d", i);
201  if (!pad.name)
202  return AVERROR(ENOMEM);
203 
204  if ((ret = ff_append_inpad_free_name(ctx, &pad)) < 0)
205  return ret;
206  }
207 
208  return 0;
209 }
210 
212 {
213  JoinContext *s = ctx->priv;
214  int i;
215 
216  for (i = 0; i < s->inputs && s->input_frames; i++) {
217  av_frame_free(&s->input_frames[i]);
218  }
219 
220  av_freep(&s->channels);
221  av_freep(&s->buffers);
222  av_freep(&s->input_frames);
223 }
224 
226 {
227  JoinContext *s = ctx->priv;
229  int i, ret;
230 
231  if ((ret = ff_add_channel_layout(&layouts, &s->ch_layout)) < 0 ||
232  (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0)
233  return ret;
234 
235  for (i = 0; i < ctx->nb_inputs; i++) {
237  if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->outcfg.channel_layouts)) < 0)
238  return ret;
239  }
240 
243  return ret;
244 
245  return 0;
246 }
247 
248 typedef struct ChannelList {
249  enum AVChannel *ch;
250  int nb_ch;
251 } ChannelList;
252 
253 static enum AVChannel channel_list_pop(ChannelList *chl, int idx)
254 {
255  enum AVChannel ret = chl->ch[idx];
256  memmove(chl->ch + idx, chl->ch + idx + 1,
257  (chl->nb_ch - idx - 1) * sizeof(*chl->ch));
258  chl->nb_ch--;
259  return ret;
260 }
261 
262 /*
263  * If ch is present in chl, remove it from the list and return it.
264  * Otherwise return AV_CHAN_NONE.
265  */
267 {
268  for (int i = 0; i < chl->nb_ch; i++)
269  if (chl->ch[i] == ch)
270  return channel_list_pop(chl, i);
271  return AV_CHAN_NONE;
272 }
273 
276 {
277  int i;
278 
279  for (i = 0; i < ctx->nb_inputs; i++) {
281  ch->input = i;
282  ch->in_channel = ch->out_channel;
283  return;
284  }
285  }
286 }
287 
290 {
291  int i;
292 
293  for (i = 0; i < ctx->nb_inputs; i++) {
294  if (inputs[i].nb_ch) {
295  ch->input = i;
296  ch->in_channel = channel_list_pop(&inputs[i], 0);
297  return;
298  }
299  }
300 }
301 
302 static int join_config_output(AVFilterLink *outlink)
303 {
304  AVFilterContext *ctx = outlink->src;
305  JoinContext *s = ctx->priv;
306  // unused channels from each input
307  ChannelList *inputs_unused;
308  char inbuf[64], outbuf[64];
309  int i, ret = 0;
310 
311  /* initialize unused channel list for each input */
312  inputs_unused = av_calloc(ctx->nb_inputs, sizeof(*inputs_unused));
313  if (!inputs_unused)
314  return AVERROR(ENOMEM);
315  for (i = 0; i < ctx->nb_inputs; i++) {
316  AVFilterLink *inlink = ctx->inputs[i];
317  AVChannelLayout *chl = &inlink->ch_layout;
318  ChannelList *iu = &inputs_unused[i];
319 
320  iu->nb_ch = chl->nb_channels;
321  iu->ch = av_malloc_array(iu->nb_ch, sizeof(*iu->ch));
322  if (!iu->ch) {
323  ret = AVERROR(ENOMEM);
324  goto fail;
325  }
326 
327  for (int ch_idx = 0; ch_idx < iu->nb_ch; ch_idx++) {
328  iu->ch[ch_idx] = av_channel_layout_channel_from_index(chl, ch_idx);
329  if (iu->ch[ch_idx] < 0) {
330  /* no channel ordering information in this input,
331  * so don't auto-map from it */
332  iu->nb_ch = 0;
333  break;
334  }
335  }
336  }
337 
338  /* process user-specified maps */
339  for (i = 0; i < s->ch_layout.nb_channels; i++) {
340  ChannelMap *ch = &s->channels[i];
342  AVChannelLayout *ichl;
343  ChannelList *iu;
344 
345  if (ch->input < 0)
346  continue;
347 
348  inlink = ctx->inputs[ch->input];
349  ichl = &inlink->ch_layout;
350  iu = &inputs_unused[ch->input];
351 
352  /* get the index for the channels defined by name */
353  if (ch->in_channel != AV_CHAN_NONE) {
355  if (ch->in_channel_idx < 0) {
356  av_channel_name(inbuf, sizeof(inbuf), ch->in_channel);
357  av_log(ctx, AV_LOG_ERROR, "Requested channel %s is not present in "
358  "input stream #%d.\n", inbuf,
359  ch->input);
360  ret = AVERROR(EINVAL);
361  goto fail;
362  }
363  }
364 
365  /* make sure channels specified by index actually exist */
366  if (ch->in_channel_idx >= ichl->nb_channels) {
367  av_log(ctx, AV_LOG_ERROR, "Requested channel with index %d is not "
368  "present in input stream #%d.\n", ch->in_channel_idx, ch->input);
369  ret = AVERROR(EINVAL);
370  goto fail;
371  }
372 
374  }
375 
376  /* guess channel maps when not explicitly defined */
377  /* first try unused matching channels */
378  for (i = 0; i < s->ch_layout.nb_channels; i++) {
379  ChannelMap *ch = &s->channels[i];
380 
381  if (ch->input < 0)
382  guess_map_matching(ctx, ch, inputs_unused);
383  }
384 
385  /* if the above failed, try to find _any_ unused input channel */
386  for (i = 0; i < s->ch_layout.nb_channels; i++) {
387  ChannelMap *ch = &s->channels[i];
388 
389  if (ch->input < 0)
390  guess_map_any(ctx, ch, inputs_unused);
391 
392  if (ch->input < 0) {
393  av_channel_name(outbuf, sizeof(outbuf), ch->out_channel);
394  av_log(ctx, AV_LOG_ERROR, "Could not find input channel for "
395  "output channel '%s'.\n",
396  outbuf);
397  ret = AVERROR(EINVAL);
398  goto fail;
399  }
400 
401  if (ch->in_channel != AV_CHAN_NONE) {
403  &ctx->inputs[ch->input]->ch_layout, ch->in_channel);
404  }
405 
406  av_assert0(ch->in_channel_idx >= 0);
407  }
408 
409  /* print mappings */
410  av_log(ctx, AV_LOG_VERBOSE, "mappings: ");
411  for (i = 0; i < s->ch_layout.nb_channels; i++) {
412  ChannelMap *ch = &s->channels[i];
413  AVFilterLink *inlink = ctx->inputs[ch->input];
414  AVChannelLayout *ichl = &inlink->ch_layout;
416  ichl, ch->in_channel_idx);
417 
418  av_channel_name(inbuf, sizeof(inbuf), in_ch);
419  av_channel_name(outbuf, sizeof(outbuf), ch->out_channel);
420  av_log(ctx, AV_LOG_VERBOSE, "%d.%s(%d) => %s(%d) ", ch->input,
421  inbuf, ch->in_channel_idx,
422  outbuf, i);
423  }
424  av_log(ctx, AV_LOG_VERBOSE, "\n");
425 
426  for (i = 0; i < ctx->nb_inputs; i++) {
427  if (inputs_unused[i].nb_ch == ctx->inputs[i]->ch_layout.nb_channels)
428  av_log(ctx, AV_LOG_WARNING, "No channels are used from input "
429  "stream %d.\n", i);
430  }
431 
432 fail:
433  for (i = 0; i < ctx->nb_inputs; i++)
434  av_freep(&inputs_unused[i].ch);
435  av_freep(&inputs_unused);
436  return ret;
437 }
438 
440 {
441  AVFilterLink *outlink = ctx->outputs[0];
442  JoinContext *s = ctx->priv;
443  AVFrame *frame;
444  int linesize = INT_MAX;
445  int nb_samples = INT_MAX;
446  int nb_buffers = 0;
447  int i, j, ret;
448 
449  for (i = 0; i < ctx->nb_inputs; i++) {
450  if (!s->input_frames[i]) {
451  nb_samples = 0;
452  break;
453  } else {
454  nb_samples = FFMIN(nb_samples, s->input_frames[i]->nb_samples);
455  }
456  }
457  if (!nb_samples)
458  goto eof;
459 
460  /* setup the output frame */
461  frame = av_frame_alloc();
462  if (!frame)
463  return AVERROR(ENOMEM);
464  if (s->ch_layout.nb_channels > FF_ARRAY_ELEMS(frame->data)) {
465  frame->extended_data = av_calloc(s->ch_layout.nb_channels,
466  sizeof(*frame->extended_data));
467  if (!frame->extended_data) {
468  ret = AVERROR(ENOMEM);
469  goto fail;
470  }
471  }
472 
473  /* copy the data pointers */
474  for (i = 0; i < s->ch_layout.nb_channels; i++) {
475  ChannelMap *ch = &s->channels[i];
476  AVFrame *cur = s->input_frames[ch->input];
477  AVBufferRef *buf;
478 
480  linesize = FFMIN(linesize, cur->linesize[0]);
481 
482  /* add the buffer where this plan is stored to the list if it's
483  * not already there */
485  if (!buf) {
486  ret = AVERROR(EINVAL);
487  goto fail;
488  }
489  for (j = 0; j < nb_buffers; j++)
490  if (s->buffers[j]->buffer == buf->buffer)
491  break;
492  if (j == i)
493  s->buffers[nb_buffers++] = buf;
494  }
495 
496  /* create references to the buffers we copied to output */
497  if (nb_buffers > FF_ARRAY_ELEMS(frame->buf)) {
498  frame->nb_extended_buf = nb_buffers - FF_ARRAY_ELEMS(frame->buf);
500  sizeof(*frame->extended_buf));
501  if (!frame->extended_buf) {
502  frame->nb_extended_buf = 0;
503  ret = AVERROR(ENOMEM);
504  goto fail;
505  }
506  }
507  for (i = 0; i < FFMIN(FF_ARRAY_ELEMS(frame->buf), nb_buffers); i++) {
508  frame->buf[i] = av_buffer_ref(s->buffers[i]);
509  if (!frame->buf[i]) {
510  ret = AVERROR(ENOMEM);
511  goto fail;
512  }
513  }
514  for (i = 0; i < frame->nb_extended_buf; i++) {
515  frame->extended_buf[i] = av_buffer_ref(s->buffers[i +
517  if (!frame->extended_buf[i]) {
518  ret = AVERROR(ENOMEM);
519  goto fail;
520  }
521  }
522 
523  frame->nb_samples = nb_samples;
525  av_make_q(1, outlink->sample_rate),
526  outlink->time_base);
527 
528 #if FF_API_OLD_CHANNEL_LAYOUT
530  frame->channel_layout = outlink->channel_layout;
531  frame->channels = outlink->ch_layout.nb_channels;
533 #endif
534  if ((ret = av_channel_layout_copy(&frame->ch_layout, &outlink->ch_layout)) < 0)
535  goto fail;
536  frame->sample_rate = outlink->sample_rate;
537  frame->format = outlink->format;
538  frame->pts = s->input_frames[0]->pts;
539  frame->linesize[0] = linesize;
540  if (frame->data != frame->extended_data) {
541  memcpy(frame->data, frame->extended_data, sizeof(*frame->data) *
542  FFMIN(FF_ARRAY_ELEMS(frame->data), s->ch_layout.nb_channels));
543  }
544 
545  s->eof_pts = frame->pts + av_rescale_q(frame->nb_samples,
546  av_make_q(1, outlink->sample_rate),
547  outlink->time_base);
548  ret = ff_filter_frame(outlink, frame);
549 
550  for (i = 0; i < ctx->nb_inputs; i++)
551  av_frame_free(&s->input_frames[i]);
552 
553  return ret;
554 
555 fail:
557  return ret;
558 eof:
559  for (i = 0; i < ctx->nb_inputs; i++) {
560  if (s->eof &&
561  ff_inlink_queued_samples(ctx->inputs[i]) <= 0 &&
562  !s->input_frames[i]) {
563  ff_outlink_set_status(outlink, AVERROR_EOF, s->eof_pts);
564  break;
565  }
566  }
567 
568  return 0;
569 }
570 
572 {
573  JoinContext *s = ctx->priv;
574  int i, ret, status;
575  int nb_samples = 0;
576  int64_t pts;
577 
579 
580  if (!s->input_frames[0]) {
581  ret = ff_inlink_consume_frame(ctx->inputs[0], &s->input_frames[0]);
582  if (ret < 0) {
583  return ret;
584  } else if (ret == 0 && ff_inlink_acknowledge_status(ctx->inputs[0], &status, &pts)) {
585  s->eof |= status == AVERROR_EOF;
586  }
587 
588  if (!s->eof && !s->input_frames[0] && ff_outlink_frame_wanted(ctx->outputs[0])) {
589  ff_inlink_request_frame(ctx->inputs[0]);
590  return 0;
591  }
592  }
593 
594  if (s->input_frames[0])
595  nb_samples = s->input_frames[0]->nb_samples;
596 
597  for (i = 1; i < ctx->nb_inputs && nb_samples > 0; i++) {
598  if (s->input_frames[i])
599  continue;
600  ret = ff_inlink_consume_samples(ctx->inputs[i], nb_samples, nb_samples, &s->input_frames[i]);
601  if (ret < 0) {
602  return ret;
603  } else if (ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts)) {
604  s->eof |= status == AVERROR_EOF;
605  }
606 
607  if (!s->eof && !s->input_frames[i]) {
608  ff_inlink_request_frame(ctx->inputs[i]);
609  return 0;
610  }
611  }
612 
613  return try_push_frame(ctx);
614 }
615 
617  {
618  .name = "default",
619  .type = AVMEDIA_TYPE_AUDIO,
620  .config_props = join_config_output,
621  },
622 };
623 
625  .name = "join",
626  .description = NULL_IF_CONFIG_SMALL("Join multiple audio streams into "
627  "multi-channel output."),
628  .priv_size = sizeof(JoinContext),
629  .priv_class = &join_class,
630  .init = join_init,
631  .uninit = join_uninit,
632  .activate = activate,
633  .inputs = NULL,
637 };
AVFrame::extended_buf
AVBufferRef ** extended_buf
For planar audio which requires more than AV_NUM_DATA_POINTERS AVBufferRef pointers,...
Definition: frame.h:604
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:73
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
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:978
AVFrame::duration
int64_t duration
Duration of the frame, in the same units as pts.
Definition: frame.h:807
ff_channel_layouts_ref
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:612
layouts
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:326
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
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:115
JoinContext::eof
int eof
Definition: af_join.c:55
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:100
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:452
guess_map_matching
static void guess_map_matching(AVFilterContext *ctx, ChannelMap *ch, ChannelList *inputs)
Definition: af_join.c:274
av_channel_layout_channel_from_index
enum AVChannel av_channel_layout_channel_from_index(const AVChannelLayout *channel_layout, unsigned int idx)
Get the channel with the given index in a channel layout.
Definition: channel_layout.c:806
AVOption
AVOption.
Definition: opt.h:251
FILTER_QUERY_FUNC
#define FILTER_QUERY_FUNC(func)
Definition: internal.h:169
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:760
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:170
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:317
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:590
ChannelList::nb_ch
int nb_ch
Definition: af_join.c:250
channel_list_pop
static enum AVChannel channel_list_pop(ChannelList *chl, int idx)
Definition: af_join.c:253
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:361
formats.h
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:1383
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:138
ChannelMap::input
int input
input stream index
Definition: af_join.c:40
AVFrame::ch_layout
AVChannelLayout ch_layout
Channel layout of the audio data.
Definition: frame.h:802
join_query_formats
static int join_query_formats(AVFilterContext *ctx)
Definition: af_join.c:225
pts
static int64_t pts
Definition: transcode_aac.c:643
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:106
AVFrame::channels
attribute_deprecated int channels
number of audio channels, only used for audio.
Definition: frame.h:731
JoinContext::buffers
AVBufferRef ** buffers
Temporary storage for buffer references, for assembling the output frame.
Definition: af_join.c:67
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:47
JoinContext::input_frames
AVFrame ** input_frames
Temporary storage for input frames, until we get one on each input.
Definition: af_join.c:62
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:88
parse_maps
static int parse_maps(AVFilterContext *ctx)
Definition: af_join.c:87
avassert.h
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
AVFrame::channel_layout
attribute_deprecated uint64_t channel_layout
Channel layout of the audio data.
Definition: frame.h:575
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:770
mask
static const uint16_t mask[17]
Definition: lzw.c:38
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_inlink_request_frame
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition: avfilter.c:1506
s
#define s(width, name)
Definition: cbs_vp9.c:198
guess_map_any
static void guess_map_any(AVFilterContext *ctx, ChannelMap *ch, ChannelList *inputs)
Definition: af_join.c:288
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
av_channel_layout_from_mask
FF_ENABLE_DEPRECATION_WARNINGS int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
Definition: channel_layout.c:399
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts_bsf.c:365
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
av_channel_layout_index_from_string
int av_channel_layout_index_from_string(const AVChannelLayout *channel_layout, const char *str)
Get the index in a channel layout of a channel described by the given string.
Definition: channel_layout.c:880
filters.h
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:142
frame
static AVFrame * frame
Definition: demux_decode.c:54
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:1402
NULL
#define NULL
Definition: coverity.c:32
ChannelList::ch
enum AVChannel * ch
Definition: af_join.c:249
ff_append_inpad_free_name
int ff_append_inpad_free_name(AVFilterContext *f, AVFilterPad *p)
Definition: avfilter.c:132
ChannelMap::in_channel
int in_channel
Definition: af_channelmap.c:41
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:247
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
ff_add_channel_layout
int ff_add_channel_layout(AVFilterChannelLayouts **l, const AVChannelLayout *channel_layout)
Definition: formats.c:487
join_options
static const AVOption join_options[]
Definition: af_join.c:73
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:1337
av_frame_get_plane_buffer
AVBufferRef * av_frame_get_plane_buffer(const AVFrame *frame, int plane)
Get the buffer reference a given data plane is stored in.
Definition: frame.c:741
JoinContext::channel_layout_str
char * channel_layout_str
Definition: af_join.c:51
F
#define F
Definition: af_join.c:72
JoinContext::ch_layout
AVChannelLayout ch_layout
Definition: af_join.c:52
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:106
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:307
AVFrame::sample_rate
int sample_rate
Sample rate of the audio data.
Definition: frame.h:567
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:71
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:427
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:578
JoinContext
Definition: af_join.c:46
internal.h
join_uninit
static av_cold void join_uninit(AVFilterContext *ctx)
Definition: af_join.c:211
AVChannel
AVChannel
Definition: channel_layout.h:47
av_channel_layout_from_string
int av_channel_layout_from_string(AVChannelLayout *channel_layout, const char *str)
Initialize a channel layout from a given string description.
Definition: channel_layout.c:412
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:420
OFFSET
#define OFFSET(x)
Definition: af_join.c:70
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
av_channel_name
int av_channel_name(char *buf, size_t buf_size, enum AVChannel channel_id)
Get a human readable string in an abbreviated form describing a given channel.
Definition: channel_layout.c:101
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:401
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
common.h
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:559
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:53
ff_inlink_queued_samples
int ff_inlink_queued_samples(AVFilterLink *link)
Definition: avfilter.c:1362
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
ChannelMap::out_channel
int out_channel
Definition: af_channelmap.c:42
activate
static int activate(AVFilterContext *ctx)
Definition: af_join.c:571
AVFilter
Filter definition.
Definition: avfilter.h:166
avfilter_af_join_outputs
static const AVFilterPad avfilter_af_join_outputs[]
Definition: af_join.c:616
ret
ret
Definition: filter_design.txt:187
AVFilterPad::type
enum AVMediaType type
AVFilterPad type.
Definition: internal.h:58
JoinContext::inputs
int inputs
Definition: af_join.c:49
av_channel_from_string
enum AVChannel av_channel_from_string(const char *str)
This is the inverse function of av_channel_name().
Definition: channel_layout.c:145
AV_CHAN_NONE
@ AV_CHAN_NONE
Invalid channel index.
Definition: channel_layout.h:49
JoinContext::eof_pts
int64_t eof_pts
Definition: af_join.c:54
status
ov_status_e status
Definition: dnn_backend_openvino.c:119
channel_layout.h
JoinContext::map
char * map
Definition: af_join.c:50
av_channel_layout_index_from_channel
int av_channel_layout_index_from_channel(const AVChannelLayout *channel_layout, enum AVChannel channel)
Get the index of a given channel in a channel layout.
Definition: channel_layout.c:846
JoinContext::channels
ChannelMap * channels
Definition: af_join.c:57
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avfilter.h
MAP_SEPARATOR
#define MAP_SEPARATOR
Definition: af_join.c:83
ChannelMap
Definition: opus_parse.h:48
AVFilterContext
An instance of a filter.
Definition: avfilter.h:397
av_channel_layout_copy
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
Definition: channel_layout.c:647
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:72
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:302
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:193
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
join_init
static av_cold int join_init(AVFilterContext *ctx)
Definition: af_join.c:155
ChannelList
Definition: af_join.c:248
ff_af_join
const AVFilter ff_af_join
Definition: af_join.c:624
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:385
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
uninit
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:285
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:229
try_push_frame
static int try_push_frame(AVFilterContext *ctx)
Definition: af_join.c:439
channel_list_pop_ch
static enum AVChannel channel_list_pop_ch(ChannelList *chl, enum AVChannel ch)
Definition: af_join.c:266
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(join)
AVFrame::nb_extended_buf
int nb_extended_buf
Number of elements in extended_buf.
Definition: frame.h:608