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/opt.h"
33 #include "libavutil/samplefmt.h"
34 
35 #include "audio.h"
36 #include "avfilter.h"
37 #include "formats.h"
38 #include "internal.h"
39 
40 struct ChannelMap {
45 };
46 
55 };
56 
57 #define MAX_CH 64
58 typedef struct ChannelMapContext {
59  const AVClass *class;
60  char *mapping_str;
63  int nch;
66 
67 #define OFFSET(x) offsetof(ChannelMapContext, x)
68 #define A AV_OPT_FLAG_AUDIO_PARAM
69 #define F AV_OPT_FLAG_FILTERING_PARAM
70 static const AVOption channelmap_options[] = {
71  { "map", "A comma-separated list of input channel numbers in output order.",
72  OFFSET(mapping_str), AV_OPT_TYPE_STRING, .flags = A|F },
73  { "channel_layout", "Output channel layout.",
74  OFFSET(output_layout), AV_OPT_TYPE_CHLAYOUT, .flags = A|F },
75  { NULL }
76 };
77 
78 AVFILTER_DEFINE_CLASS(channelmap);
79 
80 static char* split(char *message, char delim) {
81  char *next = strchr(message, delim);
82  if (next)
83  *next++ = '\0';
84  return next;
85 }
86 
87 static int get_channel_idx(char **map, int *ch, char delim, int max_nb_channels)
88 {
89  char *next;
90  int len;
91  int n = 0;
92  if (!*map)
93  return AVERROR(EINVAL);
94  next = split(*map, delim);
95  if (!next && delim == '-')
96  return AVERROR(EINVAL);
97  len = strlen(*map);
98  sscanf(*map, "%d%n", ch, &n);
99  if (n != len)
100  return AVERROR(EINVAL);
101  if (*ch < 0 || *ch >= max_nb_channels)
102  return AVERROR(EINVAL);
103  *map = next;
104  return 0;
105 }
106 
107 static int get_channel(char **map, int *ch, char delim)
108 {
109  char *next = split(*map, delim);
110  if (!next && delim == '-')
111  return AVERROR(EINVAL);
112  *ch = av_channel_from_string(*map);
113  if (*ch < 0)
114  return AVERROR(EINVAL);
115  *map = next;
116  return 0;
117 }
118 
119 static int check_idx_and_id(AVFilterContext *ctx, int channel_idx, int channel, AVChannelLayout *ch_layout, const char *io)
120 {
121  char channel_name[64];
122  char layout_name[256];
123  int nb_channels = ch_layout->nb_channels;
124 
125  if (channel_idx < 0 || channel_idx >= nb_channels) {
126  av_channel_layout_describe(ch_layout, layout_name, sizeof(layout_name));
127  if (channel >= 0) {
130  "%sput channel '%s' not available from %sput layout '%s'\n",
131  io, channel_name, io, layout_name);
132  } else {
134  "%sput channel #%d not available from %sput layout '%s'\n",
135  io, channel_idx, io, layout_name);
136  }
137  return AVERROR(EINVAL);
138  }
139 
140  return 0;
141 }
142 
144 {
145  ChannelMapContext *s = ctx->priv;
146  char *mapping, separator = '|';
147  int map_entries = 0;
148  enum MappingMode mode;
149  int64_t out_ch_mask = 0;
150  uint64_t presence_mask;
151  int i;
152 
153  mapping = s->mapping_str;
154 
155  if (!mapping) {
156  mode = MAP_NONE;
157  } else {
158  char *dash = strchr(mapping, '-');
159  if (!dash) { // short mapping
160  if (av_isdigit(*mapping))
161  mode = MAP_ONE_INT;
162  else
163  mode = MAP_ONE_STR;
164  } else if (av_isdigit(*mapping)) {
165  if (av_isdigit(*(dash+1)))
167  else
169  } else {
170  if (av_isdigit(*(dash+1)))
172  else
174  }
175  }
176 
177  if (mode != MAP_NONE) {
178  char *sep = mapping;
179  map_entries = 1;
180  while ((sep = strchr(sep, separator))) {
181  if (*++sep) // Allow trailing comma
182  map_entries++;
183  }
184  }
185 
186  if (map_entries > MAX_CH) {
187  av_log(ctx, AV_LOG_ERROR, "Too many channels mapped: '%d'.\n", map_entries);
188  return AVERROR(EINVAL);
189  }
190 
191  for (i = 0; i < MAX_CH; i++) {
192  s->map[i].in_channel_idx = -1;
193  s->map[i].out_channel_idx = -1;
194  s->map[i].in_channel = -1;
195  s->map[i].out_channel = -1;
196  }
197 
198  for (i = 0; i < map_entries; i++) {
199  int in_ch_idx = -1, out_ch_idx = -1;
200  int in_ch = -1, out_ch = -1;
201  static const char err[] = "Failed to parse channel map\n";
202  switch (mode) {
203  case MAP_ONE_INT:
204  if (get_channel_idx(&mapping, &in_ch_idx, separator, MAX_CH) < 0) {
205  av_log(ctx, AV_LOG_ERROR, err);
206  return AVERROR(EINVAL);
207  }
208  s->map[i].in_channel_idx = in_ch_idx;
209  s->map[i].out_channel_idx = i;
210  break;
211  case MAP_ONE_STR:
212  if (get_channel(&mapping, &in_ch, separator) < 0) {
213  av_log(ctx, AV_LOG_ERROR, err);
214  return AVERROR(EINVAL);
215  }
216  s->map[i].in_channel = in_ch;
217  s->map[i].out_channel_idx = i;
218  break;
219  case MAP_PAIR_INT_INT:
220  if (get_channel_idx(&mapping, &in_ch_idx, '-', MAX_CH) < 0 ||
221  get_channel_idx(&mapping, &out_ch_idx, separator, MAX_CH) < 0) {
222  av_log(ctx, AV_LOG_ERROR, err);
223  return AVERROR(EINVAL);
224  }
225  s->map[i].in_channel_idx = in_ch_idx;
226  s->map[i].out_channel_idx = out_ch_idx;
227  break;
228  case MAP_PAIR_INT_STR:
229  if (get_channel_idx(&mapping, &in_ch_idx, '-', MAX_CH) < 0 ||
230  get_channel(&mapping, &out_ch, separator) < 0) {
231  av_log(ctx, AV_LOG_ERROR, err);
232  return AVERROR(EINVAL);
233  }
234  s->map[i].in_channel_idx = in_ch_idx;
235  s->map[i].out_channel = out_ch;
236  if (out_ch < 63)
237  out_ch_mask |= 1ULL << out_ch;
238  else
239  out_ch_mask = -1;
240  break;
241  case MAP_PAIR_STR_INT:
242  if (get_channel(&mapping, &in_ch, '-') < 0 ||
243  get_channel_idx(&mapping, &out_ch_idx, separator, MAX_CH) < 0) {
244  av_log(ctx, AV_LOG_ERROR, err);
245  return AVERROR(EINVAL);
246  }
247  s->map[i].in_channel = in_ch;
248  s->map[i].out_channel_idx = out_ch_idx;
249  break;
250  case MAP_PAIR_STR_STR:
251  if (get_channel(&mapping, &in_ch, '-') < 0 ||
252  get_channel(&mapping, &out_ch, separator) < 0) {
253  av_log(ctx, AV_LOG_ERROR, err);
254  return AVERROR(EINVAL);
255  }
256  s->map[i].in_channel = in_ch;
257  s->map[i].out_channel = out_ch;
258  if (out_ch < 63)
259  out_ch_mask |= 1ULL << out_ch;
260  else
261  out_ch_mask = -1;
262  break;
263  }
264  }
265  s->mode = mode;
266  s->nch = map_entries;
267  if (s->output_layout.nb_channels == 0) {
268  if (out_ch_mask > 0)
269  av_channel_layout_from_mask(&s->output_layout, out_ch_mask);
270  else if (map_entries)
271  av_channel_layout_default(&s->output_layout, map_entries);
272  }
273 
274  if (mode == MAP_NONE) {
275  int i;
276  s->nch = s->output_layout.nb_channels;
277  for (i = 0; i < s->nch; i++) {
278  s->map[i].in_channel_idx = i;
279  s->map[i].out_channel_idx = i;
280  }
281  } else if (s->nch != s->output_layout.nb_channels) {
282  char buf[256];
283  av_channel_layout_describe(&s->output_layout, buf, sizeof(buf));
285  "Output channel layout %s does not match the number of channels mapped %d.\n",
286  buf, s->nch);
287  return AVERROR(EINVAL);
288  }
289 
290  if (!s->output_layout.nb_channels) {
291  av_log(ctx, AV_LOG_ERROR, "Output channel layout is not set and "
292  "cannot be guessed from the maps.\n");
293  return AVERROR(EINVAL);
294  }
295 
297  for (i = 0; i < s->nch; i++) {
298  s->map[i].out_channel_idx = av_channel_layout_index_from_channel(
299  &s->output_layout, s->map[i].out_channel);
300  }
301  }
302 
303  presence_mask = 0;
304  for (i = 0; i < s->nch; i++) {
305  uint64_t idx_mask;
306  int ret = check_idx_and_id(ctx, s->map[i].out_channel_idx, s->map[i].out_channel, &s->output_layout, "out");
307  if (ret < 0)
308  return ret;
309  idx_mask = (1ULL << s->map[i].out_channel_idx);
310  if (presence_mask & idx_mask) {
311  char layout_name[256];
312  av_channel_layout_describe(&s->output_layout, layout_name, sizeof(layout_name));
313  av_log(ctx, AV_LOG_ERROR, "Mapping %d assigns channel #%d twice in output layout '%s'.\n",
314  i + 1, s->map[i].out_channel_idx, layout_name);
315  return AVERROR(EINVAL);
316  }
317  presence_mask |= idx_mask;
318  }
319 
320  return 0;
321 }
322 
324 {
325  ChannelMapContext *s = ctx->priv;
327  int ret;
328 
331  (ret = ff_add_channel_layout(&channel_layouts, &s->output_layout)) < 0 ||
333  &ctx->outputs[0]->incfg.channel_layouts)) < 0)
334  return ret;
335 
337  &ctx->inputs[0]->outcfg.channel_layouts);
338 }
339 
341 {
342  AVFilterContext *ctx = inlink->dst;
343  AVFilterLink *outlink = ctx->outputs[0];
344  const ChannelMapContext *s = ctx->priv;
345  const int nch_in = inlink->ch_layout.nb_channels;
346  const int nch_out = s->nch;
347  int ch, ret;
348  uint8_t *source_planes[MAX_CH];
349 
350  memcpy(source_planes, buf->extended_data,
351  nch_in * sizeof(source_planes[0]));
352 
353  if (nch_out > nch_in) {
354  if (nch_out > FF_ARRAY_ELEMS(buf->data)) {
355  uint8_t **new_extended_data =
356  av_calloc(nch_out, sizeof(*buf->extended_data));
357  if (!new_extended_data) {
358  av_frame_free(&buf);
359  return AVERROR(ENOMEM);
360  }
361  if (buf->extended_data == buf->data) {
362  buf->extended_data = new_extended_data;
363  } else {
364  av_free(buf->extended_data);
365  buf->extended_data = new_extended_data;
366  }
367  } else if (buf->extended_data != buf->data) {
368  av_free(buf->extended_data);
369  buf->extended_data = buf->data;
370  }
371  }
372 
373  for (ch = 0; ch < nch_out; ch++) {
374  buf->extended_data[s->map[ch].out_channel_idx] =
375  source_planes[s->map[ch].in_channel_idx];
376  }
377 
378  if (buf->data != buf->extended_data)
379  memcpy(buf->data, buf->extended_data,
380  FFMIN(FF_ARRAY_ELEMS(buf->data), nch_out) * sizeof(buf->data[0]));
381 
382  if ((ret = av_channel_layout_copy(&buf->ch_layout, &outlink->ch_layout)) < 0)
383  return ret;
384 
385  return ff_filter_frame(outlink, buf);
386 }
387 
389 {
390  AVFilterContext *ctx = inlink->dst;
391  ChannelMapContext *s = ctx->priv;
392  int i, err = 0;
393 
394  for (i = 0; i < s->nch; i++) {
395  struct ChannelMap *m = &s->map[i];
396 
397  if (s->mode == MAP_PAIR_STR_INT || s->mode == MAP_PAIR_STR_STR || s->mode == MAP_ONE_STR) {
399  &inlink->ch_layout, m->in_channel);
400  }
401 
402  if (check_idx_and_id(ctx, m->in_channel_idx, m->in_channel, &inlink->ch_layout, "in") < 0)
403  err = AVERROR(EINVAL);
404  }
405 
406  return err;
407 }
408 
410  {
411  .name = "default",
412  .type = AVMEDIA_TYPE_AUDIO,
414  .filter_frame = channelmap_filter_frame,
415  .config_props = channelmap_config_input,
416  },
417 };
418 
420  .name = "channelmap",
421  .description = NULL_IF_CONFIG_SMALL("Remap audio channels."),
422  .init = channelmap_init,
423  .priv_size = sizeof(ChannelMapContext),
424  .priv_class = &channelmap_class,
428 };
MAX_CH
#define MAX_CH
Definition: af_channelmap.c:57
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:54
message
Definition: api-threadmessage-test.c:46
ChannelMapContext::mode
enum MappingMode mode
Definition: af_channelmap.c:64
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:673
channelmap_filter_frame
static int channelmap_filter_frame(AVFilterLink *inlink, AVFrame *buf)
Definition: af_channelmap.c:340
F
#define F
Definition: af_channelmap.c:69
channelmap_init
static av_cold int channelmap_init(AVFilterContext *ctx)
Definition: af_channelmap.c:143
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:621
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:375
AVOption
AVOption.
Definition: opt.h:346
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:107
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:821
mathematics.h
channel_name
Definition: channel_layout.c:41
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
MAP_NONE
@ MAP_NONE
Definition: af_channelmap.c:48
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:396
formats.h
A
#define A
Definition: af_channelmap.c:68
samplefmt.h
ff_af_channelmap
const AVFilter ff_af_channelmap
Definition: af_channelmap.c:419
AVFrame::ch_layout
AVChannelLayout ch_layout
Channel layout of the audio data.
Definition: frame.h:776
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
MappingMode
MappingMode
Definition: af_channelmap.c:47
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:867
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:70
s
#define s(width, name)
Definition: cbs_vp9.c:198
MAP_PAIR_STR_INT
@ MAP_PAIR_STR_INT
Definition: af_channelmap.c:53
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:242
ChannelMapContext::nch
int nch
Definition: af_channelmap.c:63
ctx
AVFormatContext * ctx
Definition: movenc.c:48
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:87
ChannelMapContext::output_layout
AVChannelLayout output_layout
Definition: af_channelmap.c:61
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:41
AV_OPT_TYPE_CHLAYOUT
@ AV_OPT_TYPE_CHLAYOUT
Definition: opt.h:252
ff_add_channel_layout
int ff_add_channel_layout(AVFilterChannelLayouts **l, const AVChannelLayout *channel_layout)
Definition: formats.c:521
channelmap_query_formats
static int channelmap_query_formats(AVFilterContext *ctx)
Definition: af_channelmap.c:323
MAP_PAIR_INT_INT
@ MAP_PAIR_INT_INT
Definition: af_channelmap.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:303
ChannelMapContext
Definition: af_channelmap.c:58
avfilter_af_channelmap_inputs
static const AVFilterPad avfilter_af_channelmap_inputs[]
Definition: af_channelmap.c:409
MAP_ONE_STR
@ MAP_ONE_STR
Definition: af_channelmap.c:50
MAP_ONE_INT
@ MAP_ONE_INT
Definition: af_channelmap.c:49
MAP_PAIR_INT_STR
@ MAP_PAIR_INT_STR
Definition: af_channelmap.c:52
channelmap_config_input
static int channelmap_config_input(AVFilterLink *inlink)
Definition: af_channelmap.c:388
split
static char * split(char *message, char delim)
Definition: af_channelmap.c:80
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:43
ChannelMapContext::mapping_str
char * mapping_str
Definition: af_channelmap.c:60
ChannelMapContext::map
struct ChannelMap map[MAX_CH]
Definition: af_channelmap.c:62
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: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:97
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:436
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:593
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:262
ChannelMap::out_channel
int out_channel
Definition: af_channelmap.c:42
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:145
ChannelMap::out_channel_idx
int out_channel_idx
Definition: af_channelmap.c:44
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:439
OFFSET
#define OFFSET(x)
Definition: af_channelmap.c:67
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:119
channel_layouts
static const uint16_t channel_layouts[7]
Definition: dca_lbr.c:111
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:239
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