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;
52 
53  int64_t eof_pts;
54  int eof;
55 
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(ch_layout), AV_OPT_TYPE_CHLAYOUT, {.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 
82 #define MAP_SEPARATOR '|'
83 
85 
87 {
88  JoinContext *s = ctx->priv;
89  char *cur = s->map;
90 
91  while (cur && *cur) {
92  ChannelMap *map;
93  char *sep, *next, *p;
94  int input_idx, out_ch_idx;
95 
96  next = strchr(cur, MAP_SEPARATOR);
97  if (next)
98  *next++ = 0;
99 
100  /* split the map into input and output parts */
101  if (!(sep = strchr(cur, '-'))) {
102  av_log(ctx, AV_LOG_ERROR, "Missing separator '-' in channel "
103  "map '%s'\n", cur);
104  return AVERROR(EINVAL);
105  }
106  *sep++ = 0;
107 
108  /* parse output channel */
109  out_ch_idx = av_channel_layout_index_from_string(&s->ch_layout, sep);
110  if (out_ch_idx < 0) {
111  av_log(ctx, AV_LOG_ERROR, "Invalid output channel: %s.\n", sep);
112  return AVERROR(EINVAL);
113  }
114 
115  map = &s->channels[out_ch_idx];
116 
117  if (map->input >= 0) {
118  av_log(ctx, AV_LOG_ERROR, "Multiple maps for output channel "
119  "'%s'.\n", sep);
120  return AVERROR(EINVAL);
121  }
122 
123  /* parse input channel */
124  input_idx = strtol(cur, &cur, 0);
125  if (input_idx < 0 || input_idx >= s->inputs) {
126  av_log(ctx, AV_LOG_ERROR, "Invalid input stream index: %d.\n",
127  input_idx);
128  return AVERROR(EINVAL);
129  }
130 
131  if (*cur)
132  cur++;
133 
134  map->input = input_idx;
135  map->in_channel = AV_CHAN_NONE;
136  map->in_channel_idx = strtol(cur, &p, 0);
137  if (p == cur) {
138  /* channel specifier is not a number, handle as channel name */
139  map->in_channel = av_channel_from_string(cur);
140  if (map->in_channel < 0) {
141  av_log(ctx, AV_LOG_ERROR, "Invalid input channel: %s.\n", cur);
142  return AVERROR(EINVAL);
143  }
144  } else if (map->in_channel_idx < 0) {
145  av_log(ctx, AV_LOG_ERROR, "Invalid input channel index: %d\n", map->in_channel_idx);
146  return AVERROR(EINVAL);
147  }
148 
149  cur = next;
150  }
151  return 0;
152 }
153 
155 {
156  JoinContext *s = ctx->priv;
157  int ret, i;
158 
159  s->channels = av_calloc(s->ch_layout.nb_channels, sizeof(*s->channels));
160  s->buffers = av_calloc(s->ch_layout.nb_channels, sizeof(*s->buffers));
161  s->input_frames = av_calloc(s->inputs, sizeof(*s->input_frames));
162  if (!s->channels || !s->buffers|| !s->input_frames)
163  return AVERROR(ENOMEM);
164 
165  for (i = 0; i < s->ch_layout.nb_channels; i++) {
166  s->channels[i].out_channel = av_channel_layout_channel_from_index(&s->ch_layout, i);
167  s->channels[i].input = -1;
168  s->channels[i].in_channel_idx = -1;
169  s->channels[i].in_channel = AV_CHAN_NONE;
170  }
171 
172  if ((ret = parse_maps(ctx)) < 0)
173  return ret;
174 
175  for (i = 0; i < s->inputs; i++) {
176  AVFilterPad pad = { 0 };
177 
178  pad.type = AVMEDIA_TYPE_AUDIO;
179  pad.name = av_asprintf("input%d", i);
180  if (!pad.name)
181  return AVERROR(ENOMEM);
182 
183  if ((ret = ff_append_inpad_free_name(ctx, &pad)) < 0)
184  return ret;
185  }
186 
187  return 0;
188 }
189 
191 {
192  JoinContext *s = ctx->priv;
193  int i;
194 
195  for (i = 0; i < s->inputs && s->input_frames; i++) {
196  av_frame_free(&s->input_frames[i]);
197  }
198 
199  av_freep(&s->channels);
200  av_freep(&s->buffers);
201  av_freep(&s->input_frames);
202 }
203 
205 {
206  JoinContext *s = ctx->priv;
208  int i, ret;
209 
210  if ((ret = ff_add_channel_layout(&layouts, &s->ch_layout)) < 0 ||
211  (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0)
212  return ret;
213 
214  for (i = 0; i < ctx->nb_inputs; i++) {
216  if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->outcfg.channel_layouts)) < 0)
217  return ret;
218  }
219 
222  return ret;
223 
224  return 0;
225 }
226 
227 typedef struct ChannelList {
228  enum AVChannel *ch;
229  int nb_ch;
230 } ChannelList;
231 
232 static enum AVChannel channel_list_pop(ChannelList *chl, int idx)
233 {
234  enum AVChannel ret = chl->ch[idx];
235  memmove(chl->ch + idx, chl->ch + idx + 1,
236  (chl->nb_ch - idx - 1) * sizeof(*chl->ch));
237  chl->nb_ch--;
238  return ret;
239 }
240 
241 /*
242  * If ch is present in chl, remove it from the list and return it.
243  * Otherwise return AV_CHAN_NONE.
244  */
246 {
247  for (int i = 0; i < chl->nb_ch; i++)
248  if (chl->ch[i] == ch)
249  return channel_list_pop(chl, i);
250  return AV_CHAN_NONE;
251 }
252 
255 {
256  int i;
257 
258  for (i = 0; i < ctx->nb_inputs; i++) {
260  ch->input = i;
261  ch->in_channel = ch->out_channel;
262  return;
263  }
264  }
265 }
266 
269 {
270  int i;
271 
272  for (i = 0; i < ctx->nb_inputs; i++) {
273  if (inputs[i].nb_ch) {
274  ch->input = i;
275  ch->in_channel = channel_list_pop(&inputs[i], 0);
276  return;
277  }
278  }
279 }
280 
281 static int join_config_output(AVFilterLink *outlink)
282 {
283  AVFilterContext *ctx = outlink->src;
284  JoinContext *s = ctx->priv;
285  // unused channels from each input
286  ChannelList *inputs_unused;
287  char inbuf[64], outbuf[64];
288  int i, ret = 0;
289 
290  /* initialize unused channel list for each input */
291  inputs_unused = av_calloc(ctx->nb_inputs, sizeof(*inputs_unused));
292  if (!inputs_unused)
293  return AVERROR(ENOMEM);
294  for (i = 0; i < ctx->nb_inputs; i++) {
295  AVFilterLink *inlink = ctx->inputs[i];
296  AVChannelLayout *chl = &inlink->ch_layout;
297  ChannelList *iu = &inputs_unused[i];
298 
299  iu->nb_ch = chl->nb_channels;
300  iu->ch = av_malloc_array(iu->nb_ch, sizeof(*iu->ch));
301  if (!iu->ch) {
302  ret = AVERROR(ENOMEM);
303  goto fail;
304  }
305 
306  for (int ch_idx = 0; ch_idx < iu->nb_ch; ch_idx++) {
307  iu->ch[ch_idx] = av_channel_layout_channel_from_index(chl, ch_idx);
308  if (iu->ch[ch_idx] < 0) {
309  /* no channel ordering information in this input,
310  * so don't auto-map from it */
311  iu->nb_ch = 0;
312  break;
313  }
314  }
315  }
316 
317  /* process user-specified maps */
318  for (i = 0; i < s->ch_layout.nb_channels; i++) {
319  ChannelMap *ch = &s->channels[i];
321  AVChannelLayout *ichl;
322  ChannelList *iu;
323 
324  if (ch->input < 0)
325  continue;
326 
327  inlink = ctx->inputs[ch->input];
328  ichl = &inlink->ch_layout;
329  iu = &inputs_unused[ch->input];
330 
331  /* get the index for the channels defined by name */
332  if (ch->in_channel != AV_CHAN_NONE) {
334  if (ch->in_channel_idx < 0) {
335  av_channel_name(inbuf, sizeof(inbuf), ch->in_channel);
336  av_log(ctx, AV_LOG_ERROR, "Requested channel %s is not present in "
337  "input stream #%d.\n", inbuf,
338  ch->input);
339  ret = AVERROR(EINVAL);
340  goto fail;
341  }
342  }
343 
344  /* make sure channels specified by index actually exist */
345  if (ch->in_channel_idx >= ichl->nb_channels) {
346  av_log(ctx, AV_LOG_ERROR, "Requested channel with index %d is not "
347  "present in input stream #%d.\n", ch->in_channel_idx, ch->input);
348  ret = AVERROR(EINVAL);
349  goto fail;
350  }
351 
353  }
354 
355  /* guess channel maps when not explicitly defined */
356  /* first try unused matching channels */
357  for (i = 0; i < s->ch_layout.nb_channels; i++) {
358  ChannelMap *ch = &s->channels[i];
359 
360  if (ch->input < 0)
361  guess_map_matching(ctx, ch, inputs_unused);
362  }
363 
364  /* if the above failed, try to find _any_ unused input channel */
365  for (i = 0; i < s->ch_layout.nb_channels; i++) {
366  ChannelMap *ch = &s->channels[i];
367 
368  if (ch->input < 0)
369  guess_map_any(ctx, ch, inputs_unused);
370 
371  if (ch->input < 0) {
372  av_channel_name(outbuf, sizeof(outbuf), ch->out_channel);
373  av_log(ctx, AV_LOG_ERROR, "Could not find input channel for "
374  "output channel '%s'.\n",
375  outbuf);
376  ret = AVERROR(EINVAL);
377  goto fail;
378  }
379 
380  if (ch->in_channel != AV_CHAN_NONE) {
382  &ctx->inputs[ch->input]->ch_layout, ch->in_channel);
383  }
384 
385  av_assert0(ch->in_channel_idx >= 0);
386  }
387 
388  /* print mappings */
389  av_log(ctx, AV_LOG_VERBOSE, "mappings: ");
390  for (i = 0; i < s->ch_layout.nb_channels; i++) {
391  ChannelMap *ch = &s->channels[i];
392  AVFilterLink *inlink = ctx->inputs[ch->input];
393  AVChannelLayout *ichl = &inlink->ch_layout;
395  ichl, ch->in_channel_idx);
396 
397  av_channel_name(inbuf, sizeof(inbuf), in_ch);
398  av_channel_name(outbuf, sizeof(outbuf), ch->out_channel);
399  av_log(ctx, AV_LOG_VERBOSE, "%d.%s(%d) => %s(%d) ", ch->input,
400  inbuf, ch->in_channel_idx,
401  outbuf, i);
402  }
403  av_log(ctx, AV_LOG_VERBOSE, "\n");
404 
405  for (i = 0; i < ctx->nb_inputs; i++) {
406  if (inputs_unused[i].nb_ch == ctx->inputs[i]->ch_layout.nb_channels)
407  av_log(ctx, AV_LOG_WARNING, "No channels are used from input "
408  "stream %d.\n", i);
409  }
410 
411 fail:
412  for (i = 0; i < ctx->nb_inputs; i++)
413  av_freep(&inputs_unused[i].ch);
414  av_freep(&inputs_unused);
415  return ret;
416 }
417 
419 {
420  AVFilterLink *outlink = ctx->outputs[0];
421  JoinContext *s = ctx->priv;
422  AVFrame *frame;
423  int linesize = INT_MAX;
424  int nb_samples = INT_MAX;
425  int nb_buffers = 0;
426  int i, j, ret;
427 
428  for (i = 0; i < ctx->nb_inputs; i++) {
429  if (!s->input_frames[i]) {
430  nb_samples = 0;
431  break;
432  } else {
433  nb_samples = FFMIN(nb_samples, s->input_frames[i]->nb_samples);
434  }
435  }
436  if (!nb_samples)
437  goto eof;
438 
439  /* setup the output frame */
440  frame = av_frame_alloc();
441  if (!frame)
442  return AVERROR(ENOMEM);
443  if (s->ch_layout.nb_channels > FF_ARRAY_ELEMS(frame->data)) {
444  frame->extended_data = av_calloc(s->ch_layout.nb_channels,
445  sizeof(*frame->extended_data));
446  if (!frame->extended_data) {
447  ret = AVERROR(ENOMEM);
448  goto fail;
449  }
450  }
451 
452  /* copy the data pointers */
453  for (i = 0; i < s->ch_layout.nb_channels; i++) {
454  ChannelMap *ch = &s->channels[i];
455  AVFrame *cur = s->input_frames[ch->input];
456  AVBufferRef *buf;
457 
459  linesize = FFMIN(linesize, cur->linesize[0]);
460 
461  /* add the buffer where this plan is stored to the list if it's
462  * not already there */
464  if (!buf) {
465  ret = AVERROR(EINVAL);
466  goto fail;
467  }
468  for (j = 0; j < nb_buffers; j++)
469  if (s->buffers[j]->buffer == buf->buffer)
470  break;
471  if (j == i)
472  s->buffers[nb_buffers++] = buf;
473  }
474 
475  /* create references to the buffers we copied to output */
476  if (nb_buffers > FF_ARRAY_ELEMS(frame->buf)) {
477  frame->nb_extended_buf = nb_buffers - FF_ARRAY_ELEMS(frame->buf);
479  sizeof(*frame->extended_buf));
480  if (!frame->extended_buf) {
481  frame->nb_extended_buf = 0;
482  ret = AVERROR(ENOMEM);
483  goto fail;
484  }
485  }
486  for (i = 0; i < FFMIN(FF_ARRAY_ELEMS(frame->buf), nb_buffers); i++) {
487  frame->buf[i] = av_buffer_ref(s->buffers[i]);
488  if (!frame->buf[i]) {
489  ret = AVERROR(ENOMEM);
490  goto fail;
491  }
492  }
493  for (i = 0; i < frame->nb_extended_buf; i++) {
494  frame->extended_buf[i] = av_buffer_ref(s->buffers[i +
496  if (!frame->extended_buf[i]) {
497  ret = AVERROR(ENOMEM);
498  goto fail;
499  }
500  }
501 
502  frame->nb_samples = nb_samples;
504  av_make_q(1, outlink->sample_rate),
505  outlink->time_base);
506 
507 #if FF_API_OLD_CHANNEL_LAYOUT
509  frame->channel_layout = outlink->channel_layout;
510  frame->channels = outlink->ch_layout.nb_channels;
512 #endif
513  if ((ret = av_channel_layout_copy(&frame->ch_layout, &outlink->ch_layout)) < 0)
514  goto fail;
515  frame->sample_rate = outlink->sample_rate;
516  frame->format = outlink->format;
517  frame->pts = s->input_frames[0]->pts;
518  frame->linesize[0] = linesize;
519  if (frame->data != frame->extended_data) {
520  memcpy(frame->data, frame->extended_data, sizeof(*frame->data) *
521  FFMIN(FF_ARRAY_ELEMS(frame->data), s->ch_layout.nb_channels));
522  }
523 
524  s->eof_pts = frame->pts + av_rescale_q(frame->nb_samples,
525  av_make_q(1, outlink->sample_rate),
526  outlink->time_base);
527  ret = ff_filter_frame(outlink, frame);
528 
529  for (i = 0; i < ctx->nb_inputs; i++)
530  av_frame_free(&s->input_frames[i]);
531 
532  return ret;
533 
534 fail:
536  return ret;
537 eof:
538  for (i = 0; i < ctx->nb_inputs; i++) {
539  if (s->eof &&
540  ff_inlink_queued_samples(ctx->inputs[i]) <= 0 &&
541  !s->input_frames[i]) {
542  ff_outlink_set_status(outlink, AVERROR_EOF, s->eof_pts);
543  break;
544  }
545  }
546 
547  return 0;
548 }
549 
551 {
552  JoinContext *s = ctx->priv;
553  int i, ret, status;
554  int nb_samples = 0;
555  int64_t pts;
556 
558 
559  if (!s->input_frames[0]) {
560  ret = ff_inlink_consume_frame(ctx->inputs[0], &s->input_frames[0]);
561  if (ret < 0) {
562  return ret;
563  } else if (ret == 0 && ff_inlink_acknowledge_status(ctx->inputs[0], &status, &pts)) {
564  s->eof |= status == AVERROR_EOF;
565  }
566 
567  if (!s->eof && !s->input_frames[0] && ff_outlink_frame_wanted(ctx->outputs[0])) {
568  ff_inlink_request_frame(ctx->inputs[0]);
569  return 0;
570  }
571  }
572 
573  if (s->input_frames[0])
574  nb_samples = s->input_frames[0]->nb_samples;
575 
576  for (i = 1; i < ctx->nb_inputs && nb_samples > 0; i++) {
577  if (s->input_frames[i])
578  continue;
579  ret = ff_inlink_consume_samples(ctx->inputs[i], nb_samples, nb_samples, &s->input_frames[i]);
580  if (ret < 0) {
581  return ret;
582  } else if (ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts)) {
583  s->eof |= status == AVERROR_EOF;
584  }
585 
586  if (!s->eof && !s->input_frames[i]) {
587  ff_inlink_request_frame(ctx->inputs[i]);
588  return 0;
589  }
590  }
591 
592  return try_push_frame(ctx);
593 }
594 
596  {
597  .name = "default",
598  .type = AVMEDIA_TYPE_AUDIO,
599  .config_props = join_config_output,
600  },
601 };
602 
604  .name = "join",
605  .description = NULL_IF_CONFIG_SMALL("Join multiple audio streams into "
606  "multi-channel output."),
607  .priv_size = sizeof(JoinContext),
608  .priv_class = &join_class,
609  .init = join_init,
610  .uninit = join_uninit,
611  .activate = activate,
612  .inputs = NULL,
616 };
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:54
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:253
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:808
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:319
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:229
channel_list_pop
static enum AVChannel channel_list_pop(ChannelList *chl, int idx)
Definition: af_join.c:232
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:1393
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:142
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:204
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:66
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:61
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:86
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
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:1516
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:267
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
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:882
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:1412
NULL
#define NULL
Definition: coverity.c:32
ChannelList::ch
enum AVChannel * ch
Definition: af_join.c:228
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
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
AV_OPT_TYPE_CHLAYOUT
@ AV_OPT_TYPE_CHLAYOUT
Definition: opt.h:245
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: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:1347
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
F
#define F
Definition: af_join.c:71
JoinContext::ch_layout
AVChannelLayout ch_layout
Definition: af_join.c:51
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:309
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:70
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:190
AVChannel
AVChannel
Definition: channel_layout.h:47
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:69
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:245
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:1372
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:550
AVFilter
Filter definition.
Definition: avfilter.h:166
avfilter_af_join_outputs
static const AVFilterPad avfilter_af_join_outputs[]
Definition: af_join.c:595
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:53
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:848
JoinContext::channels
ChannelMap * channels
Definition: af_join.c:56
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avfilter.h
MAP_SEPARATOR
#define MAP_SEPARATOR
Definition: af_join.c:82
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:649
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:281
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:154
ChannelList
Definition: af_join.c:227
ff_af_join
const AVFilter ff_af_join
Definition: af_join.c:603
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:418
channel_list_pop_ch
static enum AVChannel channel_list_pop_ch(ChannelList *chl, enum AVChannel ch)
Definition: af_join.c:245
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