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