LCOV - code coverage report
Current view: top level - src/libavfilter - avfiltergraph.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 552 743 74.3 %
Date: 2017-01-23 11:54:22 Functions: 35 39 89.7 %

          Line data    Source code
       1             : /*
       2             :  * filter graphs
       3             :  * Copyright (c) 2008 Vitor Sessak
       4             :  * Copyright (c) 2007 Bobby Bingham
       5             :  *
       6             :  * This file is part of FFmpeg.
       7             :  *
       8             :  * FFmpeg 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             :  * FFmpeg 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 FFmpeg; 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/bprint.h"
      30             : #include "libavutil/channel_layout.h"
      31             : #include "libavutil/internal.h"
      32             : #include "libavutil/opt.h"
      33             : #include "libavutil/pixdesc.h"
      34             : 
      35             : #define FF_INTERNAL_FIELDS 1
      36             : #include "framequeue.h"
      37             : 
      38             : #include "avfilter.h"
      39             : #include "buffersink.h"
      40             : #include "formats.h"
      41             : #include "internal.h"
      42             : #include "thread.h"
      43             : 
      44             : #define OFFSET(x) offsetof(AVFilterGraph, x)
      45             : #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
      46             : static const AVOption filtergraph_options[] = {
      47             :     { "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,
      48             :         { .i64 = AVFILTER_THREAD_SLICE }, 0, INT_MAX, FLAGS, "thread_type" },
      49             :         { "slice", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVFILTER_THREAD_SLICE }, .flags = FLAGS, .unit = "thread_type" },
      50             :     { "threads",     "Maximum number of threads", OFFSET(nb_threads),
      51             :         AV_OPT_TYPE_INT,   { .i64 = 0 }, 0, INT_MAX, FLAGS },
      52             :     {"scale_sws_opts"       , "default scale filter options"        , OFFSET(scale_sws_opts)        ,
      53             :         AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
      54             :     {"aresample_swr_opts"   , "default aresample filter options"    , OFFSET(aresample_swr_opts)    ,
      55             :         AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
      56             :     { NULL },
      57             : };
      58             : 
      59             : static const AVClass filtergraph_class = {
      60             :     .class_name = "AVFilterGraph",
      61             :     .item_name  = av_default_item_name,
      62             :     .version    = LIBAVUTIL_VERSION_INT,
      63             :     .option     = filtergraph_options,
      64             :     .category   = AV_CLASS_CATEGORY_FILTER,
      65             : };
      66             : 
      67             : #if !HAVE_THREADS
      68             : void ff_graph_thread_free(AVFilterGraph *graph)
      69             : {
      70             : }
      71             : 
      72             : int ff_graph_thread_init(AVFilterGraph *graph)
      73             : {
      74             :     graph->thread_type = 0;
      75             :     graph->nb_threads  = 1;
      76             :     return 0;
      77             : }
      78             : #endif
      79             : 
      80        5166 : AVFilterGraph *avfilter_graph_alloc(void)
      81             : {
      82        5166 :     AVFilterGraph *ret = av_mallocz(sizeof(*ret));
      83        5166 :     if (!ret)
      84           0 :         return NULL;
      85             : 
      86        5166 :     ret->internal = av_mallocz(sizeof(*ret->internal));
      87        5166 :     if (!ret->internal) {
      88           0 :         av_freep(&ret);
      89           0 :         return NULL;
      90             :     }
      91             : 
      92        5166 :     ret->av_class = &filtergraph_class;
      93        5166 :     av_opt_set_defaults(ret);
      94        5166 :     ff_framequeue_global_init(&ret->internal->frame_queues);
      95             : 
      96        5166 :     return ret;
      97             : }
      98             : 
      99       25443 : void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter)
     100             : {
     101             :     int i, j;
     102       25443 :     for (i = 0; i < graph->nb_filters; i++) {
     103       25443 :         if (graph->filters[i] == filter) {
     104       25443 :             FFSWAP(AVFilterContext*, graph->filters[i],
     105             :                    graph->filters[graph->nb_filters - 1]);
     106       25443 :             graph->nb_filters--;
     107       25443 :             filter->graph = NULL;
     108       45839 :             for (j = 0; j<filter->nb_outputs; j++)
     109       20396 :                 if (filter->outputs[j])
     110       10205 :                     filter->outputs[j]->graph = NULL;
     111             : 
     112       25443 :             return;
     113             :         }
     114             :     }
     115             : }
     116             : 
     117       10163 : void avfilter_graph_free(AVFilterGraph **graph)
     118             : {
     119       10163 :     if (!*graph)
     120        4997 :         return;
     121             : 
     122       35718 :     while ((*graph)->nb_filters)
     123       25386 :         avfilter_free((*graph)->filters[0]);
     124             : 
     125        5166 :     ff_graph_thread_free(*graph);
     126             : 
     127        5166 :     av_freep(&(*graph)->sink_links);
     128             : 
     129        5166 :     av_freep(&(*graph)->scale_sws_opts);
     130        5166 :     av_freep(&(*graph)->aresample_swr_opts);
     131        5166 :     av_freep(&(*graph)->resample_lavr_opts);
     132        5166 :     av_freep(&(*graph)->filters);
     133        5166 :     av_freep(&(*graph)->internal);
     134        5166 :     av_freep(graph);
     135             : }
     136             : 
     137             : #if FF_API_AVFILTER_OPEN
     138           0 : int avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)
     139             : {
     140           0 :     AVFilterContext **filters = av_realloc(graph->filters,
     141           0 :                                            sizeof(*filters) * (graph->nb_filters + 1));
     142           0 :     if (!filters)
     143           0 :         return AVERROR(ENOMEM);
     144             : 
     145           0 :     graph->filters = filters;
     146           0 :     graph->filters[graph->nb_filters++] = filter;
     147             : 
     148           0 :     filter->graph = graph;
     149             : 
     150           0 :     return 0;
     151             : }
     152             : #endif
     153             : 
     154       17371 : int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt,
     155             :                                  const char *name, const char *args, void *opaque,
     156             :                                  AVFilterGraph *graph_ctx)
     157             : {
     158             :     int ret;
     159             : 
     160       17371 :     *filt_ctx = avfilter_graph_alloc_filter(graph_ctx, filt, name);
     161       17371 :     if (!*filt_ctx)
     162           0 :         return AVERROR(ENOMEM);
     163             : 
     164       17371 :     ret = avfilter_init_str(*filt_ctx, args);
     165       17371 :     if (ret < 0)
     166           0 :         goto fail;
     167             : 
     168       17371 :     return 0;
     169             : 
     170             : fail:
     171           0 :     if (*filt_ctx)
     172           0 :         avfilter_free(*filt_ctx);
     173           0 :     *filt_ctx = NULL;
     174           0 :     return ret;
     175             : }
     176             : 
     177          14 : void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
     178             : {
     179          14 :     graph->disable_auto_convert = flags;
     180          14 : }
     181             : 
     182       25443 : AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph,
     183             :                                              const AVFilter *filter,
     184             :                                              const char *name)
     185             : {
     186             :     AVFilterContext **filters, *s;
     187             : 
     188       25443 :     if (graph->thread_type && !graph->internal->thread_execute) {
     189        5166 :         if (graph->execute) {
     190           0 :             graph->internal->thread_execute = graph->execute;
     191             :         } else {
     192        5166 :             int ret = ff_graph_thread_init(graph);
     193        5166 :             if (ret < 0) {
     194           0 :                 av_log(graph, AV_LOG_ERROR, "Error initializing threading.\n");
     195           0 :                 return NULL;
     196             :             }
     197             :         }
     198             :     }
     199             : 
     200       25443 :     s = ff_filter_alloc(filter, name);
     201       25443 :     if (!s)
     202           0 :         return NULL;
     203             : 
     204       25443 :     filters = av_realloc(graph->filters, sizeof(*filters) * (graph->nb_filters + 1));
     205       25443 :     if (!filters) {
     206           0 :         avfilter_free(s);
     207           0 :         return NULL;
     208             :     }
     209             : 
     210       25443 :     graph->filters = filters;
     211       25443 :     graph->filters[graph->nb_filters++] = s;
     212             : 
     213       25443 :     s->graph = graph;
     214             : 
     215       25443 :     return s;
     216             : }
     217             : 
     218             : /**
     219             :  * Check for the validity of graph.
     220             :  *
     221             :  * A graph is considered valid if all its input and output pads are
     222             :  * connected.
     223             :  *
     224             :  * @return >= 0 in case of success, a negative value otherwise
     225             :  */
     226        5067 : static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
     227             : {
     228             :     AVFilterContext *filt;
     229             :     int i, j;
     230             : 
     231       27734 :     for (i = 0; i < graph->nb_filters; i++) {
     232             :         const AVFilterPad *pad;
     233       22667 :         filt = graph->filters[i];
     234             : 
     235       40275 :         for (j = 0; j < filt->nb_inputs; j++) {
     236       17608 :             if (!filt->inputs[j] || !filt->inputs[j]->src) {
     237           0 :                 pad = &filt->input_pads[j];
     238           0 :                 av_log(log_ctx, AV_LOG_ERROR,
     239             :                        "Input pad \"%s\" with type %s of the filter instance \"%s\" of %s not connected to any source\n",
     240           0 :                        pad->name, av_get_media_type_string(pad->type), filt->name, filt->filter->name);
     241           0 :                 return AVERROR(EINVAL);
     242             :             }
     243             :         }
     244             : 
     245       40275 :         for (j = 0; j < filt->nb_outputs; j++) {
     246       17608 :             if (!filt->outputs[j] || !filt->outputs[j]->dst) {
     247           0 :                 pad = &filt->output_pads[j];
     248           0 :                 av_log(log_ctx, AV_LOG_ERROR,
     249             :                        "Output pad \"%s\" with type %s of the filter instance \"%s\" of %s not connected to any destination\n",
     250           0 :                        pad->name, av_get_media_type_string(pad->type), filt->name, filt->filter->name);
     251           0 :                 return AVERROR(EINVAL);
     252             :             }
     253             :         }
     254             :     }
     255             : 
     256        5067 :     return 0;
     257             : }
     258             : 
     259             : /**
     260             :  * Configure all the links of graphctx.
     261             :  *
     262             :  * @return >= 0 in case of success, a negative value otherwise
     263             :  */
     264        5067 : static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
     265             : {
     266             :     AVFilterContext *filt;
     267             :     int i, ret;
     268             : 
     269       30366 :     for (i = 0; i < graph->nb_filters; i++) {
     270       25299 :         filt = graph->filters[i];
     271             : 
     272       25299 :         if (!filt->nb_outputs) {
     273        5071 :             if ((ret = avfilter_config_links(filt)))
     274           0 :                 return ret;
     275             :         }
     276             :     }
     277             : 
     278        5067 :     return 0;
     279             : }
     280             : 
     281           0 : AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, const char *name)
     282             : {
     283             :     int i;
     284             : 
     285           0 :     for (i = 0; i < graph->nb_filters; i++)
     286           0 :         if (graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
     287           0 :             return graph->filters[i];
     288             : 
     289           0 :     return NULL;
     290             : }
     291             : 
     292       32220 : static void sanitize_channel_layouts(void *log, AVFilterChannelLayouts *l)
     293             : {
     294       32220 :     if (!l)
     295       25386 :         return;
     296        6834 :     if (l->nb_channel_layouts) {
     297        1199 :         if (l->all_layouts || l->all_counts)
     298           0 :             av_log(log, AV_LOG_WARNING, "All layouts set on non-empty list\n");
     299        1199 :         l->all_layouts = l->all_counts = 0;
     300             :     } else {
     301        5635 :         if (l->all_counts && !l->all_layouts)
     302           0 :             av_log(log, AV_LOG_WARNING, "All counts without all layouts\n");
     303        5635 :         l->all_layouts = 1;
     304             :     }
     305             : }
     306             : 
     307       21188 : static int filter_query_formats(AVFilterContext *ctx)
     308             : {
     309             :     int ret, i;
     310             :     AVFilterFormats *formats;
     311             :     AVFilterChannelLayouts *chlayouts;
     312             :     AVFilterFormats *samplerates;
     313       26284 :     enum AVMediaType type = ctx->inputs  && ctx->inputs [0] ? ctx->inputs [0]->type :
     314        5096 :                             ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
     315             :                             AVMEDIA_TYPE_VIDEO;
     316             : 
     317       21188 :     if ((ret = ctx->filter->query_formats(ctx)) < 0) {
     318          14 :         if (ret != AVERROR(EAGAIN))
     319           0 :             av_log(ctx, AV_LOG_ERROR, "Query format failed for '%s': %s\n",
     320           0 :                    ctx->name, av_err2str(ret));
     321          14 :         return ret;
     322             :     }
     323             : 
     324       37289 :     for (i = 0; i < ctx->nb_inputs; i++)
     325       16115 :         sanitize_channel_layouts(ctx, ctx->inputs[i]->out_channel_layouts);
     326       37279 :     for (i = 0; i < ctx->nb_outputs; i++)
     327       16105 :         sanitize_channel_layouts(ctx, ctx->outputs[i]->in_channel_layouts);
     328             : 
     329       21174 :     formats = ff_all_formats(type);
     330       21174 :     if ((ret = ff_set_common_formats(ctx, formats)) < 0)
     331           0 :         return ret;
     332       21174 :     if (type == AVMEDIA_TYPE_AUDIO) {
     333        4433 :         samplerates = ff_all_samplerates();
     334        4433 :         if ((ret = ff_set_common_samplerates(ctx, samplerates)) < 0)
     335           0 :             return ret;
     336        4433 :         chlayouts = ff_all_channel_layouts();
     337        4433 :         if ((ret = ff_set_common_channel_layouts(ctx, chlayouts)) < 0)
     338           0 :             return ret;
     339             :     }
     340       21174 :     return 0;
     341             : }
     342             : 
     343       22737 : static int formats_declared(AVFilterContext *f)
     344             : {
     345             :     int i;
     346             : 
     347       22772 :     for (i = 0; i < f->nb_inputs; i++) {
     348       17630 :         if (!f->inputs[i]->out_formats)
     349       17595 :             return 0;
     350          37 :         if (f->inputs[i]->type == AVMEDIA_TYPE_AUDIO &&
     351           4 :             !(f->inputs[i]->out_samplerates &&
     352           2 :               f->inputs[i]->out_channel_layouts))
     353           0 :             return 0;
     354             :     }
     355        5176 :     for (i = 0; i < f->nb_outputs; i++) {
     356        5132 :         if (!f->outputs[i]->in_formats)
     357        5098 :             return 0;
     358          37 :         if (f->outputs[i]->type == AVMEDIA_TYPE_AUDIO &&
     359           6 :             !(f->outputs[i]->in_samplerates &&
     360           3 :               f->outputs[i]->in_channel_layouts))
     361           0 :             return 0;
     362             :     }
     363          44 :     return 1;
     364             : }
     365             : 
     366       43132 : static AVFilterFormats *clone_filter_formats(AVFilterFormats *arg)
     367             : {
     368       43132 :     AVFilterFormats *a = av_memdup(arg, sizeof(*arg));
     369       43132 :     if (a) {
     370       43132 :         a->refcount = 0;
     371       43132 :         a->refs     = NULL;
     372       43132 :         a->formats  = av_memdup(a->formats, sizeof(*a->formats) * a->nb_formats);
     373       43132 :         if (!a->formats && arg->formats)
     374           0 :             av_freep(&a);
     375             :     }
     376       43132 :     return a;
     377             : }
     378             : 
     379       21566 : static int can_merge_formats(AVFilterFormats *a_arg,
     380             :                              AVFilterFormats *b_arg,
     381             :                              enum AVMediaType type,
     382             :                              int is_sample_rate)
     383             : {
     384             :     AVFilterFormats *a, *b, *ret;
     385       21566 :     if (a_arg == b_arg)
     386           0 :         return 1;
     387       21566 :     a = clone_filter_formats(a_arg);
     388       21566 :     b = clone_filter_formats(b_arg);
     389             : 
     390       21566 :     if (!a || !b) {
     391           0 :         if (a)
     392           0 :             av_freep(&a->formats);
     393           0 :         if (b)
     394           0 :             av_freep(&b->formats);
     395             : 
     396           0 :         av_freep(&a);
     397           0 :         av_freep(&b);
     398             : 
     399           0 :         return 0;
     400             :     }
     401             : 
     402       21566 :     if (is_sample_rate) {
     403        3946 :         ret = ff_merge_samplerates(a, b);
     404             :     } else {
     405       17620 :         ret = ff_merge_formats(a, b, type);
     406             :     }
     407       21566 :     if (ret) {
     408       18941 :         av_freep(&ret->formats);
     409       18941 :         av_freep(&ret->refs);
     410       18941 :         av_freep(&ret);
     411       18941 :         return 1;
     412             :     } else {
     413        2625 :         av_freep(&a->formats);
     414        2625 :         av_freep(&b->formats);
     415        2625 :         av_freep(&a);
     416        2625 :         av_freep(&b);
     417        2625 :         return 0;
     418             :     }
     419             : }
     420             : 
     421             : /**
     422             :  * Perform one round of query_formats() and merging formats lists on the
     423             :  * filter graph.
     424             :  * @return  >=0 if all links formats lists could be queried and merged;
     425             :  *          AVERROR(EAGAIN) some progress was made in the queries or merging
     426             :  *          and a later call may succeed;
     427             :  *          AVERROR(EIO) (may be changed) plus a log message if no progress
     428             :  *          was made and the negotiation is stuck;
     429             :  *          a negative error code if some other error happened
     430             :  */
     431        5081 : static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
     432             : {
     433             :     int i, j, ret;
     434        5081 :     int scaler_count = 0, resampler_count = 0;
     435        5081 :     int count_queried = 0;        /* successful calls to query_formats() */
     436        5081 :     int count_merged = 0;         /* successful merge of formats lists */
     437        5081 :     int count_already_merged = 0; /* lists already merged */
     438        5081 :     int count_delayed = 0;        /* lists that need to be merged later */
     439             : 
     440       27818 :     for (i = 0; i < graph->nb_filters; i++) {
     441       22737 :         AVFilterContext *f = graph->filters[i];
     442       22737 :         if (formats_declared(f))
     443          44 :             continue;
     444       22693 :         if (f->filter->query_formats)
     445       18568 :             ret = filter_query_formats(f);
     446             :         else
     447        4125 :             ret = ff_default_query_formats(f);
     448       22693 :         if (ret < 0 && ret != AVERROR(EAGAIN))
     449           0 :             return ret;
     450             :         /* note: EAGAIN could indicate a partial success, not counted yet */
     451       22693 :         count_queried += ret >= 0;
     452             :     }
     453             : 
     454             :     /* go through and merge as many format lists as possible */
     455       30438 :     for (i = 0; i < graph->nb_filters; i++) {
     456       25357 :         AVFilterContext *filter = graph->filters[i];
     457             : 
     458       45645 :         for (j = 0; j < filter->nb_inputs; j++) {
     459       20288 :             AVFilterLink *link = filter->inputs[j];
     460       20288 :             int convert_needed = 0;
     461             : 
     462       20288 :             if (!link)
     463           0 :                 continue;
     464             : 
     465       20288 :             if (link->in_formats != link->out_formats
     466       17647 :                 && link->in_formats && link->out_formats)
     467       17620 :                 if (!can_merge_formats(link->in_formats, link->out_formats,
     468             :                                       link->type, 0))
     469        2608 :                     convert_needed = 1;
     470       20288 :             if (link->type == AVMEDIA_TYPE_AUDIO) {
     471        4493 :                 if (link->in_samplerates != link->out_samplerates
     472        3949 :                     && link->in_samplerates && link->out_samplerates)
     473        3946 :                     if (!can_merge_formats(link->in_samplerates,
     474             :                                            link->out_samplerates,
     475             :                                            0, 1))
     476          17 :                         convert_needed = 1;
     477             :             }
     478             : 
     479             : #define MERGE_DISPATCH(field, statement)                                     \
     480             :             if (!(link->in_ ## field && link->out_ ## field)) {              \
     481             :                 count_delayed++;                                             \
     482             :             } else if (link->in_ ## field == link->out_ ## field) {          \
     483             :                 count_already_merged++;                                      \
     484             :             } else if (!convert_needed) {                                    \
     485             :                 count_merged++;                                              \
     486             :                 statement                                                    \
     487             :             }
     488             : 
     489       20288 :             if (link->type == AVMEDIA_TYPE_AUDIO) {
     490        4493 :                 MERGE_DISPATCH(channel_layouts,
     491             :                     if (!ff_merge_channel_layouts(link->in_channel_layouts,
     492             :                                                   link->out_channel_layouts))
     493             :                         convert_needed = 1;
     494             :                 )
     495        4493 :                 MERGE_DISPATCH(samplerates,
     496             :                     if (!ff_merge_samplerates(link->in_samplerates,
     497             :                                               link->out_samplerates))
     498             :                         convert_needed = 1;
     499             :                 )
     500             :             }
     501       20288 :             MERGE_DISPATCH(formats,
     502             :                 if (!ff_merge_formats(link->in_formats, link->out_formats,
     503             :                                       link->type))
     504             :                     convert_needed = 1;
     505             :             )
     506             : #undef MERGE_DISPATCH
     507             : 
     508       20288 :             if (convert_needed) {
     509             :                 AVFilterContext *convert;
     510             :                 AVFilter *filter;
     511             :                 AVFilterLink *inlink, *outlink;
     512             :                 char scale_args[256];
     513             :                 char inst_name[30];
     514             : 
     515        2620 :                 if (graph->disable_auto_convert) {
     516           0 :                     av_log(log_ctx, AV_LOG_ERROR,
     517             :                            "The filters '%s' and '%s' do not have a common format "
     518             :                            "and automatic conversion is disabled.\n",
     519           0 :                            link->src->name, link->dst->name);
     520           0 :                     return AVERROR(EINVAL);
     521             :                 }
     522             : 
     523             :                 /* couldn't merge format lists. auto-insert conversion filter */
     524        2620 :                 switch (link->type) {
     525             :                 case AVMEDIA_TYPE_VIDEO:
     526        2077 :                     if (!(filter = avfilter_get_by_name("scale"))) {
     527           0 :                         av_log(log_ctx, AV_LOG_ERROR, "'scale' filter "
     528             :                                "not present, cannot convert pixel formats.\n");
     529           0 :                         return AVERROR(EINVAL);
     530             :                     }
     531             : 
     532        2077 :                     snprintf(inst_name, sizeof(inst_name), "auto_scaler_%d",
     533             :                              scaler_count++);
     534             : 
     535        2077 :                     if ((ret = avfilter_graph_create_filter(&convert, filter,
     536        2077 :                                                             inst_name, graph->scale_sws_opts, NULL,
     537             :                                                             graph)) < 0)
     538           0 :                         return ret;
     539        2077 :                     break;
     540             :                 case AVMEDIA_TYPE_AUDIO:
     541         543 :                     if (!(filter = avfilter_get_by_name("aresample"))) {
     542           0 :                         av_log(log_ctx, AV_LOG_ERROR, "'aresample' filter "
     543             :                                "not present, cannot convert audio formats.\n");
     544           0 :                         return AVERROR(EINVAL);
     545             :                     }
     546             : 
     547         543 :                     snprintf(inst_name, sizeof(inst_name), "auto_resampler_%d",
     548             :                              resampler_count++);
     549         543 :                     scale_args[0] = '\0';
     550         543 :                     if (graph->aresample_swr_opts)
     551         515 :                         snprintf(scale_args, sizeof(scale_args), "%s",
     552             :                                  graph->aresample_swr_opts);
     553         543 :                     if ((ret = avfilter_graph_create_filter(&convert, filter,
     554         543 :                                                             inst_name, graph->aresample_swr_opts,
     555             :                                                             NULL, graph)) < 0)
     556           0 :                         return ret;
     557         543 :                     break;
     558             :                 default:
     559           0 :                     return AVERROR(EINVAL);
     560             :                 }
     561             : 
     562        2620 :                 if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
     563           0 :                     return ret;
     564             : 
     565        2620 :                 if ((ret = filter_query_formats(convert)) < 0)
     566           0 :                     return ret;
     567             : 
     568        2620 :                 inlink  = convert->inputs[0];
     569        2620 :                 outlink = convert->outputs[0];
     570        2620 :                 av_assert0( inlink-> in_formats->refcount > 0);
     571        2620 :                 av_assert0( inlink->out_formats->refcount > 0);
     572        2620 :                 av_assert0(outlink-> in_formats->refcount > 0);
     573        2620 :                 av_assert0(outlink->out_formats->refcount > 0);
     574        2620 :                 if (outlink->type == AVMEDIA_TYPE_AUDIO) {
     575         543 :                     av_assert0( inlink-> in_samplerates->refcount > 0);
     576         543 :                     av_assert0( inlink->out_samplerates->refcount > 0);
     577         543 :                     av_assert0(outlink-> in_samplerates->refcount > 0);
     578         543 :                     av_assert0(outlink->out_samplerates->refcount > 0);
     579         543 :                     av_assert0( inlink-> in_channel_layouts->refcount > 0);
     580         543 :                     av_assert0( inlink->out_channel_layouts->refcount > 0);
     581         543 :                     av_assert0(outlink-> in_channel_layouts->refcount > 0);
     582         543 :                     av_assert0(outlink->out_channel_layouts->refcount > 0);
     583             :                 }
     584        5240 :                 if (!ff_merge_formats( inlink->in_formats,  inlink->out_formats,  inlink->type) ||
     585        2620 :                     !ff_merge_formats(outlink->in_formats, outlink->out_formats, outlink->type))
     586           0 :                     ret = AVERROR(ENOSYS);
     587        3163 :                 if (inlink->type == AVMEDIA_TYPE_AUDIO &&
     588         543 :                     (!ff_merge_samplerates(inlink->in_samplerates,
     589         543 :                                            inlink->out_samplerates) ||
     590         543 :                      !ff_merge_channel_layouts(inlink->in_channel_layouts,
     591         543 :                                                inlink->out_channel_layouts)))
     592           0 :                     ret = AVERROR(ENOSYS);
     593        3163 :                 if (outlink->type == AVMEDIA_TYPE_AUDIO &&
     594         543 :                     (!ff_merge_samplerates(outlink->in_samplerates,
     595         543 :                                            outlink->out_samplerates) ||
     596         543 :                      !ff_merge_channel_layouts(outlink->in_channel_layouts,
     597         543 :                                                outlink->out_channel_layouts)))
     598           0 :                     ret = AVERROR(ENOSYS);
     599             : 
     600        2620 :                 if (ret < 0) {
     601           0 :                     av_log(log_ctx, AV_LOG_ERROR,
     602             :                            "Impossible to convert between the formats supported by the filter "
     603           0 :                            "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
     604           0 :                     return ret;
     605             :                 }
     606             :             }
     607             :         }
     608             :     }
     609             : 
     610        5081 :     av_log(graph, AV_LOG_DEBUG, "query_formats: "
     611             :            "%d queried, %d merged, %d already done, %d delayed\n",
     612             :            count_queried, count_merged, count_already_merged, count_delayed);
     613        5081 :     if (count_delayed) {
     614             :         AVBPrint bp;
     615             : 
     616             :         /* if count_queried > 0, one filter at least did set its formats,
     617             :            that will give additional information to its neighbour;
     618             :            if count_merged > 0, one pair of formats lists at least was merged,
     619             :            that will give additional information to all connected filters;
     620             :            in both cases, progress was made and a new round must be done */
     621          14 :         if (count_queried || count_merged)
     622          14 :             return AVERROR(EAGAIN);
     623           0 :         av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
     624           0 :         for (i = 0; i < graph->nb_filters; i++)
     625           0 :             if (!formats_declared(graph->filters[i]))
     626           0 :                 av_bprintf(&bp, "%s%s", bp.len ? ", " : "",
     627           0 :                           graph->filters[i]->name);
     628           0 :         av_log(graph, AV_LOG_ERROR,
     629             :                "The following filters could not choose their formats: %s\n"
     630             :                "Consider inserting the (a)format filter near their input or "
     631             :                "output.\n", bp.str);
     632           0 :         return AVERROR(EIO);
     633             :     }
     634        5067 :     return 0;
     635             : }
     636             : 
     637         150 : static int get_fmt_score(enum AVSampleFormat dst_fmt, enum AVSampleFormat src_fmt)
     638             : {
     639         150 :     int score = 0;
     640             : 
     641         150 :     if (av_sample_fmt_is_planar(dst_fmt) != av_sample_fmt_is_planar(src_fmt))
     642         134 :         score ++;
     643             : 
     644         150 :     if (av_get_bytes_per_sample(dst_fmt) < av_get_bytes_per_sample(src_fmt)) {
     645          46 :         score += 100 * (av_get_bytes_per_sample(src_fmt) - av_get_bytes_per_sample(dst_fmt));
     646             :     }else
     647         104 :         score += 10  * (av_get_bytes_per_sample(dst_fmt) - av_get_bytes_per_sample(src_fmt));
     648             : 
     649         174 :     if (av_get_packed_sample_fmt(dst_fmt) == AV_SAMPLE_FMT_S32 &&
     650          24 :         av_get_packed_sample_fmt(src_fmt) == AV_SAMPLE_FMT_FLT)
     651           0 :         score += 20;
     652             : 
     653         161 :     if (av_get_packed_sample_fmt(dst_fmt) == AV_SAMPLE_FMT_FLT &&
     654          11 :         av_get_packed_sample_fmt(src_fmt) == AV_SAMPLE_FMT_S32)
     655           0 :         score += 2;
     656             : 
     657         150 :     return score;
     658             : }
     659             : 
     660          75 : static enum AVSampleFormat find_best_sample_fmt_of_2(enum AVSampleFormat dst_fmt1, enum AVSampleFormat dst_fmt2,
     661             :                                                      enum AVSampleFormat src_fmt)
     662             : {
     663             :     int score1, score2;
     664             : 
     665          75 :     score1 = get_fmt_score(dst_fmt1, src_fmt);
     666          75 :     score2 = get_fmt_score(dst_fmt2, src_fmt);
     667             : 
     668          75 :     return score1 < score2 ? dst_fmt1 : dst_fmt2;
     669             : }
     670             : 
     671       60718 : static int pick_format(AVFilterLink *link, AVFilterLink *ref)
     672             : {
     673       60718 :     if (!link || !link->in_formats)
     674       40478 :         return 0;
     675             : 
     676       20240 :     if (link->type == AVMEDIA_TYPE_VIDEO) {
     677       15751 :         if(ref && ref->type == AVMEDIA_TYPE_VIDEO){
     678          70 :             int has_alpha= av_pix_fmt_desc_get(ref->format)->nb_components % 2 == 0;
     679          70 :             enum AVPixelFormat best= AV_PIX_FMT_NONE;
     680             :             int i;
     681         464 :             for (i=0; i<link->in_formats->nb_formats; i++) {
     682         394 :                 enum AVPixelFormat p = link->in_formats->formats[i];
     683         394 :                 best= av_find_best_pix_fmt_of_2(best, p, ref->format, has_alpha, NULL);
     684             :             }
     685         140 :             av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s alpha:%d\n",
     686          70 :                    av_get_pix_fmt_name(best), link->in_formats->nb_formats,
     687          70 :                    av_get_pix_fmt_name(ref->format), has_alpha);
     688          70 :             link->in_formats->formats[0] = best;
     689             :         }
     690        4489 :     } else if (link->type == AVMEDIA_TYPE_AUDIO) {
     691        4489 :         if(ref && ref->type == AVMEDIA_TYPE_AUDIO){
     692          20 :             enum AVSampleFormat best= AV_SAMPLE_FMT_NONE;
     693             :             int i;
     694          95 :             for (i=0; i<link->in_formats->nb_formats; i++) {
     695          75 :                 enum AVSampleFormat p = link->in_formats->formats[i];
     696          75 :                 best = find_best_sample_fmt_of_2(best, p, ref->format);
     697             :             }
     698          40 :             av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s\n",
     699          20 :                    av_get_sample_fmt_name(best), link->in_formats->nb_formats,
     700          20 :                    av_get_sample_fmt_name(ref->format));
     701          20 :             link->in_formats->formats[0] = best;
     702             :         }
     703             :     }
     704             : 
     705       20240 :     link->in_formats->nb_formats = 1;
     706       20240 :     link->format = link->in_formats->formats[0];
     707             : 
     708       20240 :     if (link->type == AVMEDIA_TYPE_AUDIO) {
     709        4489 :         if (!link->in_samplerates->nb_formats) {
     710           0 :             av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
     711           0 :                    " the link between filters %s and %s.\n", link->src->name,
     712           0 :                    link->dst->name);
     713           0 :             return AVERROR(EINVAL);
     714             :         }
     715        4489 :         link->in_samplerates->nb_formats = 1;
     716        4489 :         link->sample_rate = link->in_samplerates->formats[0];
     717             : 
     718        4489 :         if (link->in_channel_layouts->all_layouts) {
     719           0 :             av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
     720           0 :                    " the link between filters %s and %s.\n", link->src->name,
     721           0 :                    link->dst->name);
     722           0 :             if (!link->in_channel_layouts->all_counts)
     723           0 :                 av_log(link->src, AV_LOG_ERROR, "Unknown channel layouts not "
     724             :                        "supported, try specifying a channel layout using "
     725             :                        "'aformat=channel_layouts=something'.\n");
     726           0 :             return AVERROR(EINVAL);
     727             :         }
     728        4489 :         link->in_channel_layouts->nb_channel_layouts = 1;
     729        4489 :         link->channel_layout = link->in_channel_layouts->channel_layouts[0];
     730        4489 :         if ((link->channels = FF_LAYOUT2COUNT(link->channel_layout)))
     731          10 :             link->channel_layout = 0;
     732             :         else
     733        4479 :             link->channels = av_get_channel_layout_nb_channels(link->channel_layout);
     734             :     }
     735             : 
     736       20240 :     ff_formats_unref(&link->in_formats);
     737       20240 :     ff_formats_unref(&link->out_formats);
     738       20240 :     ff_formats_unref(&link->in_samplerates);
     739       20240 :     ff_formats_unref(&link->out_samplerates);
     740       20240 :     ff_channel_layouts_unref(&link->in_channel_layouts);
     741       20240 :     ff_channel_layouts_unref(&link->out_channel_layouts);
     742             : 
     743       20240 :     return 0;
     744             : }
     745             : 
     746             : #define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format, unref_format) \
     747             : do {                                                                   \
     748             :     for (i = 0; i < filter->nb_inputs; i++) {                          \
     749             :         AVFilterLink *link = filter->inputs[i];                        \
     750             :         fmt_type fmt;                                                  \
     751             :                                                                        \
     752             :         if (!link->out_ ## list || link->out_ ## list->nb != 1)        \
     753             :             continue;                                                  \
     754             :         fmt = link->out_ ## list->var[0];                              \
     755             :                                                                        \
     756             :         for (j = 0; j < filter->nb_outputs; j++) {                     \
     757             :             AVFilterLink *out_link = filter->outputs[j];               \
     758             :             list_type *fmts;                                           \
     759             :                                                                        \
     760             :             if (link->type != out_link->type ||                        \
     761             :                 out_link->in_ ## list->nb == 1)                        \
     762             :                 continue;                                              \
     763             :             fmts = out_link->in_ ## list;                              \
     764             :                                                                        \
     765             :             if (!out_link->in_ ## list->nb) {                          \
     766             :                 if ((ret = add_format(&out_link->in_ ##list, fmt)) < 0)\
     767             :                     return ret;                                        \
     768             :                 ret = 1;                                               \
     769             :                 break;                                                 \
     770             :             }                                                          \
     771             :                                                                        \
     772             :             for (k = 0; k < out_link->in_ ## list->nb; k++)            \
     773             :                 if (fmts->var[k] == fmt) {                             \
     774             :                     fmts->var[0]  = fmt;                               \
     775             :                     fmts->nb = 1;                                      \
     776             :                     ret = 1;                                           \
     777             :                     break;                                             \
     778             :                 }                                                      \
     779             :         }                                                              \
     780             :     }                                                                  \
     781             : } while (0)
     782             : 
     783       27970 : static int reduce_formats_on_filter(AVFilterContext *filter)
     784             : {
     785       27970 :     int i, j, k, ret = 0;
     786             : 
     787       27970 :     REDUCE_FORMATS(int,      AVFilterFormats,        formats,         formats,
     788             :                    nb_formats, ff_add_format, ff_formats_unref);
     789       27970 :     REDUCE_FORMATS(int,      AVFilterFormats,        samplerates,     formats,
     790             :                    nb_formats, ff_add_format, ff_formats_unref);
     791             : 
     792             :     /* reduce channel layouts */
     793       50364 :     for (i = 0; i < filter->nb_inputs; i++) {
     794       22394 :         AVFilterLink *inlink = filter->inputs[i];
     795             :         uint64_t fmt;
     796             : 
     797       28871 :         if (!inlink->out_channel_layouts ||
     798        6477 :             inlink->out_channel_layouts->nb_channel_layouts != 1)
     799       16938 :             continue;
     800        5456 :         fmt = inlink->out_channel_layouts->channel_layouts[0];
     801             : 
     802        8898 :         for (j = 0; j < filter->nb_outputs; j++) {
     803        4447 :             AVFilterLink *outlink = filter->outputs[j];
     804             :             AVFilterChannelLayouts *fmts;
     805             : 
     806        4447 :             fmts = outlink->in_channel_layouts;
     807        4447 :             if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1)
     808        3422 :                 continue;
     809             : 
     810        2030 :             if (fmts->all_layouts &&
     811        1007 :                 (!FF_LAYOUT2COUNT(fmt) || fmts->all_counts)) {
     812             :                 /* Turn the infinite list into a singleton */
     813        1005 :                 fmts->all_layouts = fmts->all_counts  = 0;
     814        1005 :                 if (ff_add_channel_layout(&outlink->in_channel_layouts, fmt) < 0)
     815           0 :                     ret = 1;
     816        1005 :                 break;
     817             :             }
     818             : 
     819          70 :             for (k = 0; k < outlink->in_channel_layouts->nb_channel_layouts; k++) {
     820          68 :                 if (fmts->channel_layouts[k] == fmt) {
     821          18 :                     fmts->channel_layouts[0]  = fmt;
     822          18 :                     fmts->nb_channel_layouts = 1;
     823          18 :                     ret = 1;
     824          18 :                     break;
     825             :                 }
     826             :             }
     827             :         }
     828             :     }
     829             : 
     830       27970 :     return ret;
     831             : }
     832             : 
     833        5584 : static int reduce_formats(AVFilterGraph *graph)
     834             : {
     835             :     int i, reduced, ret;
     836             : 
     837             :     do {
     838        5584 :         reduced = 0;
     839             : 
     840       33554 :         for (i = 0; i < graph->nb_filters; i++) {
     841       27970 :             if ((ret = reduce_formats_on_filter(graph->filters[i])) < 0)
     842           0 :                 return ret;
     843       27970 :             reduced |= ret;
     844             :         }
     845        5584 :     } while (reduced);
     846             : 
     847        5067 :     return 0;
     848             : }
     849             : 
     850       25299 : static void swap_samplerates_on_filter(AVFilterContext *filter)
     851             : {
     852       25299 :     AVFilterLink *link = NULL;
     853             :     int sample_rate;
     854             :     int i, j;
     855             : 
     856       41048 :     for (i = 0; i < filter->nb_inputs; i++) {
     857       20229 :         link = filter->inputs[i];
     858             : 
     859       24709 :         if (link->type == AVMEDIA_TYPE_AUDIO &&
     860        4480 :             link->out_samplerates->nb_formats== 1)
     861        4480 :             break;
     862             :     }
     863       25299 :     if (i == filter->nb_inputs)
     864       20819 :         return;
     865             : 
     866        4480 :     sample_rate = link->out_samplerates->formats[0];
     867             : 
     868        7945 :     for (i = 0; i < filter->nb_outputs; i++) {
     869        3465 :         AVFilterLink *outlink = filter->outputs[i];
     870        3465 :         int best_idx, best_diff = INT_MAX;
     871             : 
     872        6929 :         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
     873        3464 :             outlink->in_samplerates->nb_formats < 2)
     874        3465 :             continue;
     875             : 
     876           0 :         for (j = 0; j < outlink->in_samplerates->nb_formats; j++) {
     877           0 :             int diff = abs(sample_rate - outlink->in_samplerates->formats[j]);
     878             : 
     879           0 :             av_assert0(diff < INT_MAX); // This would lead to the use of uninitialized best_diff but is only possible with invalid sample rates
     880             : 
     881           0 :             if (diff < best_diff) {
     882           0 :                 best_diff = diff;
     883           0 :                 best_idx  = j;
     884             :             }
     885             :         }
     886           0 :         FFSWAP(int, outlink->in_samplerates->formats[0],
     887             :                outlink->in_samplerates->formats[best_idx]);
     888             :     }
     889             : }
     890             : 
     891        5067 : static void swap_samplerates(AVFilterGraph *graph)
     892             : {
     893             :     int i;
     894             : 
     895       30366 :     for (i = 0; i < graph->nb_filters; i++)
     896       25299 :         swap_samplerates_on_filter(graph->filters[i]);
     897        5067 : }
     898             : 
     899             : #define CH_CENTER_PAIR (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)
     900             : #define CH_FRONT_PAIR  (AV_CH_FRONT_LEFT           | AV_CH_FRONT_RIGHT)
     901             : #define CH_STEREO_PAIR (AV_CH_STEREO_LEFT          | AV_CH_STEREO_RIGHT)
     902             : #define CH_WIDE_PAIR   (AV_CH_WIDE_LEFT            | AV_CH_WIDE_RIGHT)
     903             : #define CH_SIDE_PAIR   (AV_CH_SIDE_LEFT            | AV_CH_SIDE_RIGHT)
     904             : #define CH_DIRECT_PAIR (AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT)
     905             : #define CH_BACK_PAIR   (AV_CH_BACK_LEFT            | AV_CH_BACK_RIGHT)
     906             : 
     907             : /* allowable substitutions for channel pairs when comparing layouts,
     908             :  * ordered by priority for both values */
     909             : static const uint64_t ch_subst[][2] = {
     910             :     { CH_FRONT_PAIR,      CH_CENTER_PAIR     },
     911             :     { CH_FRONT_PAIR,      CH_WIDE_PAIR       },
     912             :     { CH_FRONT_PAIR,      AV_CH_FRONT_CENTER },
     913             :     { CH_CENTER_PAIR,     CH_FRONT_PAIR      },
     914             :     { CH_CENTER_PAIR,     CH_WIDE_PAIR       },
     915             :     { CH_CENTER_PAIR,     AV_CH_FRONT_CENTER },
     916             :     { CH_WIDE_PAIR,       CH_FRONT_PAIR      },
     917             :     { CH_WIDE_PAIR,       CH_CENTER_PAIR     },
     918             :     { CH_WIDE_PAIR,       AV_CH_FRONT_CENTER },
     919             :     { AV_CH_FRONT_CENTER, CH_FRONT_PAIR      },
     920             :     { AV_CH_FRONT_CENTER, CH_CENTER_PAIR     },
     921             :     { AV_CH_FRONT_CENTER, CH_WIDE_PAIR       },
     922             :     { CH_SIDE_PAIR,       CH_DIRECT_PAIR     },
     923             :     { CH_SIDE_PAIR,       CH_BACK_PAIR       },
     924             :     { CH_SIDE_PAIR,       AV_CH_BACK_CENTER  },
     925             :     { CH_BACK_PAIR,       CH_DIRECT_PAIR     },
     926             :     { CH_BACK_PAIR,       CH_SIDE_PAIR       },
     927             :     { CH_BACK_PAIR,       AV_CH_BACK_CENTER  },
     928             :     { AV_CH_BACK_CENTER,  CH_BACK_PAIR       },
     929             :     { AV_CH_BACK_CENTER,  CH_DIRECT_PAIR     },
     930             :     { AV_CH_BACK_CENTER,  CH_SIDE_PAIR       },
     931             : };
     932             : 
     933       25299 : static void swap_channel_layouts_on_filter(AVFilterContext *filter)
     934             : {
     935       25299 :     AVFilterLink *link = NULL;
     936             :     int i, j, k;
     937             : 
     938       41050 :     for (i = 0; i < filter->nb_inputs; i++) {
     939       20229 :         link = filter->inputs[i];
     940             : 
     941       24709 :         if (link->type == AVMEDIA_TYPE_AUDIO &&
     942        4480 :             link->out_channel_layouts->nb_channel_layouts == 1)
     943        4478 :             break;
     944             :     }
     945       25299 :     if (i == filter->nb_inputs)
     946       20821 :         return;
     947             : 
     948        7942 :     for (i = 0; i < filter->nb_outputs; i++) {
     949        3464 :         AVFilterLink *outlink = filter->outputs[i];
     950        3464 :         int best_idx = -1, best_score = INT_MIN, best_count_diff = INT_MAX;
     951             : 
     952        6927 :         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
     953        3463 :             outlink->in_channel_layouts->nb_channel_layouts < 2)
     954        3463 :             continue;
     955             : 
     956          19 :         for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts; j++) {
     957          18 :             uint64_t  in_chlayout = link->out_channel_layouts->channel_layouts[0];
     958          18 :             uint64_t out_chlayout = outlink->in_channel_layouts->channel_layouts[j];
     959          18 :             int  in_channels      = av_get_channel_layout_nb_channels(in_chlayout);
     960          18 :             int out_channels      = av_get_channel_layout_nb_channels(out_chlayout);
     961          18 :             int count_diff        = out_channels - in_channels;
     962             :             int matched_channels, extra_channels;
     963          18 :             int score = 100000;
     964             : 
     965          18 :             if (FF_LAYOUT2COUNT(in_chlayout) || FF_LAYOUT2COUNT(out_chlayout)) {
     966             :                 /* Compute score in case the input or output layout encodes
     967             :                    a channel count; in this case the score is not altered by
     968             :                    the computation afterwards, as in_chlayout and
     969             :                    out_chlayout have both been set to 0 */
     970          18 :                 if (FF_LAYOUT2COUNT(in_chlayout))
     971          18 :                     in_channels = FF_LAYOUT2COUNT(in_chlayout);
     972          18 :                 if (FF_LAYOUT2COUNT(out_chlayout))
     973           0 :                     out_channels = FF_LAYOUT2COUNT(out_chlayout);
     974          36 :                 score -= 10000 + FFABS(out_channels - in_channels) +
     975          18 :                          (in_channels > out_channels ? 10000 : 0);
     976          18 :                 in_chlayout = out_chlayout = 0;
     977             :                 /* Let the remaining computation run, even if the score
     978             :                    value is not altered */
     979             :             }
     980             : 
     981             :             /* channel substitution */
     982         396 :             for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) {
     983         378 :                 uint64_t cmp0 = ch_subst[k][0];
     984         378 :                 uint64_t cmp1 = ch_subst[k][1];
     985         378 :                 if (( in_chlayout & cmp0) && (!(out_chlayout & cmp0)) &&
     986           0 :                     (out_chlayout & cmp1) && (!( in_chlayout & cmp1))) {
     987           0 :                     in_chlayout  &= ~cmp0;
     988           0 :                     out_chlayout &= ~cmp1;
     989             :                     /* add score for channel match, minus a deduction for
     990             :                        having to do the substitution */
     991           0 :                     score += 10 * av_get_channel_layout_nb_channels(cmp1) - 2;
     992             :                 }
     993             :             }
     994             : 
     995             :             /* no penalty for LFE channel mismatch */
     996          18 :             if ( (in_chlayout & AV_CH_LOW_FREQUENCY) &&
     997           0 :                 (out_chlayout & AV_CH_LOW_FREQUENCY))
     998           0 :                 score += 10;
     999          18 :             in_chlayout  &= ~AV_CH_LOW_FREQUENCY;
    1000          18 :             out_chlayout &= ~AV_CH_LOW_FREQUENCY;
    1001             : 
    1002          18 :             matched_channels = av_get_channel_layout_nb_channels(in_chlayout &
    1003             :                                                                  out_chlayout);
    1004          18 :             extra_channels   = av_get_channel_layout_nb_channels(out_chlayout &
    1005          18 :                                                                  (~in_chlayout));
    1006          18 :             score += 10 * matched_channels - 5 * extra_channels;
    1007             : 
    1008          18 :             if (score > best_score ||
    1009           0 :                 (count_diff < best_count_diff && score == best_score)) {
    1010           1 :                 best_score = score;
    1011           1 :                 best_idx   = j;
    1012           1 :                 best_count_diff = count_diff;
    1013             :             }
    1014             :         }
    1015           1 :         av_assert0(best_idx >= 0);
    1016           1 :         FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0],
    1017             :                outlink->in_channel_layouts->channel_layouts[best_idx]);
    1018             :     }
    1019             : 
    1020             : }
    1021             : 
    1022        5067 : static void swap_channel_layouts(AVFilterGraph *graph)
    1023             : {
    1024             :     int i;
    1025             : 
    1026       30366 :     for (i = 0; i < graph->nb_filters; i++)
    1027       25299 :         swap_channel_layouts_on_filter(graph->filters[i]);
    1028        5067 : }
    1029             : 
    1030       25299 : static void swap_sample_fmts_on_filter(AVFilterContext *filter)
    1031             : {
    1032       25299 :     AVFilterLink *link = NULL;
    1033             :     int format, bps;
    1034             :     int i, j;
    1035             : 
    1036       41088 :     for (i = 0; i < filter->nb_inputs; i++) {
    1037       20230 :         link = filter->inputs[i];
    1038             : 
    1039       24711 :         if (link->type == AVMEDIA_TYPE_AUDIO &&
    1040        4481 :             link->out_formats->nb_formats == 1)
    1041        4441 :             break;
    1042             :     }
    1043       25299 :     if (i == filter->nb_inputs)
    1044       20858 :         return;
    1045             : 
    1046        4441 :     format = link->out_formats->formats[0];
    1047        4441 :     bps    = av_get_bytes_per_sample(format);
    1048             : 
    1049        7880 :     for (i = 0; i < filter->nb_outputs; i++) {
    1050        3439 :         AVFilterLink *outlink = filter->outputs[i];
    1051        3439 :         int best_idx = -1, best_score = INT_MIN;
    1052             : 
    1053        6877 :         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
    1054        3438 :             outlink->in_formats->nb_formats < 2)
    1055        3418 :             continue;
    1056             : 
    1057          47 :         for (j = 0; j < outlink->in_formats->nb_formats; j++) {
    1058          47 :             int out_format = outlink->in_formats->formats[j];
    1059          47 :             int out_bps    = av_get_bytes_per_sample(out_format);
    1060             :             int score;
    1061             : 
    1062          77 :             if (av_get_packed_sample_fmt(out_format) == format ||
    1063          30 :                 av_get_planar_sample_fmt(out_format) == format) {
    1064          21 :                 best_idx   = j;
    1065          21 :                 break;
    1066             :             }
    1067             : 
    1068             :             /* for s32 and float prefer double to prevent loss of information */
    1069          26 :             if (bps == 4 && out_bps == 8) {
    1070           0 :                 best_idx = j;
    1071           0 :                 break;
    1072             :             }
    1073             : 
    1074             :             /* prefer closest higher or equal bps */
    1075          26 :             score = -abs(out_bps - bps);
    1076          26 :             if (out_bps >= bps)
    1077           0 :                 score += INT_MAX/2;
    1078             : 
    1079          26 :             if (score > best_score) {
    1080          22 :                 best_score = score;
    1081          22 :                 best_idx   = j;
    1082             :             }
    1083             :         }
    1084          21 :         av_assert0(best_idx >= 0);
    1085          21 :         FFSWAP(int, outlink->in_formats->formats[0],
    1086             :                outlink->in_formats->formats[best_idx]);
    1087             :     }
    1088             : }
    1089             : 
    1090        5067 : static void swap_sample_fmts(AVFilterGraph *graph)
    1091             : {
    1092             :     int i;
    1093             : 
    1094       30366 :     for (i = 0; i < graph->nb_filters; i++)
    1095       25299 :         swap_sample_fmts_on_filter(graph->filters[i]);
    1096             : 
    1097        5067 : }
    1098             : 
    1099       10200 : static int pick_formats(AVFilterGraph *graph)
    1100             : {
    1101             :     int i, j, ret;
    1102             :     int change;
    1103             : 
    1104             :     do{
    1105       10200 :         change = 0;
    1106       61132 :         for (i = 0; i < graph->nb_filters; i++) {
    1107       50932 :             AVFilterContext *filter = graph->filters[i];
    1108       50932 :             if (filter->nb_inputs){
    1109       81424 :                 for (j = 0; j < filter->nb_inputs; j++){
    1110       40751 :                     if(filter->inputs[j]->in_formats && filter->inputs[j]->in_formats->nb_formats == 1) {
    1111       10041 :                         if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
    1112           0 :                             return ret;
    1113       10041 :                         change = 1;
    1114             :                     }
    1115             :                 }
    1116             :             }
    1117       50932 :             if (filter->nb_outputs){
    1118       81475 :                 for (j = 0; j < filter->nb_outputs; j++){
    1119       40751 :                     if(filter->outputs[j]->in_formats && filter->outputs[j]->in_formats->nb_formats == 1) {
    1120       10107 :                         if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
    1121           0 :                             return ret;
    1122       10107 :                         change = 1;
    1123             :                     }
    1124             :                 }
    1125             :             }
    1126       50932 :             if (filter->nb_inputs && filter->nb_outputs && filter->inputs[0]->format>=0) {
    1127       60789 :                 for (j = 0; j < filter->nb_outputs; j++) {
    1128       30407 :                     if(filter->outputs[j]->format<0) {
    1129          90 :                         if ((ret = pick_format(filter->outputs[j], filter->inputs[0])) < 0)
    1130           0 :                             return ret;
    1131          90 :                         change = 1;
    1132             :                     }
    1133             :                 }
    1134             :             }
    1135             :         }
    1136       10200 :     }while(change);
    1137             : 
    1138       30366 :     for (i = 0; i < graph->nb_filters; i++) {
    1139       25299 :         AVFilterContext *filter = graph->filters[i];
    1140             : 
    1141       45539 :         for (j = 0; j < filter->nb_inputs; j++)
    1142       20240 :             if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
    1143           0 :                 return ret;
    1144       45539 :         for (j = 0; j < filter->nb_outputs; j++)
    1145       20240 :             if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
    1146           0 :                 return ret;
    1147             :     }
    1148        5067 :     return 0;
    1149             : }
    1150             : 
    1151             : /**
    1152             :  * Configure the formats of all the links in the graph.
    1153             :  */
    1154        5067 : static int graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
    1155             : {
    1156             :     int ret;
    1157             : 
    1158             :     /* find supported formats from sub-filters, and merge along links */
    1159       10148 :     while ((ret = query_formats(graph, log_ctx)) == AVERROR(EAGAIN))
    1160          14 :         av_log(graph, AV_LOG_DEBUG, "query_formats not finished\n");
    1161        5067 :     if (ret < 0)
    1162           0 :         return ret;
    1163             : 
    1164             :     /* Once everything is merged, it's possible that we'll still have
    1165             :      * multiple valid media format choices. We try to minimize the amount
    1166             :      * of format conversion inside filters */
    1167        5067 :     if ((ret = reduce_formats(graph)) < 0)
    1168           0 :         return ret;
    1169             : 
    1170             :     /* for audio filters, ensure the best format, sample rate and channel layout
    1171             :      * is selected */
    1172        5067 :     swap_sample_fmts(graph);
    1173        5067 :     swap_samplerates(graph);
    1174        5067 :     swap_channel_layouts(graph);
    1175             : 
    1176        5067 :     if ((ret = pick_formats(graph)) < 0)
    1177           0 :         return ret;
    1178             : 
    1179        5067 :     return 0;
    1180             : }
    1181             : 
    1182        5067 : static int graph_config_pointers(AVFilterGraph *graph,
    1183             :                                              AVClass *log_ctx)
    1184             : {
    1185             :     unsigned i, j;
    1186        5067 :     int sink_links_count = 0, n = 0;
    1187             :     AVFilterContext *f;
    1188             :     AVFilterLink **sinks;
    1189             : 
    1190       30366 :     for (i = 0; i < graph->nb_filters; i++) {
    1191       25299 :         f = graph->filters[i];
    1192       45539 :         for (j = 0; j < f->nb_inputs; j++) {
    1193       20240 :             f->inputs[j]->graph     = graph;
    1194       20240 :             f->inputs[j]->age_index = -1;
    1195             :         }
    1196       45539 :         for (j = 0; j < f->nb_outputs; j++) {
    1197       20240 :             f->outputs[j]->graph    = graph;
    1198       20240 :             f->outputs[j]->age_index= -1;
    1199             :         }
    1200       25299 :         if (!f->nb_outputs) {
    1201        5071 :             if (f->nb_inputs > INT_MAX - sink_links_count)
    1202           0 :                 return AVERROR(EINVAL);
    1203        5071 :             sink_links_count += f->nb_inputs;
    1204             :         }
    1205             :     }
    1206        5067 :     sinks = av_calloc(sink_links_count, sizeof(*sinks));
    1207        5067 :     if (!sinks)
    1208           0 :         return AVERROR(ENOMEM);
    1209       30366 :     for (i = 0; i < graph->nb_filters; i++) {
    1210       25299 :         f = graph->filters[i];
    1211       25299 :         if (!f->nb_outputs) {
    1212       10142 :             for (j = 0; j < f->nb_inputs; j++) {
    1213        5071 :                 sinks[n] = f->inputs[j];
    1214        5071 :                 f->inputs[j]->age_index = n++;
    1215             :             }
    1216             :         }
    1217             :     }
    1218        5067 :     av_assert0(n == sink_links_count);
    1219        5067 :     graph->sink_links       = sinks;
    1220        5067 :     graph->sink_links_count = sink_links_count;
    1221        5067 :     return 0;
    1222             : }
    1223             : 
    1224        5067 : static int graph_insert_fifos(AVFilterGraph *graph, AVClass *log_ctx)
    1225             : {
    1226             :     AVFilterContext *f;
    1227             :     int i, j, ret;
    1228        5067 :     int fifo_count = 0;
    1229             : 
    1230       27746 :     for (i = 0; i < graph->nb_filters; i++) {
    1231       22679 :         f = graph->filters[i];
    1232             : 
    1233       40299 :         for (j = 0; j < f->nb_inputs; j++) {
    1234       17620 :             AVFilterLink *link = f->inputs[j];
    1235             :             AVFilterContext *fifo_ctx;
    1236             :             AVFilter *fifo;
    1237             :             char name[32];
    1238             : 
    1239       17620 :             if (!link->dstpad->needs_fifo)
    1240       17608 :                 continue;
    1241             : 
    1242          24 :             fifo = f->inputs[j]->type == AVMEDIA_TYPE_VIDEO ?
    1243          12 :                    avfilter_get_by_name("fifo") :
    1244             :                    avfilter_get_by_name("afifo");
    1245             : 
    1246          12 :             snprintf(name, sizeof(name), "auto_fifo_%d", fifo_count++);
    1247             : 
    1248          12 :             ret = avfilter_graph_create_filter(&fifo_ctx, fifo, name, NULL,
    1249             :                                                NULL, graph);
    1250          12 :             if (ret < 0)
    1251           0 :                 return ret;
    1252             : 
    1253          12 :             ret = avfilter_insert_filter(link, fifo_ctx, 0, 0);
    1254          12 :             if (ret < 0)
    1255           0 :                 return ret;
    1256             :         }
    1257             :     }
    1258             : 
    1259        5067 :     return 0;
    1260             : }
    1261             : 
    1262        5067 : int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
    1263             : {
    1264             :     int ret;
    1265             : 
    1266        5067 :     if ((ret = graph_check_validity(graphctx, log_ctx)))
    1267           0 :         return ret;
    1268        5067 :     if ((ret = graph_insert_fifos(graphctx, log_ctx)) < 0)
    1269           0 :         return ret;
    1270        5067 :     if ((ret = graph_config_formats(graphctx, log_ctx)))
    1271           0 :         return ret;
    1272        5067 :     if ((ret = graph_config_links(graphctx, log_ctx)))
    1273           0 :         return ret;
    1274        5067 :     if ((ret = graph_config_pointers(graphctx, log_ctx)))
    1275           0 :         return ret;
    1276             : 
    1277        5067 :     return 0;
    1278             : }
    1279             : 
    1280           0 : int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags)
    1281             : {
    1282           0 :     int i, r = AVERROR(ENOSYS);
    1283             : 
    1284           0 :     if (!graph)
    1285           0 :         return r;
    1286             : 
    1287           0 :     if ((flags & AVFILTER_CMD_FLAG_ONE) && !(flags & AVFILTER_CMD_FLAG_FAST)) {
    1288           0 :         r = avfilter_graph_send_command(graph, target, cmd, arg, res, res_len, flags | AVFILTER_CMD_FLAG_FAST);
    1289           0 :         if (r != AVERROR(ENOSYS))
    1290           0 :             return r;
    1291             :     }
    1292             : 
    1293           0 :     if (res_len && res)
    1294           0 :         res[0] = 0;
    1295             : 
    1296           0 :     for (i = 0; i < graph->nb_filters; i++) {
    1297           0 :         AVFilterContext *filter = graph->filters[i];
    1298           0 :         if (!strcmp(target, "all") || (filter->name && !strcmp(target, filter->name)) || !strcmp(target, filter->filter->name)) {
    1299           0 :             r = avfilter_process_command(filter, cmd, arg, res, res_len, flags);
    1300           0 :             if (r != AVERROR(ENOSYS)) {
    1301           0 :                 if ((flags & AVFILTER_CMD_FLAG_ONE) || r < 0)
    1302           0 :                     return r;
    1303             :             }
    1304             :         }
    1305             :     }
    1306             : 
    1307           0 :     return r;
    1308             : }
    1309             : 
    1310           0 : int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *command, const char *arg, int flags, double ts)
    1311             : {
    1312             :     int i;
    1313             : 
    1314           0 :     if(!graph)
    1315           0 :         return 0;
    1316             : 
    1317           0 :     for (i = 0; i < graph->nb_filters; i++) {
    1318           0 :         AVFilterContext *filter = graph->filters[i];
    1319           0 :         if(filter && (!strcmp(target, "all") || !strcmp(target, filter->name) || !strcmp(target, filter->filter->name))){
    1320           0 :             AVFilterCommand **queue = &filter->command_queue, *next;
    1321           0 :             while (*queue && (*queue)->time <= ts)
    1322           0 :                 queue = &(*queue)->next;
    1323           0 :             next = *queue;
    1324           0 :             *queue = av_mallocz(sizeof(AVFilterCommand));
    1325           0 :             (*queue)->command = av_strdup(command);
    1326           0 :             (*queue)->arg     = av_strdup(arg);
    1327           0 :             (*queue)->time    = ts;
    1328           0 :             (*queue)->flags   = flags;
    1329           0 :             (*queue)->next    = next;
    1330           0 :             if(flags & AVFILTER_CMD_FLAG_ONE)
    1331           0 :                 return 0;
    1332             :         }
    1333             :     }
    1334             : 
    1335           0 :     return 0;
    1336             : }
    1337             : 
    1338      386836 : static void heap_bubble_up(AVFilterGraph *graph,
    1339             :                            AVFilterLink *link, int index)
    1340             : {
    1341      386836 :     AVFilterLink **links = graph->sink_links;
    1342             : 
    1343      386836 :     av_assert0(index >= 0);
    1344             : 
    1345      773685 :     while (index) {
    1346          13 :         int parent = (index - 1) >> 1;
    1347          13 :         if (links[parent]->current_pts_us >= link->current_pts_us)
    1348           0 :             break;
    1349          13 :         links[index] = links[parent];
    1350          13 :         links[index]->age_index = index;
    1351          13 :         index = parent;
    1352             :     }
    1353      386836 :     links[index] = link;
    1354      386836 :     link->age_index = index;
    1355      386836 : }
    1356             : 
    1357      386836 : static void heap_bubble_down(AVFilterGraph *graph,
    1358             :                              AVFilterLink *link, int index)
    1359             : {
    1360      386836 :     AVFilterLink **links = graph->sink_links;
    1361             : 
    1362      386836 :     av_assert0(index >= 0);
    1363             : 
    1364         574 :     while (1) {
    1365      387410 :         int child = 2 * index + 1;
    1366      387410 :         if (child >= graph->sink_links_count)
    1367      386678 :             break;
    1368         746 :         if (child + 1 < graph->sink_links_count &&
    1369          14 :             links[child + 1]->current_pts_us < links[child]->current_pts_us)
    1370           4 :             child++;
    1371         732 :         if (link->current_pts_us < links[child]->current_pts_us)
    1372         158 :             break;
    1373         574 :         links[index] = links[child];
    1374         574 :         links[index]->age_index = index;
    1375         574 :         index = child;
    1376             :     }
    1377      386836 :     links[index] = link;
    1378      386836 :     link->age_index = index;
    1379      386836 : }
    1380             : 
    1381      386836 : void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link)
    1382             : {
    1383      386836 :     heap_bubble_up  (graph, link, link->age_index);
    1384      386836 :     heap_bubble_down(graph, link, link->age_index);
    1385      386836 : }
    1386             : 
    1387      369689 : int avfilter_graph_request_oldest(AVFilterGraph *graph)
    1388             : {
    1389      369689 :     AVFilterLink *oldest = graph->sink_links[0];
    1390             :     int64_t frame_count;
    1391             :     int r;
    1392             : 
    1393      739378 :     while (graph->sink_links_count) {
    1394      369689 :         oldest = graph->sink_links[0];
    1395      369689 :         if (oldest->dst->filter->activate) {
    1396             :             /* For now, buffersink is the only filter implementing activate. */
    1397      369689 :             return av_buffersink_get_frame_flags(oldest->dst, NULL,
    1398             :                                                  AV_BUFFERSINK_FLAG_PEEK);
    1399             :         }
    1400           0 :         r = ff_request_frame(oldest);
    1401           0 :         if (r != AVERROR_EOF)
    1402           0 :             break;
    1403           0 :         av_log(oldest->dst, AV_LOG_DEBUG, "EOF on sink link %s:%s.\n",
    1404           0 :                oldest->dst ? oldest->dst->name : "unknown",
    1405           0 :                oldest->dstpad ? oldest->dstpad->name : "unknown");
    1406             :         /* EOF: remove the link from the heap */
    1407           0 :         if (oldest->age_index < --graph->sink_links_count)
    1408           0 :             heap_bubble_down(graph, graph->sink_links[graph->sink_links_count],
    1409             :                              oldest->age_index);
    1410           0 :         oldest->age_index = -1;
    1411             :     }
    1412           0 :     if (!graph->sink_links_count)
    1413           0 :         return AVERROR_EOF;
    1414             :     av_assert1(!oldest->dst->filter->activate);
    1415             :     av_assert1(oldest->age_index >= 0);
    1416           0 :     frame_count = oldest->frame_count_out;
    1417           0 :     while (frame_count == oldest->frame_count_out) {
    1418           0 :         r = ff_filter_graph_run_once(graph);
    1419           0 :         if (r == AVERROR(EAGAIN) &&
    1420           0 :             !oldest->frame_wanted_out && !oldest->frame_blocked_in &&
    1421           0 :             !oldest->status_in)
    1422           0 :             ff_request_frame(oldest);
    1423           0 :         else if (r < 0)
    1424           0 :             return r;
    1425             :     }
    1426           0 :     return 0;
    1427             : }
    1428             : 
    1429     4078409 : int ff_filter_graph_run_once(AVFilterGraph *graph)
    1430             : {
    1431             :     AVFilterContext *filter;
    1432             :     unsigned i;
    1433             : 
    1434     4078409 :     av_assert0(graph->nb_filters);
    1435     4078409 :     filter = graph->filters[0];
    1436    19718459 :     for (i = 1; i < graph->nb_filters; i++)
    1437    15640050 :         if (graph->filters[i]->ready > filter->ready)
    1438     2576143 :             filter = graph->filters[i];
    1439     4078409 :     if (!filter->ready)
    1440      391883 :         return AVERROR(EAGAIN);
    1441     3686526 :     return ff_filter_activate(filter);
    1442             : }

Generated by: LCOV version 1.12