lavfi: Drop deprecated non-const filter retrieval
[ffmpeg.git] / libavfilter / avfiltergraph.c
1 /*
2  * filter graphs
3  * Copyright (c) 2008 Vitor Sessak
4  * Copyright (c) 2007 Bobby Bingham
5  *
6  * This file is part of Libav.
7  *
8  * Libav is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * Libav is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with Libav; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 #include "config.h"
24
25 #include <string.h>
26
27 #include "libavutil/avassert.h"
28 #include "libavutil/avstring.h"
29 #include "libavutil/channel_layout.h"
30 #include "libavutil/common.h"
31 #include "libavutil/internal.h"
32 #include "libavutil/log.h"
33 #include "libavutil/opt.h"
34
35 #include "avfilter.h"
36 #include "formats.h"
37 #include "internal.h"
38 #include "thread.h"
39
40 #define OFFSET(x) offsetof(AVFilterGraph, x)
41 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM
42 static const AVOption filtergraph_options[] = {
43     { "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,
44         { .i64 = AVFILTER_THREAD_SLICE }, 0, INT_MAX, FLAGS, "thread_type" },
45         { "slice", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVFILTER_THREAD_SLICE }, .flags = FLAGS, .unit = "thread_type" },
46     { "threads",     "Maximum number of threads", OFFSET(nb_threads),
47         AV_OPT_TYPE_INT,   { .i64 = 0 }, 0, INT_MAX, FLAGS },
48     { NULL },
49 };
50
51 static const AVClass filtergraph_class = {
52     .class_name = "AVFilterGraph",
53     .item_name  = av_default_item_name,
54     .version    = LIBAVUTIL_VERSION_INT,
55     .option     = filtergraph_options,
56 };
57
58 #if !HAVE_THREADS
59 void ff_graph_thread_free(AVFilterGraph *graph)
60 {
61 }
62
63 int ff_graph_thread_init(AVFilterGraph *graph)
64 {
65     graph->thread_type = 0;
66     graph->nb_threads  = 1;
67     return 0;
68 }
69 #endif
70
71 AVFilterGraph *avfilter_graph_alloc(void)
72 {
73     AVFilterGraph *ret = av_mallocz(sizeof(*ret));
74     if (!ret)
75         return NULL;
76
77     ret->internal = av_mallocz(sizeof(*ret->internal));
78     if (!ret->internal) {
79         av_freep(&ret);
80         return NULL;
81     }
82
83     ret->av_class = &filtergraph_class;
84     av_opt_set_defaults(ret);
85
86     return ret;
87 }
88
89 void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter)
90 {
91     int i;
92     for (i = 0; i < graph->nb_filters; i++) {
93         if (graph->filters[i] == filter) {
94             FFSWAP(AVFilterContext*, graph->filters[i],
95                    graph->filters[graph->nb_filters - 1]);
96             graph->nb_filters--;
97             return;
98         }
99     }
100 }
101
102 void avfilter_graph_free(AVFilterGraph **graph)
103 {
104     if (!*graph)
105         return;
106
107     while ((*graph)->nb_filters)
108         avfilter_free((*graph)->filters[0]);
109
110     ff_graph_thread_free(*graph);
111
112     av_freep(&(*graph)->scale_sws_opts);
113     av_freep(&(*graph)->resample_lavr_opts);
114     av_freep(&(*graph)->filters);
115     av_freep(&(*graph)->internal);
116     av_freep(graph);
117 }
118
119 int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt,
120                                  const char *name, const char *args, void *opaque,
121                                  AVFilterGraph *graph_ctx)
122 {
123     int ret;
124
125     *filt_ctx = avfilter_graph_alloc_filter(graph_ctx, filt, name);
126     if (!*filt_ctx)
127         return AVERROR(ENOMEM);
128
129     ret = avfilter_init_str(*filt_ctx, args);
130     if (ret < 0)
131         goto fail;
132
133     return 0;
134
135 fail:
136     if (*filt_ctx)
137         avfilter_free(*filt_ctx);
138     *filt_ctx = NULL;
139     return ret;
140 }
141
142 AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph,
143                                              const AVFilter *filter,
144                                              const char *name)
145 {
146     AVFilterContext **filters, *s;
147
148     if (graph->thread_type && !graph->internal->thread_execute) {
149         if (graph->execute) {
150             graph->internal->thread_execute = graph->execute;
151         } else {
152             int ret = ff_graph_thread_init(graph);
153             if (ret < 0) {
154                 av_log(graph, AV_LOG_ERROR, "Error initializing threading.\n");
155                 return NULL;
156             }
157         }
158     }
159
160     s = ff_filter_alloc(filter, name);
161     if (!s)
162         return NULL;
163
164     filters = av_realloc(graph->filters, sizeof(*filters) * (graph->nb_filters + 1));
165     if (!filters) {
166         avfilter_free(s);
167         return NULL;
168     }
169
170     graph->filters = filters;
171     graph->filters[graph->nb_filters++] = s;
172
173     s->graph = graph;
174
175     return s;
176 }
177
178 /**
179  * Check for the validity of graph.
180  *
181  * A graph is considered valid if all its input and output pads are
182  * connected.
183  *
184  * @return 0 in case of success, a negative value otherwise
185  */
186 static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
187 {
188     AVFilterContext *filt;
189     int i, j;
190
191     for (i = 0; i < graph->nb_filters; i++) {
192         filt = graph->filters[i];
193
194         for (j = 0; j < filt->nb_inputs; j++) {
195             if (!filt->inputs[j] || !filt->inputs[j]->src) {
196                 av_log(log_ctx, AV_LOG_ERROR,
197                        "Input pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any source\n",
198                        filt->input_pads[j].name, filt->name, filt->filter->name);
199                 return AVERROR(EINVAL);
200             }
201         }
202
203         for (j = 0; j < filt->nb_outputs; j++) {
204             if (!filt->outputs[j] || !filt->outputs[j]->dst) {
205                 av_log(log_ctx, AV_LOG_ERROR,
206                        "Output pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any destination\n",
207                        filt->output_pads[j].name, filt->name, filt->filter->name);
208                 return AVERROR(EINVAL);
209             }
210         }
211     }
212
213     return 0;
214 }
215
216 /**
217  * Configure all the links of graphctx.
218  *
219  * @return 0 in case of success, a negative value otherwise
220  */
221 static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
222 {
223     AVFilterContext *filt;
224     int i, ret;
225
226     for (i = 0; i < graph->nb_filters; i++) {
227         filt = graph->filters[i];
228
229         if (!filt->nb_outputs) {
230             if ((ret = avfilter_config_links(filt)))
231                 return ret;
232         }
233     }
234
235     return 0;
236 }
237
238 AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name)
239 {
240     int i;
241
242     for (i = 0; i < graph->nb_filters; i++)
243         if (graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
244             return graph->filters[i];
245
246     return NULL;
247 }
248
249 static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
250 {
251     int i, j, ret;
252     int scaler_count = 0, resampler_count = 0;
253
254     /* ask all the sub-filters for their supported media formats */
255     for (i = 0; i < graph->nb_filters; i++) {
256         if (graph->filters[i]->filter->query_formats)
257             ret = graph->filters[i]->filter->query_formats(graph->filters[i]);
258         else
259             ret = ff_default_query_formats(graph->filters[i]);
260         if (ret < 0) {
261             av_log(log_ctx, AV_LOG_ERROR,
262                    "Error querying formats for the filter %s (%s)\n",
263                    graph->filters[i]->name, graph->filters[i]->filter->name);
264             return ret;
265         }
266     }
267
268     /* go through and merge as many format lists as possible */
269     for (i = 0; i < graph->nb_filters; i++) {
270         AVFilterContext *filter = graph->filters[i];
271
272         for (j = 0; j < filter->nb_inputs; j++) {
273             AVFilterLink *link = filter->inputs[j];
274             int convert_needed = 0;
275
276             if (!link)
277                 continue;
278
279             if (link->in_formats != link->out_formats &&
280                 !ff_merge_formats(link->in_formats,
281                                         link->out_formats))
282                 convert_needed = 1;
283             if (link->type == AVMEDIA_TYPE_AUDIO) {
284                 if (link->in_channel_layouts != link->out_channel_layouts &&
285                     !ff_merge_channel_layouts(link->in_channel_layouts,
286                                               link->out_channel_layouts))
287                     convert_needed = 1;
288                 if (link->in_samplerates != link->out_samplerates &&
289                     !ff_merge_samplerates(link->in_samplerates,
290                                           link->out_samplerates))
291                     convert_needed = 1;
292             }
293
294             if (convert_needed) {
295                 AVFilterContext *convert;
296                 const AVFilter *filter;
297                 AVFilterLink *inlink, *outlink;
298                 char scale_args[256];
299                 char inst_name[30];
300
301                 /* couldn't merge format lists. auto-insert conversion filter */
302                 switch (link->type) {
303                 case AVMEDIA_TYPE_VIDEO:
304                     if (!(filter = avfilter_get_by_name("scale"))) {
305                         av_log(log_ctx, AV_LOG_ERROR, "'scale' filter "
306                                "not present, cannot convert pixel formats.\n");
307                         return AVERROR(EINVAL);
308                     }
309
310                     snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
311                              scaler_count++);
312
313                     if ((ret = avfilter_graph_create_filter(&convert, filter,
314                                                             inst_name, graph->scale_sws_opts, NULL,
315                                                             graph)) < 0)
316                         return ret;
317                     break;
318                 case AVMEDIA_TYPE_AUDIO:
319                     if (!(filter = avfilter_get_by_name("resample"))) {
320                         av_log(log_ctx, AV_LOG_ERROR, "'resample' filter "
321                                "not present, cannot convert audio formats.\n");
322                         return AVERROR(EINVAL);
323                     }
324
325                     snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d",
326                              resampler_count++);
327                     scale_args[0] = '\0';
328                     if (graph->resample_lavr_opts)
329                         snprintf(scale_args, sizeof(scale_args), "%s",
330                                  graph->resample_lavr_opts);
331                     if ((ret = avfilter_graph_create_filter(&convert, filter,
332                                                             inst_name, scale_args,
333                                                             NULL, graph)) < 0)
334                         return ret;
335                     break;
336                 default:
337                     return AVERROR(EINVAL);
338                 }
339
340                 if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
341                     return ret;
342
343                 convert->filter->query_formats(convert);
344                 inlink  = convert->inputs[0];
345                 outlink = convert->outputs[0];
346                 if (!ff_merge_formats( inlink->in_formats,  inlink->out_formats) ||
347                     !ff_merge_formats(outlink->in_formats, outlink->out_formats))
348                     ret |= AVERROR(ENOSYS);
349                 if (inlink->type == AVMEDIA_TYPE_AUDIO &&
350                     (!ff_merge_samplerates(inlink->in_samplerates,
351                                            inlink->out_samplerates) ||
352                      !ff_merge_channel_layouts(inlink->in_channel_layouts,
353                                                inlink->out_channel_layouts)))
354                     ret |= AVERROR(ENOSYS);
355                 if (outlink->type == AVMEDIA_TYPE_AUDIO &&
356                     (!ff_merge_samplerates(outlink->in_samplerates,
357                                            outlink->out_samplerates) ||
358                      !ff_merge_channel_layouts(outlink->in_channel_layouts,
359                                                outlink->out_channel_layouts)))
360                     ret |= AVERROR(ENOSYS);
361
362                 if (ret < 0) {
363                     av_log(log_ctx, AV_LOG_ERROR,
364                            "Impossible to convert between the formats supported by the filter "
365                            "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
366                     return ret;
367                 }
368             }
369         }
370     }
371
372     return 0;
373 }
374
375 static int pick_format(AVFilterLink *link)
376 {
377     if (!link || !link->in_formats)
378         return 0;
379
380     link->in_formats->nb_formats = 1;
381     link->format = link->in_formats->formats[0];
382
383     if (link->type == AVMEDIA_TYPE_AUDIO) {
384         if (!link->in_samplerates->nb_formats) {
385             av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
386                    " the link between filters %s and %s.\n", link->src->name,
387                    link->dst->name);
388             return AVERROR(EINVAL);
389         }
390         link->in_samplerates->nb_formats = 1;
391         link->sample_rate = link->in_samplerates->formats[0];
392
393         if (!link->in_channel_layouts->nb_channel_layouts) {
394             av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
395                    "the link between filters %s and %s.\n", link->src->name,
396                    link->dst->name);
397             return AVERROR(EINVAL);
398         }
399         link->in_channel_layouts->nb_channel_layouts = 1;
400         link->channel_layout = link->in_channel_layouts->channel_layouts[0];
401     }
402
403     ff_formats_unref(&link->in_formats);
404     ff_formats_unref(&link->out_formats);
405     ff_formats_unref(&link->in_samplerates);
406     ff_formats_unref(&link->out_samplerates);
407     ff_channel_layouts_unref(&link->in_channel_layouts);
408     ff_channel_layouts_unref(&link->out_channel_layouts);
409
410     return 0;
411 }
412
413 #define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format) \
414 do {                                                                   \
415     for (i = 0; i < filter->nb_inputs; i++) {                          \
416         AVFilterLink *link = filter->inputs[i];                        \
417         fmt_type fmt;                                                  \
418                                                                        \
419         if (!link->out_ ## list || link->out_ ## list->nb != 1)        \
420             continue;                                                  \
421         fmt = link->out_ ## list->var[0];                              \
422                                                                        \
423         for (j = 0; j < filter->nb_outputs; j++) {                     \
424             AVFilterLink *out_link = filter->outputs[j];               \
425             list_type *fmts;                                           \
426                                                                        \
427             if (link->type != out_link->type ||                        \
428                 out_link->in_ ## list->nb == 1)                        \
429                 continue;                                              \
430             fmts = out_link->in_ ## list;                              \
431                                                                        \
432             if (!out_link->in_ ## list->nb) {                          \
433                 add_format(&out_link->in_ ##list, fmt);                \
434                 break;                                                 \
435             }                                                          \
436                                                                        \
437             for (k = 0; k < out_link->in_ ## list->nb; k++)            \
438                 if (fmts->var[k] == fmt) {                             \
439                     fmts->var[0]  = fmt;                               \
440                     fmts->nb = 1;                                      \
441                     ret = 1;                                           \
442                     break;                                             \
443                 }                                                      \
444         }                                                              \
445     }                                                                  \
446 } while (0)
447
448 static int reduce_formats_on_filter(AVFilterContext *filter)
449 {
450     int i, j, k, ret = 0;
451
452     REDUCE_FORMATS(int,      AVFilterFormats,        formats,         formats,
453                    nb_formats, ff_add_format);
454     REDUCE_FORMATS(int,      AVFilterFormats,        samplerates,     formats,
455                    nb_formats, ff_add_format);
456     REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts,
457                    channel_layouts, nb_channel_layouts, ff_add_channel_layout);
458
459     return ret;
460 }
461
462 static void reduce_formats(AVFilterGraph *graph)
463 {
464     int i, reduced;
465
466     do {
467         reduced = 0;
468
469         for (i = 0; i < graph->nb_filters; i++)
470             reduced |= reduce_formats_on_filter(graph->filters[i]);
471     } while (reduced);
472 }
473
474 static void swap_samplerates_on_filter(AVFilterContext *filter)
475 {
476     AVFilterLink *link = NULL;
477     int sample_rate;
478     int i, j;
479
480     for (i = 0; i < filter->nb_inputs; i++) {
481         link = filter->inputs[i];
482
483         if (link->type == AVMEDIA_TYPE_AUDIO &&
484             link->out_samplerates->nb_formats== 1)
485             break;
486     }
487     if (i == filter->nb_inputs)
488         return;
489
490     sample_rate = link->out_samplerates->formats[0];
491
492     for (i = 0; i < filter->nb_outputs; i++) {
493         AVFilterLink *outlink = filter->outputs[i];
494         int best_idx, best_diff = INT_MAX;
495
496         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
497             outlink->in_samplerates->nb_formats < 2)
498             continue;
499
500         for (j = 0; j < outlink->in_samplerates->nb_formats; j++) {
501             int diff = abs(sample_rate - outlink->in_samplerates->formats[j]);
502
503             if (diff < best_diff) {
504                 best_diff = diff;
505                 best_idx  = j;
506             }
507         }
508         FFSWAP(int, outlink->in_samplerates->formats[0],
509                outlink->in_samplerates->formats[best_idx]);
510     }
511 }
512
513 static void swap_samplerates(AVFilterGraph *graph)
514 {
515     int i;
516
517     for (i = 0; i < graph->nb_filters; i++)
518         swap_samplerates_on_filter(graph->filters[i]);
519 }
520
521 #define CH_CENTER_PAIR (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)
522 #define CH_FRONT_PAIR  (AV_CH_FRONT_LEFT           | AV_CH_FRONT_RIGHT)
523 #define CH_STEREO_PAIR (AV_CH_STEREO_LEFT          | AV_CH_STEREO_RIGHT)
524 #define CH_WIDE_PAIR   (AV_CH_WIDE_LEFT            | AV_CH_WIDE_RIGHT)
525 #define CH_SIDE_PAIR   (AV_CH_SIDE_LEFT            | AV_CH_SIDE_RIGHT)
526 #define CH_DIRECT_PAIR (AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT)
527 #define CH_BACK_PAIR   (AV_CH_BACK_LEFT            | AV_CH_BACK_RIGHT)
528
529 /* allowable substitutions for channel pairs when comparing layouts,
530  * ordered by priority for both values */
531 static const uint64_t ch_subst[][2] = {
532     { CH_FRONT_PAIR,      CH_CENTER_PAIR     },
533     { CH_FRONT_PAIR,      CH_WIDE_PAIR       },
534     { CH_FRONT_PAIR,      AV_CH_FRONT_CENTER },
535     { CH_CENTER_PAIR,     CH_FRONT_PAIR      },
536     { CH_CENTER_PAIR,     CH_WIDE_PAIR       },
537     { CH_CENTER_PAIR,     AV_CH_FRONT_CENTER },
538     { CH_WIDE_PAIR,       CH_FRONT_PAIR      },
539     { CH_WIDE_PAIR,       CH_CENTER_PAIR     },
540     { CH_WIDE_PAIR,       AV_CH_FRONT_CENTER },
541     { AV_CH_FRONT_CENTER, CH_FRONT_PAIR      },
542     { AV_CH_FRONT_CENTER, CH_CENTER_PAIR     },
543     { AV_CH_FRONT_CENTER, CH_WIDE_PAIR       },
544     { CH_SIDE_PAIR,       CH_DIRECT_PAIR     },
545     { CH_SIDE_PAIR,       CH_BACK_PAIR       },
546     { CH_SIDE_PAIR,       AV_CH_BACK_CENTER  },
547     { CH_BACK_PAIR,       CH_DIRECT_PAIR     },
548     { CH_BACK_PAIR,       CH_SIDE_PAIR       },
549     { CH_BACK_PAIR,       AV_CH_BACK_CENTER  },
550     { AV_CH_BACK_CENTER,  CH_BACK_PAIR       },
551     { AV_CH_BACK_CENTER,  CH_DIRECT_PAIR     },
552     { AV_CH_BACK_CENTER,  CH_SIDE_PAIR       },
553 };
554
555 static void swap_channel_layouts_on_filter(AVFilterContext *filter)
556 {
557     AVFilterLink *link = NULL;
558     int i, j, k;
559
560     for (i = 0; i < filter->nb_inputs; i++) {
561         link = filter->inputs[i];
562
563         if (link->type == AVMEDIA_TYPE_AUDIO &&
564             link->out_channel_layouts->nb_channel_layouts == 1)
565             break;
566     }
567     if (i == filter->nb_inputs)
568         return;
569
570     for (i = 0; i < filter->nb_outputs; i++) {
571         AVFilterLink *outlink = filter->outputs[i];
572         int best_idx = -1, best_score = INT_MIN, best_count_diff = INT_MAX;
573
574         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
575             outlink->in_channel_layouts->nb_channel_layouts < 2)
576             continue;
577
578         for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts; j++) {
579             uint64_t  in_chlayout = link->out_channel_layouts->channel_layouts[0];
580             uint64_t out_chlayout = outlink->in_channel_layouts->channel_layouts[j];
581             int  in_channels      = av_get_channel_layout_nb_channels(in_chlayout);
582             int out_channels      = av_get_channel_layout_nb_channels(out_chlayout);
583             int count_diff        = out_channels - in_channels;
584             int matched_channels, extra_channels;
585             int score = 0;
586
587             /* channel substitution */
588             for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) {
589                 uint64_t cmp0 = ch_subst[k][0];
590                 uint64_t cmp1 = ch_subst[k][1];
591                 if (( in_chlayout & cmp0) && (!(out_chlayout & cmp0)) &&
592                     (out_chlayout & cmp1) && (!( in_chlayout & cmp1))) {
593                     in_chlayout  &= ~cmp0;
594                     out_chlayout &= ~cmp1;
595                     /* add score for channel match, minus a deduction for
596                        having to do the substitution */
597                     score += 10 * av_get_channel_layout_nb_channels(cmp1) - 2;
598                 }
599             }
600
601             /* no penalty for LFE channel mismatch */
602             if ( (in_chlayout & AV_CH_LOW_FREQUENCY) &&
603                 (out_chlayout & AV_CH_LOW_FREQUENCY))
604                 score += 10;
605             in_chlayout  &= ~AV_CH_LOW_FREQUENCY;
606             out_chlayout &= ~AV_CH_LOW_FREQUENCY;
607
608             matched_channels = av_get_channel_layout_nb_channels(in_chlayout &
609                                                                  out_chlayout);
610             extra_channels   = av_get_channel_layout_nb_channels(out_chlayout &
611                                                                  (~in_chlayout));
612             score += 10 * matched_channels - 5 * extra_channels;
613
614             if (score > best_score ||
615                 (count_diff < best_count_diff && score == best_score)) {
616                 best_score = score;
617                 best_idx   = j;
618                 best_count_diff = count_diff;
619             }
620         }
621         av_assert0(best_idx >= 0);
622         FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0],
623                outlink->in_channel_layouts->channel_layouts[best_idx]);
624     }
625
626 }
627
628 static void swap_channel_layouts(AVFilterGraph *graph)
629 {
630     int i;
631
632     for (i = 0; i < graph->nb_filters; i++)
633         swap_channel_layouts_on_filter(graph->filters[i]);
634 }
635
636 static void swap_sample_fmts_on_filter(AVFilterContext *filter)
637 {
638     AVFilterLink *link = NULL;
639     int format, bps;
640     int i, j;
641
642     for (i = 0; i < filter->nb_inputs; i++) {
643         link = filter->inputs[i];
644
645         if (link->type == AVMEDIA_TYPE_AUDIO &&
646             link->out_formats->nb_formats == 1)
647             break;
648     }
649     if (i == filter->nb_inputs)
650         return;
651
652     format = link->out_formats->formats[0];
653     bps    = av_get_bytes_per_sample(format);
654
655     for (i = 0; i < filter->nb_outputs; i++) {
656         AVFilterLink *outlink = filter->outputs[i];
657         int best_idx = -1, best_score = INT_MIN;
658
659         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
660             outlink->in_formats->nb_formats < 2)
661             continue;
662
663         for (j = 0; j < outlink->in_formats->nb_formats; j++) {
664             int out_format = outlink->in_formats->formats[j];
665             int out_bps    = av_get_bytes_per_sample(out_format);
666             int score;
667
668             if (av_get_packed_sample_fmt(out_format) == format ||
669                 av_get_planar_sample_fmt(out_format) == format) {
670                 best_idx   = j;
671                 break;
672             }
673
674             /* for s32 and float prefer double to prevent loss of information */
675             if (bps == 4 && out_bps == 8) {
676                 best_idx = j;
677                 break;
678             }
679
680             /* prefer closest higher or equal bps */
681             score = -abs(out_bps - bps);
682             if (out_bps >= bps)
683                 score += INT_MAX/2;
684
685             if (score > best_score) {
686                 best_score = score;
687                 best_idx   = j;
688             }
689         }
690         av_assert0(best_idx >= 0);
691         FFSWAP(int, outlink->in_formats->formats[0],
692                outlink->in_formats->formats[best_idx]);
693     }
694 }
695
696 static void swap_sample_fmts(AVFilterGraph *graph)
697 {
698     int i;
699
700     for (i = 0; i < graph->nb_filters; i++)
701         swap_sample_fmts_on_filter(graph->filters[i]);
702
703 }
704
705 static int pick_formats(AVFilterGraph *graph)
706 {
707     int i, j, ret;
708
709     for (i = 0; i < graph->nb_filters; i++) {
710         AVFilterContext *filter = graph->filters[i];
711
712         for (j = 0; j < filter->nb_inputs; j++)
713             if ((ret = pick_format(filter->inputs[j])) < 0)
714                 return ret;
715         for (j = 0; j < filter->nb_outputs; j++)
716             if ((ret = pick_format(filter->outputs[j])) < 0)
717                 return ret;
718     }
719     return 0;
720 }
721
722 /**
723  * Configure the formats of all the links in the graph.
724  */
725 static int graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
726 {
727     int ret;
728
729     /* find supported formats from sub-filters, and merge along links */
730     if ((ret = query_formats(graph, log_ctx)) < 0)
731         return ret;
732
733     /* Once everything is merged, it's possible that we'll still have
734      * multiple valid media format choices. We try to minimize the amount
735      * of format conversion inside filters */
736     reduce_formats(graph);
737
738     /* for audio filters, ensure the best format, sample rate and channel layout
739      * is selected */
740     swap_sample_fmts(graph);
741     swap_samplerates(graph);
742     swap_channel_layouts(graph);
743
744     if ((ret = pick_formats(graph)) < 0)
745         return ret;
746
747     return 0;
748 }
749
750 static int graph_insert_fifos(AVFilterGraph *graph, AVClass *log_ctx)
751 {
752     AVFilterContext *f;
753     int i, j, ret;
754     int fifo_count = 0;
755
756     for (i = 0; i < graph->nb_filters; i++) {
757         f = graph->filters[i];
758
759         for (j = 0; j < f->nb_inputs; j++) {
760             AVFilterLink *link = f->inputs[j];
761             AVFilterContext *fifo_ctx;
762             const AVFilter *fifo;
763             char name[32];
764
765             if (!link->dstpad->needs_fifo)
766                 continue;
767
768             fifo = f->inputs[j]->type == AVMEDIA_TYPE_VIDEO ?
769                    avfilter_get_by_name("fifo") :
770                    avfilter_get_by_name("afifo");
771
772             snprintf(name, sizeof(name), "auto-inserted fifo %d", fifo_count++);
773
774             ret = avfilter_graph_create_filter(&fifo_ctx, fifo, name, NULL,
775                                                NULL, graph);
776             if (ret < 0)
777                 return ret;
778
779             ret = avfilter_insert_filter(link, fifo_ctx, 0, 0);
780             if (ret < 0)
781                 return ret;
782         }
783     }
784
785     return 0;
786 }
787
788 int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
789 {
790     int ret;
791
792     if ((ret = graph_check_validity(graphctx, log_ctx)))
793         return ret;
794     if ((ret = graph_insert_fifos(graphctx, log_ctx)) < 0)
795         return ret;
796     if ((ret = graph_config_formats(graphctx, log_ctx)))
797         return ret;
798     if ((ret = graph_config_links(graphctx, log_ctx)))
799         return ret;
800
801     return 0;
802 }