Check size_bmp more fully
[platform/upstream/libav.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 #if FF_API_AVFILTER_OPEN
120 int avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)
121 {
122     AVFilterContext **filters = av_realloc(graph->filters,
123                                            sizeof(*filters) * (graph->nb_filters + 1));
124     if (!filters)
125         return AVERROR(ENOMEM);
126
127     graph->filters = filters;
128     graph->filters[graph->nb_filters++] = filter;
129
130     filter->graph = graph;
131
132     return 0;
133 }
134 #endif
135
136 int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt,
137                                  const char *name, const char *args, void *opaque,
138                                  AVFilterGraph *graph_ctx)
139 {
140     int ret;
141
142     *filt_ctx = avfilter_graph_alloc_filter(graph_ctx, filt, name);
143     if (!*filt_ctx)
144         return AVERROR(ENOMEM);
145
146     ret = avfilter_init_str(*filt_ctx, args);
147     if (ret < 0)
148         goto fail;
149
150     return 0;
151
152 fail:
153     if (*filt_ctx)
154         avfilter_free(*filt_ctx);
155     *filt_ctx = NULL;
156     return ret;
157 }
158
159 AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph,
160                                              const AVFilter *filter,
161                                              const char *name)
162 {
163     AVFilterContext **filters, *s;
164
165     if (graph->thread_type && !graph->internal->thread_execute) {
166         if (graph->execute) {
167             graph->internal->thread_execute = graph->execute;
168         } else {
169             int ret = ff_graph_thread_init(graph);
170             if (ret < 0) {
171                 av_log(graph, AV_LOG_ERROR, "Error initializing threading.\n");
172                 return NULL;
173             }
174         }
175     }
176
177     s = ff_filter_alloc(filter, name);
178     if (!s)
179         return NULL;
180
181     filters = av_realloc(graph->filters, sizeof(*filters) * (graph->nb_filters + 1));
182     if (!filters) {
183         avfilter_free(s);
184         return NULL;
185     }
186
187     graph->filters = filters;
188     graph->filters[graph->nb_filters++] = s;
189
190     s->graph = graph;
191
192     return s;
193 }
194
195 /**
196  * Check for the validity of graph.
197  *
198  * A graph is considered valid if all its input and output pads are
199  * connected.
200  *
201  * @return 0 in case of success, a negative value otherwise
202  */
203 static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
204 {
205     AVFilterContext *filt;
206     int i, j;
207
208     for (i = 0; i < graph->nb_filters; i++) {
209         filt = graph->filters[i];
210
211         for (j = 0; j < filt->nb_inputs; j++) {
212             if (!filt->inputs[j] || !filt->inputs[j]->src) {
213                 av_log(log_ctx, AV_LOG_ERROR,
214                        "Input pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any source\n",
215                        filt->input_pads[j].name, filt->name, filt->filter->name);
216                 return AVERROR(EINVAL);
217             }
218         }
219
220         for (j = 0; j < filt->nb_outputs; j++) {
221             if (!filt->outputs[j] || !filt->outputs[j]->dst) {
222                 av_log(log_ctx, AV_LOG_ERROR,
223                        "Output pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any destination\n",
224                        filt->output_pads[j].name, filt->name, filt->filter->name);
225                 return AVERROR(EINVAL);
226             }
227         }
228     }
229
230     return 0;
231 }
232
233 /**
234  * Configure all the links of graphctx.
235  *
236  * @return 0 in case of success, a negative value otherwise
237  */
238 static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
239 {
240     AVFilterContext *filt;
241     int i, ret;
242
243     for (i = 0; i < graph->nb_filters; i++) {
244         filt = graph->filters[i];
245
246         if (!filt->nb_outputs) {
247             if ((ret = avfilter_config_links(filt)))
248                 return ret;
249         }
250     }
251
252     return 0;
253 }
254
255 AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name)
256 {
257     int i;
258
259     for (i = 0; i < graph->nb_filters; i++)
260         if (graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
261             return graph->filters[i];
262
263     return NULL;
264 }
265
266 static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
267 {
268     int i, j, ret;
269     int scaler_count = 0, resampler_count = 0;
270
271     /* ask all the sub-filters for their supported media formats */
272     for (i = 0; i < graph->nb_filters; i++) {
273         if (graph->filters[i]->filter->query_formats)
274             ret = graph->filters[i]->filter->query_formats(graph->filters[i]);
275         else
276             ret = ff_default_query_formats(graph->filters[i]);
277         if (ret < 0) {
278             av_log(log_ctx, AV_LOG_ERROR,
279                    "Error querying formats for the filter %s (%s)\n",
280                    graph->filters[i]->name, graph->filters[i]->filter->name);
281             return ret;
282         }
283     }
284
285     /* go through and merge as many format lists as possible */
286     for (i = 0; i < graph->nb_filters; i++) {
287         AVFilterContext *filter = graph->filters[i];
288
289         for (j = 0; j < filter->nb_inputs; j++) {
290             AVFilterLink *link = filter->inputs[j];
291             int convert_needed = 0;
292
293             if (!link)
294                 continue;
295
296             if (link->in_formats != link->out_formats &&
297                 !ff_merge_formats(link->in_formats,
298                                         link->out_formats))
299                 convert_needed = 1;
300             if (link->type == AVMEDIA_TYPE_AUDIO) {
301                 if (link->in_channel_layouts != link->out_channel_layouts &&
302                     !ff_merge_channel_layouts(link->in_channel_layouts,
303                                               link->out_channel_layouts))
304                     convert_needed = 1;
305                 if (link->in_samplerates != link->out_samplerates &&
306                     !ff_merge_samplerates(link->in_samplerates,
307                                           link->out_samplerates))
308                     convert_needed = 1;
309             }
310
311             if (convert_needed) {
312                 AVFilterContext *convert;
313                 AVFilter *filter;
314                 AVFilterLink *inlink, *outlink;
315                 char scale_args[256];
316                 char inst_name[30];
317
318                 /* couldn't merge format lists. auto-insert conversion filter */
319                 switch (link->type) {
320                 case AVMEDIA_TYPE_VIDEO:
321                     if (!(filter = avfilter_get_by_name("scale"))) {
322                         av_log(log_ctx, AV_LOG_ERROR, "'scale' filter "
323                                "not present, cannot convert pixel formats.\n");
324                         return AVERROR(EINVAL);
325                     }
326
327                     snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
328                              scaler_count++);
329
330                     if ((ret = avfilter_graph_create_filter(&convert, filter,
331                                                             inst_name, graph->scale_sws_opts, NULL,
332                                                             graph)) < 0)
333                         return ret;
334                     break;
335                 case AVMEDIA_TYPE_AUDIO:
336                     if (!(filter = avfilter_get_by_name("resample"))) {
337                         av_log(log_ctx, AV_LOG_ERROR, "'resample' filter "
338                                "not present, cannot convert audio formats.\n");
339                         return AVERROR(EINVAL);
340                     }
341
342                     snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d",
343                              resampler_count++);
344                     scale_args[0] = '\0';
345                     if (graph->resample_lavr_opts)
346                         snprintf(scale_args, sizeof(scale_args), "%s",
347                                  graph->resample_lavr_opts);
348                     if ((ret = avfilter_graph_create_filter(&convert, filter,
349                                                             inst_name, scale_args,
350                                                             NULL, graph)) < 0)
351                         return ret;
352                     break;
353                 default:
354                     return AVERROR(EINVAL);
355                 }
356
357                 if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
358                     return ret;
359
360                 convert->filter->query_formats(convert);
361                 inlink  = convert->inputs[0];
362                 outlink = convert->outputs[0];
363                 if (!ff_merge_formats( inlink->in_formats,  inlink->out_formats) ||
364                     !ff_merge_formats(outlink->in_formats, outlink->out_formats))
365                     ret |= AVERROR(ENOSYS);
366                 if (inlink->type == AVMEDIA_TYPE_AUDIO &&
367                     (!ff_merge_samplerates(inlink->in_samplerates,
368                                            inlink->out_samplerates) ||
369                      !ff_merge_channel_layouts(inlink->in_channel_layouts,
370                                                inlink->out_channel_layouts)))
371                     ret |= AVERROR(ENOSYS);
372                 if (outlink->type == AVMEDIA_TYPE_AUDIO &&
373                     (!ff_merge_samplerates(outlink->in_samplerates,
374                                            outlink->out_samplerates) ||
375                      !ff_merge_channel_layouts(outlink->in_channel_layouts,
376                                                outlink->out_channel_layouts)))
377                     ret |= AVERROR(ENOSYS);
378
379                 if (ret < 0) {
380                     av_log(log_ctx, AV_LOG_ERROR,
381                            "Impossible to convert between the formats supported by the filter "
382                            "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
383                     return ret;
384                 }
385             }
386         }
387     }
388
389     return 0;
390 }
391
392 static int pick_format(AVFilterLink *link)
393 {
394     if (!link || !link->in_formats)
395         return 0;
396
397     link->in_formats->nb_formats = 1;
398     link->format = link->in_formats->formats[0];
399
400     if (link->type == AVMEDIA_TYPE_AUDIO) {
401         if (!link->in_samplerates->nb_formats) {
402             av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
403                    " the link between filters %s and %s.\n", link->src->name,
404                    link->dst->name);
405             return AVERROR(EINVAL);
406         }
407         link->in_samplerates->nb_formats = 1;
408         link->sample_rate = link->in_samplerates->formats[0];
409
410         if (!link->in_channel_layouts->nb_channel_layouts) {
411             av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
412                    "the link between filters %s and %s.\n", link->src->name,
413                    link->dst->name);
414             return AVERROR(EINVAL);
415         }
416         link->in_channel_layouts->nb_channel_layouts = 1;
417         link->channel_layout = link->in_channel_layouts->channel_layouts[0];
418     }
419
420     ff_formats_unref(&link->in_formats);
421     ff_formats_unref(&link->out_formats);
422     ff_formats_unref(&link->in_samplerates);
423     ff_formats_unref(&link->out_samplerates);
424     ff_channel_layouts_unref(&link->in_channel_layouts);
425     ff_channel_layouts_unref(&link->out_channel_layouts);
426
427     return 0;
428 }
429
430 #define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format) \
431 do {                                                                   \
432     for (i = 0; i < filter->nb_inputs; i++) {                          \
433         AVFilterLink *link = filter->inputs[i];                        \
434         fmt_type fmt;                                                  \
435                                                                        \
436         if (!link->out_ ## list || link->out_ ## list->nb != 1)        \
437             continue;                                                  \
438         fmt = link->out_ ## list->var[0];                              \
439                                                                        \
440         for (j = 0; j < filter->nb_outputs; j++) {                     \
441             AVFilterLink *out_link = filter->outputs[j];               \
442             list_type *fmts;                                           \
443                                                                        \
444             if (link->type != out_link->type ||                        \
445                 out_link->in_ ## list->nb == 1)                        \
446                 continue;                                              \
447             fmts = out_link->in_ ## list;                              \
448                                                                        \
449             if (!out_link->in_ ## list->nb) {                          \
450                 add_format(&out_link->in_ ##list, fmt);                \
451                 break;                                                 \
452             }                                                          \
453                                                                        \
454             for (k = 0; k < out_link->in_ ## list->nb; k++)            \
455                 if (fmts->var[k] == fmt) {                             \
456                     fmts->var[0]  = fmt;                               \
457                     fmts->nb = 1;                                      \
458                     ret = 1;                                           \
459                     break;                                             \
460                 }                                                      \
461         }                                                              \
462     }                                                                  \
463 } while (0)
464
465 static int reduce_formats_on_filter(AVFilterContext *filter)
466 {
467     int i, j, k, ret = 0;
468
469     REDUCE_FORMATS(int,      AVFilterFormats,        formats,         formats,
470                    nb_formats, ff_add_format);
471     REDUCE_FORMATS(int,      AVFilterFormats,        samplerates,     formats,
472                    nb_formats, ff_add_format);
473     REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts,
474                    channel_layouts, nb_channel_layouts, ff_add_channel_layout);
475
476     return ret;
477 }
478
479 static void reduce_formats(AVFilterGraph *graph)
480 {
481     int i, reduced;
482
483     do {
484         reduced = 0;
485
486         for (i = 0; i < graph->nb_filters; i++)
487             reduced |= reduce_formats_on_filter(graph->filters[i]);
488     } while (reduced);
489 }
490
491 static void swap_samplerates_on_filter(AVFilterContext *filter)
492 {
493     AVFilterLink *link = NULL;
494     int sample_rate;
495     int i, j;
496
497     for (i = 0; i < filter->nb_inputs; i++) {
498         link = filter->inputs[i];
499
500         if (link->type == AVMEDIA_TYPE_AUDIO &&
501             link->out_samplerates->nb_formats== 1)
502             break;
503     }
504     if (i == filter->nb_inputs)
505         return;
506
507     sample_rate = link->out_samplerates->formats[0];
508
509     for (i = 0; i < filter->nb_outputs; i++) {
510         AVFilterLink *outlink = filter->outputs[i];
511         int best_idx, best_diff = INT_MAX;
512
513         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
514             outlink->in_samplerates->nb_formats < 2)
515             continue;
516
517         for (j = 0; j < outlink->in_samplerates->nb_formats; j++) {
518             int diff = abs(sample_rate - outlink->in_samplerates->formats[j]);
519
520             if (diff < best_diff) {
521                 best_diff = diff;
522                 best_idx  = j;
523             }
524         }
525         FFSWAP(int, outlink->in_samplerates->formats[0],
526                outlink->in_samplerates->formats[best_idx]);
527     }
528 }
529
530 static void swap_samplerates(AVFilterGraph *graph)
531 {
532     int i;
533
534     for (i = 0; i < graph->nb_filters; i++)
535         swap_samplerates_on_filter(graph->filters[i]);
536 }
537
538 #define CH_CENTER_PAIR (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)
539 #define CH_FRONT_PAIR  (AV_CH_FRONT_LEFT           | AV_CH_FRONT_RIGHT)
540 #define CH_STEREO_PAIR (AV_CH_STEREO_LEFT          | AV_CH_STEREO_RIGHT)
541 #define CH_WIDE_PAIR   (AV_CH_WIDE_LEFT            | AV_CH_WIDE_RIGHT)
542 #define CH_SIDE_PAIR   (AV_CH_SIDE_LEFT            | AV_CH_SIDE_RIGHT)
543 #define CH_DIRECT_PAIR (AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT)
544 #define CH_BACK_PAIR   (AV_CH_BACK_LEFT            | AV_CH_BACK_RIGHT)
545
546 /* allowable substitutions for channel pairs when comparing layouts,
547  * ordered by priority for both values */
548 static const uint64_t ch_subst[][2] = {
549     { CH_FRONT_PAIR,      CH_CENTER_PAIR     },
550     { CH_FRONT_PAIR,      CH_WIDE_PAIR       },
551     { CH_FRONT_PAIR,      AV_CH_FRONT_CENTER },
552     { CH_CENTER_PAIR,     CH_FRONT_PAIR      },
553     { CH_CENTER_PAIR,     CH_WIDE_PAIR       },
554     { CH_CENTER_PAIR,     AV_CH_FRONT_CENTER },
555     { CH_WIDE_PAIR,       CH_FRONT_PAIR      },
556     { CH_WIDE_PAIR,       CH_CENTER_PAIR     },
557     { CH_WIDE_PAIR,       AV_CH_FRONT_CENTER },
558     { AV_CH_FRONT_CENTER, CH_FRONT_PAIR      },
559     { AV_CH_FRONT_CENTER, CH_CENTER_PAIR     },
560     { AV_CH_FRONT_CENTER, CH_WIDE_PAIR       },
561     { CH_SIDE_PAIR,       CH_DIRECT_PAIR     },
562     { CH_SIDE_PAIR,       CH_BACK_PAIR       },
563     { CH_SIDE_PAIR,       AV_CH_BACK_CENTER  },
564     { CH_BACK_PAIR,       CH_DIRECT_PAIR     },
565     { CH_BACK_PAIR,       CH_SIDE_PAIR       },
566     { CH_BACK_PAIR,       AV_CH_BACK_CENTER  },
567     { AV_CH_BACK_CENTER,  CH_BACK_PAIR       },
568     { AV_CH_BACK_CENTER,  CH_DIRECT_PAIR     },
569     { AV_CH_BACK_CENTER,  CH_SIDE_PAIR       },
570 };
571
572 static void swap_channel_layouts_on_filter(AVFilterContext *filter)
573 {
574     AVFilterLink *link = NULL;
575     int i, j, k;
576
577     for (i = 0; i < filter->nb_inputs; i++) {
578         link = filter->inputs[i];
579
580         if (link->type == AVMEDIA_TYPE_AUDIO &&
581             link->out_channel_layouts->nb_channel_layouts == 1)
582             break;
583     }
584     if (i == filter->nb_inputs)
585         return;
586
587     for (i = 0; i < filter->nb_outputs; i++) {
588         AVFilterLink *outlink = filter->outputs[i];
589         int best_idx = -1, best_score = INT_MIN, best_count_diff = INT_MAX;
590
591         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
592             outlink->in_channel_layouts->nb_channel_layouts < 2)
593             continue;
594
595         for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts; j++) {
596             uint64_t  in_chlayout = link->out_channel_layouts->channel_layouts[0];
597             uint64_t out_chlayout = outlink->in_channel_layouts->channel_layouts[j];
598             int  in_channels      = av_get_channel_layout_nb_channels(in_chlayout);
599             int out_channels      = av_get_channel_layout_nb_channels(out_chlayout);
600             int count_diff        = out_channels - in_channels;
601             int matched_channels, extra_channels;
602             int score = 0;
603
604             /* channel substitution */
605             for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) {
606                 uint64_t cmp0 = ch_subst[k][0];
607                 uint64_t cmp1 = ch_subst[k][1];
608                 if (( in_chlayout & cmp0) && (!(out_chlayout & cmp0)) &&
609                     (out_chlayout & cmp1) && (!( in_chlayout & cmp1))) {
610                     in_chlayout  &= ~cmp0;
611                     out_chlayout &= ~cmp1;
612                     /* add score for channel match, minus a deduction for
613                        having to do the substitution */
614                     score += 10 * av_get_channel_layout_nb_channels(cmp1) - 2;
615                 }
616             }
617
618             /* no penalty for LFE channel mismatch */
619             if ( (in_chlayout & AV_CH_LOW_FREQUENCY) &&
620                 (out_chlayout & AV_CH_LOW_FREQUENCY))
621                 score += 10;
622             in_chlayout  &= ~AV_CH_LOW_FREQUENCY;
623             out_chlayout &= ~AV_CH_LOW_FREQUENCY;
624
625             matched_channels = av_get_channel_layout_nb_channels(in_chlayout &
626                                                                  out_chlayout);
627             extra_channels   = av_get_channel_layout_nb_channels(out_chlayout &
628                                                                  (~in_chlayout));
629             score += 10 * matched_channels - 5 * extra_channels;
630
631             if (score > best_score ||
632                 (count_diff < best_count_diff && score == best_score)) {
633                 best_score = score;
634                 best_idx   = j;
635                 best_count_diff = count_diff;
636             }
637         }
638         av_assert0(best_idx >= 0);
639         FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0],
640                outlink->in_channel_layouts->channel_layouts[best_idx]);
641     }
642
643 }
644
645 static void swap_channel_layouts(AVFilterGraph *graph)
646 {
647     int i;
648
649     for (i = 0; i < graph->nb_filters; i++)
650         swap_channel_layouts_on_filter(graph->filters[i]);
651 }
652
653 static void swap_sample_fmts_on_filter(AVFilterContext *filter)
654 {
655     AVFilterLink *link = NULL;
656     int format, bps;
657     int i, j;
658
659     for (i = 0; i < filter->nb_inputs; i++) {
660         link = filter->inputs[i];
661
662         if (link->type == AVMEDIA_TYPE_AUDIO &&
663             link->out_formats->nb_formats == 1)
664             break;
665     }
666     if (i == filter->nb_inputs)
667         return;
668
669     format = link->out_formats->formats[0];
670     bps    = av_get_bytes_per_sample(format);
671
672     for (i = 0; i < filter->nb_outputs; i++) {
673         AVFilterLink *outlink = filter->outputs[i];
674         int best_idx = -1, best_score = INT_MIN;
675
676         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
677             outlink->in_formats->nb_formats < 2)
678             continue;
679
680         for (j = 0; j < outlink->in_formats->nb_formats; j++) {
681             int out_format = outlink->in_formats->formats[j];
682             int out_bps    = av_get_bytes_per_sample(out_format);
683             int score;
684
685             if (av_get_packed_sample_fmt(out_format) == format ||
686                 av_get_planar_sample_fmt(out_format) == format) {
687                 best_idx   = j;
688                 break;
689             }
690
691             /* for s32 and float prefer double to prevent loss of information */
692             if (bps == 4 && out_bps == 8) {
693                 best_idx = j;
694                 break;
695             }
696
697             /* prefer closest higher or equal bps */
698             score = -abs(out_bps - bps);
699             if (out_bps >= bps)
700                 score += INT_MAX/2;
701
702             if (score > best_score) {
703                 best_score = score;
704                 best_idx   = j;
705             }
706         }
707         av_assert0(best_idx >= 0);
708         FFSWAP(int, outlink->in_formats->formats[0],
709                outlink->in_formats->formats[best_idx]);
710     }
711 }
712
713 static void swap_sample_fmts(AVFilterGraph *graph)
714 {
715     int i;
716
717     for (i = 0; i < graph->nb_filters; i++)
718         swap_sample_fmts_on_filter(graph->filters[i]);
719
720 }
721
722 static int pick_formats(AVFilterGraph *graph)
723 {
724     int i, j, ret;
725
726     for (i = 0; i < graph->nb_filters; i++) {
727         AVFilterContext *filter = graph->filters[i];
728
729         for (j = 0; j < filter->nb_inputs; j++)
730             if ((ret = pick_format(filter->inputs[j])) < 0)
731                 return ret;
732         for (j = 0; j < filter->nb_outputs; j++)
733             if ((ret = pick_format(filter->outputs[j])) < 0)
734                 return ret;
735     }
736     return 0;
737 }
738
739 /**
740  * Configure the formats of all the links in the graph.
741  */
742 static int graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
743 {
744     int ret;
745
746     /* find supported formats from sub-filters, and merge along links */
747     if ((ret = query_formats(graph, log_ctx)) < 0)
748         return ret;
749
750     /* Once everything is merged, it's possible that we'll still have
751      * multiple valid media format choices. We try to minimize the amount
752      * of format conversion inside filters */
753     reduce_formats(graph);
754
755     /* for audio filters, ensure the best format, sample rate and channel layout
756      * is selected */
757     swap_sample_fmts(graph);
758     swap_samplerates(graph);
759     swap_channel_layouts(graph);
760
761     if ((ret = pick_formats(graph)) < 0)
762         return ret;
763
764     return 0;
765 }
766
767 static int graph_insert_fifos(AVFilterGraph *graph, AVClass *log_ctx)
768 {
769     AVFilterContext *f;
770     int i, j, ret;
771     int fifo_count = 0;
772
773     for (i = 0; i < graph->nb_filters; i++) {
774         f = graph->filters[i];
775
776         for (j = 0; j < f->nb_inputs; j++) {
777             AVFilterLink *link = f->inputs[j];
778             AVFilterContext *fifo_ctx;
779             AVFilter *fifo;
780             char name[32];
781
782             if (!link->dstpad->needs_fifo)
783                 continue;
784
785             fifo = f->inputs[j]->type == AVMEDIA_TYPE_VIDEO ?
786                    avfilter_get_by_name("fifo") :
787                    avfilter_get_by_name("afifo");
788
789             snprintf(name, sizeof(name), "auto-inserted fifo %d", fifo_count++);
790
791             ret = avfilter_graph_create_filter(&fifo_ctx, fifo, name, NULL,
792                                                NULL, graph);
793             if (ret < 0)
794                 return ret;
795
796             ret = avfilter_insert_filter(link, fifo_ctx, 0, 0);
797             if (ret < 0)
798                 return ret;
799         }
800     }
801
802     return 0;
803 }
804
805 int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
806 {
807     int ret;
808
809     if ((ret = graph_check_validity(graphctx, log_ctx)))
810         return ret;
811     if ((ret = graph_insert_fifos(graphctx, log_ctx)) < 0)
812         return ret;
813     if ((ret = graph_config_formats(graphctx, log_ctx)))
814         return ret;
815     if ((ret = graph_config_links(graphctx, log_ctx)))
816         return ret;
817
818     return 0;
819 }