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
34
39
45 };
46
55 };
56
68
69 #define OFFSET(x) offsetof(ChannelMapContext, x)
70 #define A AV_OPT_FLAG_AUDIO_PARAM
71 #define F AV_OPT_FLAG_FILTERING_PARAM
73 { "map", "A comma-separated list of input channel numbers in output order.",
75 { "channel_layout", "Output channel layout.",
77 { NULL }
78 };
79
81
82 static char*
split(
char *message,
char delim) {
83 char *next = strchr(message, delim);
84 if (next)
85 *next++ = '0円';
86 return next;
87 }
88
90 {
91 char *next =
split(*map, delim);
94 if (!next && delim == '-')
96 len = strlen(*map);
97 sscanf(*map, "%d%n", ch, &n);
98 if (n != len)
100 if (*ch < 0 || *ch > max_ch)
102 *map = next;
103 return 0;
104 }
105
107 {
108 char *next =
split(*map, delim);
109 if (!next && delim == '-')
114 *map = next;
115 return 0;
116 }
117
119 {
121 char *mapping, separator = '|';
122 int map_entries = 0;
125 uint64_t out_ch_mask = 0;
126 int i;
127
129
130 if (!mapping) {
132 } else {
133 char *dash = strchr(mapping, '-');
134 if (!dash) { // short mapping
137 else
142 else
144 } else {
147 else
149 }
150 #if FF_API_OLD_FILTER_OPTS
151 if (strchr(mapping, ',')) {
153 "'|' to separate the mappings.\n");
154 separator = ',';
155 }
156 #endif
157 }
158
160 char *sep = mapping;
161 map_entries = 1;
162 while ((sep = strchr(sep, separator))) {
163 if (*++sep) // Allow trailing comma
164 map_entries++;
165 }
166 }
167
168 if (map_entries >
MAX_CH) {
171 }
172
173 for (i = 0; i < map_entries; i++) {
174 int in_ch_idx = -1, out_ch_idx = -1;
175 uint64_t in_ch = 0, out_ch = 0;
176 static const char err[] = "Failed to parse channel map\n";
177 switch (mode) {
182 }
185 break;
190 }
193 break;
199 }
202 break;
206 out_ch & out_ch_mask) {
209 }
212 out_ch_mask |= out_ch;
213 break;
219 }
222 break;
226 out_ch & out_ch_mask) {
229 }
232 out_ch_mask |= out_ch;
233 break;
234 }
235 }
237 s->
nch = map_entries;
240
247 }
249 int i;
251 for (i = 0; i < s->
nch; i++) {
254 }
255 } else if (out_ch_mask && out_ch_mask != fmt) {
258 "Output channel layout '%s' does not match the list of channel mapped: '%s'.\n",
263 "Output channel layout %s does not match the number of channels mapped %d.\n",
266 }
268 }
271 "cannot be guessed from the maps.\n");
273 }
274
276
278 for (i = 0; i < s->
nch; i++) {
281 }
282 }
283
284 return 0;
285 }
286
288 {
290
295
296 return 0;
297 }
298
300 {
305 const int nch_out = s->
nch;
306 int ch;
308
310 nch_in * sizeof(source_planes[0]));
311
312 if (nch_out > nch_in) {
316 if (!new_extended_data) {
319 }
322 } else {
325 }
329 }
330 }
331
332 for (ch = 0; ch < nch_out; ch++) {
335 }
336
340
342 }
343
345 {
349 int i, err = 0;
351 char layout_name[256];
352
353 for (i = 0; i < s->
nch; i++) {
355
359 }
360
367 "input channel '%s' not available from input layout '%s'\n",
368 channel_name, layout_name);
369 } else {
371 "input channel #%d not available from input layout '%s'\n",
373 }
375 }
376 }
377
378 return err;
379 }
380
382 {
387 .needs_writable = 1,
388 },
389 { NULL }
390 };
391
393 {
396 },
397 { NULL }
398 };
399
401 .
name =
"channelmap",
406 .priv_class = &channelmap_class,
407 .
inputs = avfilter_af_channelmap_inputs,
408 .
outputs = avfilter_af_channelmap_outputs,
409 };