FFmpeg
af_channelmap.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Google, Inc.
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * audio channel mapping filter
24  */
25 
26 #include <ctype.h>
27 
28 #include "libavutil/avstring.h"
30 #include "libavutil/common.h"
31 #include "libavutil/mathematics.h"
32 #include "libavutil/mem.h"
33 #include "libavutil/opt.h"
34 #include "libavutil/samplefmt.h"
35 
36 #include "audio.h"
37 #include "avfilter.h"
38 #include "formats.h"
39 #include "internal.h"
40 
41 struct ChannelMap {
46 };
47 
56 };
57 
58 #define MAX_CH 64
59 typedef struct ChannelMapContext {
60  const AVClass *class;
61  char *mapping_str;
64  int nch;
67 
68 #define OFFSET(x) offsetof(ChannelMapContext, x)
69 #define A AV_OPT_FLAG_AUDIO_PARAM
70 #define F AV_OPT_FLAG_FILTERING_PARAM
71 static const AVOption channelmap_options[] = {
72  { "map", "A comma-separated list of input channel numbers in output order.",
73  OFFSET(mapping_str), AV_OPT_TYPE_STRING, .flags = A|F },
74  { "channel_layout", "Output channel layout.",
75  OFFSET(output_layout), AV_OPT_TYPE_CHLAYOUT, .flags = A|F },
76  { NULL }
77 };
78 
79 AVFILTER_DEFINE_CLASS(channelmap);
80 
81 static char* split(char *message, char delim) {
82  char *next = strchr(message, delim);
83  if (next)
84  *next++ = '\0';
85  return next;
86 }
87 
88 static int get_channel_idx(char **map, int *ch, char delim, int max_nb_channels)
89 {
90  char *next;
91  int len;
92  int n = 0;
93  if (!*map)
94  return AVERROR(EINVAL);
95  next = split(*map, delim);
96  if (!next && delim == '-')
97  return AVERROR(EINVAL);
98  len = strlen(*map);
99  sscanf(*map, "%d%n", ch, &n);
100  if (n != len)
101  return AVERROR(EINVAL);
102  if (*ch < 0 || *ch >= max_nb_channels)
103  return AVERROR(EINVAL);
104  *map = next;
105  return 0;
106 }
107 
108 static int get_channel(char **map, int *ch, char delim)
109 {
110  char *next = split(*map, delim);
111  if (!next && delim == '-')
112  return AVERROR(EINVAL);
113  *ch = av_channel_from_string(*map);
114  if (*ch < 0)
115  return AVERROR(EINVAL);
116  *map = next;
117  return 0;
118 }
119 
120 static int check_idx_and_id(AVFilterContext *ctx, int channel_idx, int channel, AVChannelLayout *ch_layout, const char *io)
121 {
122  char channel_name[64];
123  char layout_name[256];
124  int nb_channels = ch_layout->nb_channels;
125 
126  if (channel_idx < 0 || channel_idx >= nb_channels) {
127  av_channel_layout_describe(ch_layout, layout_name, sizeof(layout_name));
128  if (channel >= 0) {
131  "%sput channel '%s' not available from %sput layout '%s'\n",
132  io, channel_name, io, layout_name);
133  } else {
135  "%sput channel #%d not available from %sput layout '%s'\n",
136  io, channel_idx, io, layout_name);
137  }
138  return AVERROR(EINVAL);
139  }
140 
141  return 0;
142 }
143 
145 {
146  ChannelMapContext *s = ctx->priv;
147  char *mapping, separator = '|';
148  int map_entries = 0;
149  enum MappingMode mode;
150  int64_t out_ch_mask = 0;
151  uint64_t presence_mask;
152  int i;
153 
154  mapping = s->mapping_str;
155 
156  if (!mapping) {
157  mode = MAP_NONE;
158  } else {
159  char *dash = strchr(mapping, '-');
160  if (!dash) { // short mapping
161  if (av_isdigit(*mapping))
162  mode = MAP_ONE_INT;
163  else
164  mode = MAP_ONE_STR;
165  } else if (av_isdigit(*mapping)) {
166  if (av_isdigit(*(dash+1)))
168  else
170  } else {
171  if (av_isdigit(*(dash+1)))
173  else
175  }
176  }
177 
178  if (mode != MAP_NONE) {
179  char *sep = mapping;
180  map_entries = 1;
181  while ((sep = strchr(sep, separator))) {
182  if (*++sep) // Allow trailing comma
183  map_entries++;
184  }
185  }
186 
187  if (map_entries > MAX_CH) {
188  av_log(ctx, AV_LOG_ERROR, "Too many channels mapped: '%d'.\n", map_entries);
189  return AVERROR(EINVAL);
190  }
191 
192  for (i = 0; i < MAX_CH; i++) {
193  s->map[i].in_channel_idx = -1;
194  s->map[i].out_channel_idx = -1;
195  s->map[i].in_channel = -1;
196  s->map[i].out_channel = -1;
197  }
198 
199  for (i = 0; i < map_entries; i++) {
200  int in_ch_idx = -1, out_ch_idx = -1;
201  int in_ch = -1, out_ch = -1;
202  static const char err[] = "Failed to parse channel map\n";
203  switch (mode) {
204  case MAP_ONE_INT:
205  if (get_channel_idx(&mapping, &in_ch_idx, separator, MAX_CH) < 0) {
206  av_log(ctx, AV_LOG_ERROR, err);
207  return AVERROR(EINVAL);
208  }
209  s->map[i].in_channel_idx = in_ch_idx;
210  s->map[i].out_channel_idx = i;
211  break;
212  case MAP_ONE_STR:
213  if (get_channel(&mapping, &in_ch, separator) < 0) {
214  av_log(ctx, AV_LOG_ERROR, err);
215  return AVERROR(EINVAL);
216  }
217  s->map[i].in_channel = in_ch;
218  s->map[i].out_channel_idx = i;
219  break;
220  case MAP_PAIR_INT_INT:
221  if (get_channel_idx(&mapping, &in_ch_idx, '-', MAX_CH) < 0 ||
222  get_channel_idx(&mapping, &out_ch_idx, separator, MAX_CH) < 0) {
223  av_log(ctx, AV_LOG_ERROR, err);
224  return AVERROR(EINVAL);
225  }
226  s->map[i].in_channel_idx = in_ch_idx;
227  s->map[i].out_channel_idx = out_ch_idx;
228  break;
229  case MAP_PAIR_INT_STR:
230  if (get_channel_idx(&mapping, &in_ch_idx, '-', MAX_CH) < 0 ||
231  get_channel(&mapping, &out_ch, separator) < 0) {
232  av_log(ctx, AV_LOG_ERROR, err);
233  return AVERROR(EINVAL);
234  }
235  s->map[i].in_channel_idx = in_ch_idx;
236  s->map[i].out_channel = out_ch;
237  if (out_ch < 63)
238  out_ch_mask |= 1ULL << out_ch;
239  else
240  out_ch_mask = -1;
241  break;
242  case MAP_PAIR_STR_INT:
243  if (get_channel(&mapping, &in_ch, '-') < 0 ||
244  get_channel_idx(&mapping, &out_ch_idx, separator, MAX_CH) < 0) {
245  av_log(ctx, AV_LOG_ERROR, err);
246  return AVERROR(EINVAL);
247  }
248  s->map[i].in_channel = in_ch;
249  s->map[i].out_channel_idx = out_ch_idx;
250  break;
251  case MAP_PAIR_STR_STR:
252  if (get_channel(&mapping, &in_ch, '-') < 0 ||
253  get_channel(&mapping, &out_ch, separator) < 0) {
254  av_log(ctx, AV_LOG_ERROR, err);
255  return AVERROR(EINVAL);
256  }
257  s->map[i].in_channel = in_ch;
258  s->map[i].out_channel = out_ch;
259  if (out_ch < 63)
260  out_ch_mask |= 1ULL << out_ch;
261  else
262  out_ch_mask = -1;
263  break;
264  }
265  }
266  s->mode = mode;
267  s->nch = map_entries;
268  if (s->output_layout.nb_channels == 0) {
269  if (out_ch_mask > 0)
270  av_channel_layout_from_mask(&s->output_layout, out_ch_mask);
271  else if (map_entries)
272  av_channel_layout_default(&s->output_layout, map_entries);
273  }
274 
275  if (mode == MAP_NONE) {
276  int i;
277  s->nch = s->output_layout.nb_channels;
278  for (i = 0; i < s->nch; i++) {
279  s->map[i].in_channel_idx = i;
280  s->map[i].out_channel_idx = i;
281  }
282  } else if (s->nch != s->output_layout.nb_channels) {
283  char buf[256];
284  av_channel_layout_describe(&s->output_layout, buf, sizeof(buf));
286  "Output channel layout %s does not match the number of channels mapped %d.\n",
287  buf, s->nch);
288  return AVERROR(EINVAL);
289  }
290 
291  if (!s->output_layout.nb_channels) {
292  av_log(ctx, AV_LOG_ERROR, "Output channel layout is not set and "
293  "cannot be guessed from the maps.\n");
294  return AVERROR(EINVAL);
295  }
296 
298  for (i = 0; i < s->nch; i++) {
299  s->map[i].out_channel_idx = av_channel_layout_index_from_channel(
300  &s->output_layout, s->map[i].out_channel);
301  }
302  }
303 
304  presence_mask = 0;
305  for (i = 0; i < s->nch; i++) {
306  uint64_t idx_mask;
307  int ret = check_idx_and_id(ctx, s->map[i].out_channel_idx, s->map[i].out_channel, &s->output_layout, "out");
308  if (ret < 0)
309  return ret;
310  idx_mask = (1ULL << s->map[i].out_channel_idx);
311  if (presence_mask & idx_mask) {
312  char layout_name[256];
313  av_channel_layout_describe(&s->output_layout, layout_name, sizeof(layout_name));
314  av_log(ctx, AV_LOG_ERROR, "Mapping %d assigns channel #%d twice in output layout '%s'.\n",
315  i + 1, s->map[i].out_channel_idx, layout_name);
316  return AVERROR(EINVAL);
317  }
318  presence_mask |= idx_mask;
319  }
320 
321  return 0;
322 }
323 
325 {
326  ChannelMapContext *s = ctx->priv;
328  int ret;
329 
332  (ret = ff_add_channel_layout(&channel_layouts, &s->output_layout)) < 0 ||
334  &ctx->outputs[0]->incfg.channel_layouts)) < 0)
335  return ret;
336 
338  &ctx->inputs[0]->outcfg.channel_layouts);
339 }
340 
342 {
343  AVFilterContext *ctx = inlink->dst;
344  AVFilterLink *outlink = ctx->outputs[0];
345  const ChannelMapContext *s = ctx->priv;
346  const int nch_in = inlink->ch_layout.nb_channels;
347  const int nch_out = s->nch;
348  int ch, ret;
349  uint8_t *source_planes[MAX_CH];
350 
351  memcpy(source_planes, buf->extended_data,
352  nch_in * sizeof(source_planes[0]));
353 
354  if (nch_out > nch_in) {
355  if (nch_out > FF_ARRAY_ELEMS(buf->data)) {
356  uint8_t **new_extended_data =
357  av_calloc(nch_out, sizeof(*buf->extended_data));
358  if (!new_extended_data) {
359  av_frame_free(&buf);
360  return AVERROR(ENOMEM);
361  }
362  if (buf->extended_data == buf->data) {
363  buf->extended_data = new_extended_data;
364  } else {
365  av_free(buf->extended_data);
366  buf->extended_data = new_extended_data;
367  }
368  } else if (buf->extended_data != buf->data) {
369  av_free(buf->extended_data);
370  buf->extended_data = buf->data;
371  }
372  }
373 
374  for (ch = 0; ch < nch_out; ch++) {
375  buf->extended_data[s->map[ch].out_channel_idx] =
376  source_planes[s->map[ch].in_channel_idx];
377  }
378 
379  if (buf->data != buf->extended_data)
380  memcpy(buf->data, buf->extended_data,
381  FFMIN(FF_ARRAY_ELEMS(buf->data), nch_out) * sizeof(buf->data[0]));
382 
383  if ((ret = av_channel_layout_copy(&buf->ch_layout, &outlink->ch_layout)) < 0)
384  return ret;
385 
386  return ff_filter_frame(outlink, buf);
387 }
388 
390 {
391  AVFilterContext *ctx = inlink->dst;
392  ChannelMapContext *s = ctx->priv;
393  int i, err = 0;
394 
395  for (i = 0; i < s->nch; i++) {
396  struct ChannelMap *m = &s->map[i];
397 
398  if (s->mode == MAP_PAIR_STR_INT || s->mode == MAP_PAIR_STR_STR || s->mode == MAP_ONE_STR) {
400  &inlink->ch_layout, m->in_channel);
401  }
402 
403  if (check_idx_and_id(ctx, m->in_channel_idx, m->in_channel, &inlink->ch_layout, "in") < 0)
404  err = AVERROR(EINVAL);
405  }
406 
407  return err;
408 }
409 
411  {
412  .name = "default",
413  .type = AVMEDIA_TYPE_AUDIO,
415  .filter_frame = channelmap_filter_frame,
416  .config_props = channelmap_config_input,
417  },
418 };
419 
421  .name = "channelmap",
422  .description = NULL_IF_CONFIG_SMALL("Remap audio channels."),
423  .init = channelmap_init,
424  .priv_size = sizeof(ChannelMapContext),
425  .priv_class = &channelmap_class,
429 };
MAX_CH
#define MAX_CH
Definition: af_channelmap.c:58
AVFilterChannelLayouts
A list of supported channel layouts.
Definition: formats.h:85
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
MAP_PAIR_STR_STR
@ MAP_PAIR_STR_STR
Definition: af_channelmap.c:55
message
Definition: api-threadmessage-test.c:47
ChannelMapContext::mode
enum MappingMode mode
Definition: af_channelmap.c:65
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1015
ff_channel_layouts_ref
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:674
channelmap_filter_frame
static int channelmap_filter_frame(AVFilterLink *inlink, AVFrame *buf)
Definition: af_channelmap.c:341
F
#define F
Definition: af_channelmap.c:70
channelmap_init
static av_cold int channelmap_init(AVFilterContext *ctx)
Definition: af_channelmap.c:144
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_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
ff_all_channel_counts
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition.
Definition: formats.c:622
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
AVOption
AVOption.
Definition: opt.h:357
FILTER_QUERY_FUNC
#define FILTER_QUERY_FUNC(func)
Definition: internal.h:159
get_channel
static int get_channel(char **map, int *ch, char delim)
Definition: af_channelmap.c:108
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:822
mathematics.h
channel_name
Definition: channel_layout.c:42
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
MAP_NONE
@ MAP_NONE
Definition: af_channelmap.c:49
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:313
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:395
formats.h
A
#define A
Definition: af_channelmap.c:69
samplefmt.h
ff_af_channelmap
const AVFilter ff_af_channelmap
Definition: af_channelmap.c:420
AVFrame::ch_layout
AVChannelLayout ch_layout
Channel layout of the audio data.
Definition: frame.h:775
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
MappingMode
MappingMode
Definition: af_channelmap.c:48
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:868
av_channel_layout_describe
int av_channel_layout_describe(const AVChannelLayout *channel_layout, char *buf, size_t buf_size)
Get a human-readable string describing the channel layout properties.
Definition: channel_layout.c:644
channelmap_options
static const AVOption channelmap_options[]
Definition: af_channelmap.c:71
s
#define s(width, name)
Definition: cbs_vp9.c:198
MAP_PAIR_STR_INT
@ MAP_PAIR_STR_INT
Definition: af_channelmap.c:54
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
av_channel_layout_from_mask
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:243
ChannelMapContext::nch
int nch
Definition: af_channelmap.c:64
ctx
AVFormatContext * ctx
Definition: movenc.c:49
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:182
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
get_channel_idx
static int get_channel_idx(char **map, int *ch, char delim, int max_nb_channels)
Definition: af_channelmap.c:88
ChannelMapContext::output_layout
AVChannelLayout output_layout
Definition: af_channelmap.c:62
ff_audio_default_filterpad
const AVFilterPad ff_audio_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_AUDIO.
Definition: audio.c:33
ChannelMap::in_channel
int in_channel
Definition: af_channelmap.c:42
AV_OPT_TYPE_CHLAYOUT
@ AV_OPT_TYPE_CHLAYOUT
Definition: opt.h:262
ff_add_channel_layout
int ff_add_channel_layout(AVFilterChannelLayouts **l, const AVChannelLayout *channel_layout)
Definition: formats.c:522
channelmap_query_formats
static int channelmap_query_formats(AVFilterContext *ctx)
Definition: af_channelmap.c:324
MAP_PAIR_INT_INT
@ MAP_PAIR_INT_INT
Definition: af_channelmap.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:94
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:303
ChannelMapContext
Definition: af_channelmap.c:59
avfilter_af_channelmap_inputs
static const AVFilterPad avfilter_af_channelmap_inputs[]
Definition: af_channelmap.c:410
MAP_ONE_STR
@ MAP_ONE_STR
Definition: af_channelmap.c:51
MAP_ONE_INT
@ MAP_ONE_INT
Definition: af_channelmap.c:50
MAP_PAIR_INT_STR
@ MAP_PAIR_INT_STR
Definition: af_channelmap.c:53
channelmap_config_input
static int channelmap_config_input(AVFilterLink *inlink)
Definition: af_channelmap.c:389
split
static char * split(char *message, char delim)
Definition: af_channelmap.c:81
av_isdigit
static av_const int av_isdigit(int c)
Locale-independent conversion of ASCII isdigit.
Definition: avstring.h:202
ChannelMap::in_channel_idx
int in_channel_idx
index of in_channel in the input stream data
Definition: af_channelmap.c:44
ChannelMapContext::mapping_str
char * mapping_str
Definition: af_channelmap.c:61
ChannelMapContext::map
struct ChannelMap map[MAX_CH]
Definition: af_channelmap.c:63
internal.h
av_channel_layout_default
void av_channel_layout_default(AVChannelLayout *ch_layout, int nb_channels)
Get the default channel layout for a given number of channels.
Definition: channel_layout.c:830
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
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:98
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:435
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:594
len
int len
Definition: vorbis_enc_data.h:426
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:39
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
ChannelMap::out_channel
int out_channel
Definition: af_channelmap.c:43
AVFilter
Filter definition.
Definition: avfilter.h:166
ret
ret
Definition: filter_design.txt:187
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:146
ChannelMap::out_channel_idx
int out_channel_idx
Definition: af_channelmap.c:45
channel_layout.h
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(channelmap)
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:704
mode
mode
Definition: ebur128.h:83
avfilter.h
ChannelMap
Definition: opus_parse.h:48
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
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:440
OFFSET
#define OFFSET(x)
Definition: af_channelmap.c:68
mem.h
audio.h
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
check_idx_and_id
static int check_idx_and_id(AVFilterContext *ctx, int channel_idx, int channel, AVChannelLayout *ch_layout, const char *io)
Definition: af_channelmap.c:120
channel_layouts
static const uint16_t channel_layouts[7]
Definition: dca_lbr.c:112
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:183
ChannelMap::channel_idx
int channel_idx
Definition: opus_parse.h:50
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:249
channel
channel
Definition: ebur128.h:39
AVFILTERPAD_FLAG_NEEDS_WRITABLE
#define AVFILTERPAD_FLAG_NEEDS_WRITABLE
The filter expects writable frames from its input link, duplicating data buffers if needed.
Definition: internal.h:52