avfiltergraph.c 27.4 KB
Newer Older
1
/*
2
 * filter graphs
3 4
 * Copyright (c) 2008 Vitor Sessak
 * 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 10 11 12
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
13
 * Libav is distributed in the hope that it will be useful,
14 15 16 17 18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * 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 21 22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

23 24
#include "config.h"

25 26
#include <string.h>

27
#include "libavutil/avassert.h"
28
#include "libavutil/avstring.h"
29 30 31
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/log.h"
32 33
#include "libavutil/opt.h"

34
#include "avfilter.h"
35
#include "formats.h"
36
#include "internal.h"
37 38 39 40 41 42 43 44 45 46 47 48
#include "thread.h"

#define OFFSET(x) offsetof(AVFilterGraph, x)
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
static const AVOption filtergraph_options[] = {
    { "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,
        { .i64 = AVFILTER_THREAD_SLICE }, 0, INT_MAX, FLAGS, "thread_type" },
        { "slice", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVFILTER_THREAD_SLICE }, .flags = FLAGS, .unit = "thread_type" },
    { "threads",     "Maximum number of threads", OFFSET(nb_threads),
        AV_OPT_TYPE_INT,   { .i64 = 0 }, 0, INT_MAX, FLAGS },
    { NULL },
};
49

50 51 52 53
static const AVClass filtergraph_class = {
    .class_name = "AVFilterGraph",
    .item_name  = av_default_item_name,
    .version    = LIBAVUTIL_VERSION_INT,
54
    .option     = filtergraph_options,
55 56
};

57 58 59 60 61 62 63 64 65 66 67 68 69
#if !HAVE_THREADS
void ff_graph_thread_free(AVFilterGraph *graph)
{
}

int ff_graph_thread_init(AVFilterGraph *graph)
{
    graph->thread_type = 0;
    graph->nb_threads  = 1;
    return 0;
}
#endif

70 71
AVFilterGraph *avfilter_graph_alloc(void)
{
72
    AVFilterGraph *ret = av_mallocz(sizeof(*ret));
73 74
    if (!ret)
        return NULL;
75 76 77 78 79 80 81

    ret->internal = av_mallocz(sizeof(*ret->internal));
    if (!ret->internal) {
        av_freep(&ret);
        return NULL;
    }

82
    ret->av_class = &filtergraph_class;
83 84
    av_opt_set_defaults(ret);

85
    return ret;
86 87
}

88 89 90 91 92 93 94 95 96 97 98 99 100
void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter)
{
    int i;
    for (i = 0; i < graph->nb_filters; i++) {
        if (graph->filters[i] == filter) {
            FFSWAP(AVFilterContext*, graph->filters[i],
                   graph->filters[graph->nb_filters - 1]);
            graph->nb_filters--;
            return;
        }
    }
}

101
void avfilter_graph_free(AVFilterGraph **graph)
Vitor Sessak's avatar
Vitor Sessak committed
102
{
103
    if (!*graph)
104
        return;
105 106 107 108

    while ((*graph)->nb_filters)
        avfilter_free((*graph)->filters[0]);

109 110
    ff_graph_thread_free(*graph);

111
    av_freep(&(*graph)->scale_sws_opts);
112
    av_freep(&(*graph)->resample_lavr_opts);
113
    av_freep(&(*graph)->filters);
114
    av_freep(&(*graph)->internal);
115
    av_freep(graph);
116 117
}

118
#if FF_API_AVFILTER_OPEN
Vitor Sessak's avatar
Vitor Sessak committed
119
int avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)
120
{
121
    AVFilterContext **filters = av_realloc(graph->filters,
122
                                           sizeof(*filters) * (graph->nb_filters + 1));
123
    if (!filters)
124
        return AVERROR(ENOMEM);
Vitor Sessak's avatar
Vitor Sessak committed
125

126
    graph->filters = filters;
127
    graph->filters[graph->nb_filters++] = filter;
Vitor Sessak's avatar
Vitor Sessak committed
128

129 130 131 132
#if FF_API_FOO_COUNT
    graph->filter_count = graph->nb_filters;
#endif

133 134
    filter->graph = graph;

Vitor Sessak's avatar
Vitor Sessak committed
135
    return 0;
136
}
137
#endif
138

139 140 141 142 143 144
int avfilter_graph_create_filter(AVFilterContext **filt_ctx, AVFilter *filt,
                                 const char *name, const char *args, void *opaque,
                                 AVFilterGraph *graph_ctx)
{
    int ret;

145 146 147
    *filt_ctx = avfilter_graph_alloc_filter(graph_ctx, filt, name);
    if (!*filt_ctx)
        return AVERROR(ENOMEM);
148 149 150

    ret = avfilter_init_str(*filt_ctx, args);
    if (ret < 0)
151
        goto fail;
152

153 154 155 156 157 158 159 160 161
    return 0;

fail:
    if (*filt_ctx)
        avfilter_free(*filt_ctx);
    *filt_ctx = NULL;
    return ret;
}

162 163 164 165 166 167
AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph,
                                             const AVFilter *filter,
                                             const char *name)
{
    AVFilterContext **filters, *s;

168 169 170 171 172 173 174 175
    if (graph->thread_type && !graph->internal->thread) {
        int ret = ff_graph_thread_init(graph);
        if (ret < 0) {
            av_log(graph, AV_LOG_ERROR, "Error initializing threading.\n");
            return NULL;
        }
    }

176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
    s = ff_filter_alloc(filter, name);
    if (!s)
        return NULL;

    filters = av_realloc(graph->filters, sizeof(*filters) * (graph->nb_filters + 1));
    if (!filters) {
        avfilter_free(s);
        return NULL;
    }

    graph->filters = filters;
    graph->filters[graph->nb_filters++] = s;

#if FF_API_FOO_COUNT
    graph->filter_count = graph->nb_filters;
#endif

193 194
    s->graph = graph;

195 196 197
    return s;
}

198 199 200 201 202 203 204 205 206
/**
 * Check for the validity of graph.
 *
 * A graph is considered valid if all its input and output pads are
 * connected.
 *
 * @return 0 in case of success, a negative value otherwise
 */
static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
207 208 209 210
{
    AVFilterContext *filt;
    int i, j;

211
    for (i = 0; i < graph->nb_filters; i++) {
212 213
        filt = graph->filters[i];

214
        for (j = 0; j < filt->nb_inputs; j++) {
215 216 217 218
            if (!filt->inputs[j] || !filt->inputs[j]->src) {
                av_log(log_ctx, AV_LOG_ERROR,
                       "Input pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any source\n",
                       filt->input_pads[j].name, filt->name, filt->filter->name);
219
                return AVERROR(EINVAL);
220 221 222
            }
        }

223
        for (j = 0; j < filt->nb_outputs; j++) {
224 225 226 227
            if (!filt->outputs[j] || !filt->outputs[j]->dst) {
                av_log(log_ctx, AV_LOG_ERROR,
                       "Output pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any destination\n",
                       filt->output_pads[j].name, filt->name, filt->filter->name);
228
                return AVERROR(EINVAL);
229 230 231 232 233 234 235
            }
        }
    }

    return 0;
}

236 237 238 239 240 241
/**
 * Configure all the links of graphctx.
 *
 * @return 0 in case of success, a negative value otherwise
 */
static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
242 243 244 245
{
    AVFilterContext *filt;
    int i, ret;

246
    for (i = 0; i < graph->nb_filters; i++) {
247 248
        filt = graph->filters[i];

249
        if (!filt->nb_outputs) {
250 251 252 253 254 255 256 257
            if ((ret = avfilter_config_links(filt)))
                return ret;
        }
    }

    return 0;
}

258
AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name)
259 260 261
{
    int i;

262
    for (i = 0; i < graph->nb_filters; i++)
263
        if (graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
264 265 266 267 268
            return graph->filters[i];

    return NULL;
}

269
static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
Vitor Sessak's avatar
Vitor Sessak committed
270
{
271
    int i, j, ret;
272
    int scaler_count = 0, resampler_count = 0;
Vitor Sessak's avatar
Vitor Sessak committed
273

274
    /* ask all the sub-filters for their supported media formats */
275
    for (i = 0; i < graph->nb_filters; i++) {
276
        if (graph->filters[i]->filter->query_formats)
Vitor Sessak's avatar
Vitor Sessak committed
277 278
            graph->filters[i]->filter->query_formats(graph->filters[i]);
        else
279
            ff_default_query_formats(graph->filters[i]);
Vitor Sessak's avatar
Vitor Sessak committed
280 281 282
    }

    /* go through and merge as many format lists as possible */
283
    for (i = 0; i < graph->nb_filters; i++) {
Vitor Sessak's avatar
Vitor Sessak committed
284 285
        AVFilterContext *filter = graph->filters[i];

286
        for (j = 0; j < filter->nb_inputs; j++) {
Vitor Sessak's avatar
Vitor Sessak committed
287
            AVFilterLink *link = filter->inputs[j];
288 289 290 291 292 293
            int convert_needed = 0;

            if (!link)
                continue;

            if (link->in_formats != link->out_formats &&
294
                !ff_merge_formats(link->in_formats,
295 296 297 298 299 300 301 302 303 304 305 306 307 308
                                        link->out_formats))
                convert_needed = 1;
            if (link->type == AVMEDIA_TYPE_AUDIO) {
                if (link->in_channel_layouts != link->out_channel_layouts &&
                    !ff_merge_channel_layouts(link->in_channel_layouts,
                                              link->out_channel_layouts))
                    convert_needed = 1;
                if (link->in_samplerates != link->out_samplerates &&
                    !ff_merge_samplerates(link->in_samplerates,
                                          link->out_samplerates))
                    convert_needed = 1;
            }

            if (convert_needed) {
Anton Khirnov's avatar
Anton Khirnov committed
309 310 311 312 313 314 315 316 317
                AVFilterContext *convert;
                AVFilter *filter;
                AVFilterLink *inlink, *outlink;
                char scale_args[256];
                char inst_name[30];

                /* couldn't merge format lists. auto-insert conversion filter */
                switch (link->type) {
                case AVMEDIA_TYPE_VIDEO:
318 319 320 321 322 323
                    if (!(filter = avfilter_get_by_name("scale"))) {
                        av_log(log_ctx, AV_LOG_ERROR, "'scale' filter "
                               "not present, cannot convert pixel formats.\n");
                        return AVERROR(EINVAL);
                    }

Anton Khirnov's avatar
Anton Khirnov committed
324 325
                    snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
                             scaler_count++);
326

327
                    if ((ret = avfilter_graph_create_filter(&convert, filter,
328
                                                            inst_name, graph->scale_sws_opts, NULL,
Anton Khirnov's avatar
Anton Khirnov committed
329 330 331 332 333 334 335
                                                            graph)) < 0)
                        return ret;
                    break;
                case AVMEDIA_TYPE_AUDIO:
                    if (!(filter = avfilter_get_by_name("resample"))) {
                        av_log(log_ctx, AV_LOG_ERROR, "'resample' filter "
                               "not present, cannot convert audio formats.\n");
336 337 338
                        return AVERROR(EINVAL);
                    }

Anton Khirnov's avatar
Anton Khirnov committed
339 340
                    snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d",
                             resampler_count++);
341 342 343 344
                    scale_args[0] = '\0';
                    if (graph->resample_lavr_opts)
                        snprintf(scale_args, sizeof(scale_args), "%s",
                                 graph->resample_lavr_opts);
345
                    if ((ret = avfilter_graph_create_filter(&convert, filter,
346 347
                                                            inst_name, scale_args,
                                                            NULL, graph)) < 0)
348
                        return ret;
Anton Khirnov's avatar
Anton Khirnov committed
349 350 351 352 353 354 355 356 357 358 359
                    break;
                default:
                    return AVERROR(EINVAL);
                }

                if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
                    return ret;

                convert->filter->query_formats(convert);
                inlink  = convert->inputs[0];
                outlink = convert->outputs[0];
360 361
                if (!ff_merge_formats( inlink->in_formats,  inlink->out_formats) ||
                    !ff_merge_formats(outlink->in_formats, outlink->out_formats))
Anton Khirnov's avatar
Anton Khirnov committed
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
                    ret |= AVERROR(ENOSYS);
                if (inlink->type == AVMEDIA_TYPE_AUDIO &&
                    (!ff_merge_samplerates(inlink->in_samplerates,
                                           inlink->out_samplerates) ||
                     !ff_merge_channel_layouts(inlink->in_channel_layouts,
                                               inlink->out_channel_layouts)))
                    ret |= AVERROR(ENOSYS);
                if (outlink->type == AVMEDIA_TYPE_AUDIO &&
                    (!ff_merge_samplerates(outlink->in_samplerates,
                                           outlink->out_samplerates) ||
                     !ff_merge_channel_layouts(outlink->in_channel_layouts,
                                               outlink->out_channel_layouts)))
                    ret |= AVERROR(ENOSYS);

                if (ret < 0) {
                    av_log(log_ctx, AV_LOG_ERROR,
                           "Impossible to convert between the formats supported by the filter "
                           "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
                    return ret;
                }
Vitor Sessak's avatar
Vitor Sessak committed
382 383 384 385 386 387 388
            }
        }
    }

    return 0;
}

389
static int pick_format(AVFilterLink *link)
Vitor Sessak's avatar
Vitor Sessak committed
390
{
391
    if (!link || !link->in_formats)
392
        return 0;
Vitor Sessak's avatar
Vitor Sessak committed
393

394
    link->in_formats->nb_formats = 1;
Vitor Sessak's avatar
Vitor Sessak committed
395 396
    link->format = link->in_formats->formats[0];

397
    if (link->type == AVMEDIA_TYPE_AUDIO) {
398
        if (!link->in_samplerates->nb_formats) {
399 400 401 402 403
            av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
                   " the link between filters %s and %s.\n", link->src->name,
                   link->dst->name);
            return AVERROR(EINVAL);
        }
404
        link->in_samplerates->nb_formats = 1;
405 406 407 408 409 410 411 412 413 414 415 416
        link->sample_rate = link->in_samplerates->formats[0];

        if (!link->in_channel_layouts->nb_channel_layouts) {
            av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
                   "the link between filters %s and %s.\n", link->src->name,
                   link->dst->name);
            return AVERROR(EINVAL);
        }
        link->in_channel_layouts->nb_channel_layouts = 1;
        link->channel_layout = link->in_channel_layouts->channel_layouts[0];
    }

417 418 419 420
    ff_formats_unref(&link->in_formats);
    ff_formats_unref(&link->out_formats);
    ff_formats_unref(&link->in_samplerates);
    ff_formats_unref(&link->out_samplerates);
421 422 423 424
    ff_channel_layouts_unref(&link->in_channel_layouts);
    ff_channel_layouts_unref(&link->out_channel_layouts);

    return 0;
Vitor Sessak's avatar
Vitor Sessak committed
425 426
}

427 428
#define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format) \
do {                                                                   \
429
    for (i = 0; i < filter->nb_inputs; i++) {                          \
430 431 432 433 434 435 436
        AVFilterLink *link = filter->inputs[i];                        \
        fmt_type fmt;                                                  \
                                                                       \
        if (!link->out_ ## list || link->out_ ## list->nb != 1)        \
            continue;                                                  \
        fmt = link->out_ ## list->var[0];                              \
                                                                       \
437
        for (j = 0; j < filter->nb_outputs; j++) {                     \
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
            AVFilterLink *out_link = filter->outputs[j];               \
            list_type *fmts;                                           \
                                                                       \
            if (link->type != out_link->type ||                        \
                out_link->in_ ## list->nb == 1)                        \
                continue;                                              \
            fmts = out_link->in_ ## list;                              \
                                                                       \
            if (!out_link->in_ ## list->nb) {                          \
                add_format(&out_link->in_ ##list, fmt);                \
                break;                                                 \
            }                                                          \
                                                                       \
            for (k = 0; k < out_link->in_ ## list->nb; k++)            \
                if (fmts->var[k] == fmt) {                             \
                    fmts->var[0]  = fmt;                               \
                    fmts->nb = 1;                                      \
                    ret = 1;                                           \
                    break;                                             \
                }                                                      \
        }                                                              \
    }                                                                  \
} while (0)

462 463 464 465
static int reduce_formats_on_filter(AVFilterContext *filter)
{
    int i, j, k, ret = 0;

466
    REDUCE_FORMATS(int,      AVFilterFormats,        formats,         formats,
467
                   nb_formats, ff_add_format);
468
    REDUCE_FORMATS(int,      AVFilterFormats,        samplerates,     formats,
469
                   nb_formats, ff_add_format);
470 471
    REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts,
                   channel_layouts, nb_channel_layouts, ff_add_channel_layout);
472 473 474 475 476 477 478 479 480 481 482

    return ret;
}

static void reduce_formats(AVFilterGraph *graph)
{
    int i, reduced;

    do {
        reduced = 0;

483
        for (i = 0; i < graph->nb_filters; i++)
484 485 486 487
            reduced |= reduce_formats_on_filter(graph->filters[i]);
    } while (reduced);
}

488 489 490 491 492 493
static void swap_samplerates_on_filter(AVFilterContext *filter)
{
    AVFilterLink *link = NULL;
    int sample_rate;
    int i, j;

494
    for (i = 0; i < filter->nb_inputs; i++) {
495 496 497
        link = filter->inputs[i];

        if (link->type == AVMEDIA_TYPE_AUDIO &&
498
            link->out_samplerates->nb_formats== 1)
499 500
            break;
    }
501
    if (i == filter->nb_inputs)
502 503 504 505
        return;

    sample_rate = link->out_samplerates->formats[0];

506
    for (i = 0; i < filter->nb_outputs; i++) {
507 508 509 510
        AVFilterLink *outlink = filter->outputs[i];
        int best_idx, best_diff = INT_MAX;

        if (outlink->type != AVMEDIA_TYPE_AUDIO ||
511
            outlink->in_samplerates->nb_formats < 2)
512 513
            continue;

514
        for (j = 0; j < outlink->in_samplerates->nb_formats; j++) {
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530
            int diff = abs(sample_rate - outlink->in_samplerates->formats[j]);

            if (diff < best_diff) {
                best_diff = diff;
                best_idx  = j;
            }
        }
        FFSWAP(int, outlink->in_samplerates->formats[0],
               outlink->in_samplerates->formats[best_idx]);
    }
}

static void swap_samplerates(AVFilterGraph *graph)
{
    int i;

531
    for (i = 0; i < graph->nb_filters; i++)
532 533 534
        swap_samplerates_on_filter(graph->filters[i]);
}

535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568
#define CH_CENTER_PAIR (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)
#define CH_FRONT_PAIR  (AV_CH_FRONT_LEFT           | AV_CH_FRONT_RIGHT)
#define CH_STEREO_PAIR (AV_CH_STEREO_LEFT          | AV_CH_STEREO_RIGHT)
#define CH_WIDE_PAIR   (AV_CH_WIDE_LEFT            | AV_CH_WIDE_RIGHT)
#define CH_SIDE_PAIR   (AV_CH_SIDE_LEFT            | AV_CH_SIDE_RIGHT)
#define CH_DIRECT_PAIR (AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT)
#define CH_BACK_PAIR   (AV_CH_BACK_LEFT            | AV_CH_BACK_RIGHT)

/* allowable substitutions for channel pairs when comparing layouts,
 * ordered by priority for both values */
static const uint64_t ch_subst[][2] = {
    { CH_FRONT_PAIR,      CH_CENTER_PAIR     },
    { CH_FRONT_PAIR,      CH_WIDE_PAIR       },
    { CH_FRONT_PAIR,      AV_CH_FRONT_CENTER },
    { CH_CENTER_PAIR,     CH_FRONT_PAIR      },
    { CH_CENTER_PAIR,     CH_WIDE_PAIR       },
    { CH_CENTER_PAIR,     AV_CH_FRONT_CENTER },
    { CH_WIDE_PAIR,       CH_FRONT_PAIR      },
    { CH_WIDE_PAIR,       CH_CENTER_PAIR     },
    { CH_WIDE_PAIR,       AV_CH_FRONT_CENTER },
    { AV_CH_FRONT_CENTER, CH_FRONT_PAIR      },
    { AV_CH_FRONT_CENTER, CH_CENTER_PAIR     },
    { AV_CH_FRONT_CENTER, CH_WIDE_PAIR       },
    { CH_SIDE_PAIR,       CH_DIRECT_PAIR     },
    { CH_SIDE_PAIR,       CH_BACK_PAIR       },
    { CH_SIDE_PAIR,       AV_CH_BACK_CENTER  },
    { CH_BACK_PAIR,       CH_DIRECT_PAIR     },
    { CH_BACK_PAIR,       CH_SIDE_PAIR       },
    { CH_BACK_PAIR,       AV_CH_BACK_CENTER  },
    { AV_CH_BACK_CENTER,  CH_BACK_PAIR       },
    { AV_CH_BACK_CENTER,  CH_DIRECT_PAIR     },
    { AV_CH_BACK_CENTER,  CH_SIDE_PAIR       },
};

569
static void swap_channel_layouts_on_filter(AVFilterContext *filter)
Vitor Sessak's avatar
Vitor Sessak committed
570
{
571
    AVFilterLink *link = NULL;
572
    int i, j, k;
Vitor Sessak's avatar
Vitor Sessak committed
573

574
    for (i = 0; i < filter->nb_inputs; i++) {
575 576 577 578 579 580
        link = filter->inputs[i];

        if (link->type == AVMEDIA_TYPE_AUDIO &&
            link->out_channel_layouts->nb_channel_layouts == 1)
            break;
    }
581
    if (i == filter->nb_inputs)
582 583
        return;

584
    for (i = 0; i < filter->nb_outputs; i++) {
585
        AVFilterLink *outlink = filter->outputs[i];
586
        int best_idx = -1, best_score = INT_MIN, best_count_diff = INT_MAX;
587 588 589 590 591 592

        if (outlink->type != AVMEDIA_TYPE_AUDIO ||
            outlink->in_channel_layouts->nb_channel_layouts < 2)
            continue;

        for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts; j++) {
593
            uint64_t  in_chlayout = link->out_channel_layouts->channel_layouts[0];
594
            uint64_t out_chlayout = outlink->in_channel_layouts->channel_layouts[j];
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
            int  in_channels      = av_get_channel_layout_nb_channels(in_chlayout);
            int out_channels      = av_get_channel_layout_nb_channels(out_chlayout);
            int count_diff        = out_channels - in_channels;
            int matched_channels, extra_channels;
            int score = 0;

            /* channel substitution */
            for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) {
                uint64_t cmp0 = ch_subst[k][0];
                uint64_t cmp1 = ch_subst[k][1];
                if (( in_chlayout & cmp0) && (!(out_chlayout & cmp0)) &&
                    (out_chlayout & cmp1) && (!( in_chlayout & cmp1))) {
                    in_chlayout  &= ~cmp0;
                    out_chlayout &= ~cmp1;
                    /* add score for channel match, minus a deduction for
                       having to do the substitution */
                    score += 10 * av_get_channel_layout_nb_channels(cmp1) - 2;
                }
            }
614

615 616 617 618 619 620 621 622 623 624 625 626 627 628 629
            /* no penalty for LFE channel mismatch */
            if ( (in_chlayout & AV_CH_LOW_FREQUENCY) &&
                (out_chlayout & AV_CH_LOW_FREQUENCY))
                score += 10;
            in_chlayout  &= ~AV_CH_LOW_FREQUENCY;
            out_chlayout &= ~AV_CH_LOW_FREQUENCY;

            matched_channels = av_get_channel_layout_nb_channels(in_chlayout &
                                                                 out_chlayout);
            extra_channels   = av_get_channel_layout_nb_channels(out_chlayout &
                                                                 (~in_chlayout));
            score += 10 * matched_channels - 5 * extra_channels;

            if (score > best_score ||
                (count_diff < best_count_diff && score == best_score)) {
630 631
                best_score = score;
                best_idx   = j;
632
                best_count_diff = count_diff;
633 634
            }
        }
635
        av_assert0(best_idx >= 0);
636 637 638 639 640 641 642 643 644 645
        FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0],
               outlink->in_channel_layouts->channel_layouts[best_idx]);
    }

}

static void swap_channel_layouts(AVFilterGraph *graph)
{
    int i;

646
    for (i = 0; i < graph->nb_filters; i++)
647 648 649
        swap_channel_layouts_on_filter(graph->filters[i]);
}

650 651 652 653 654 655
static void swap_sample_fmts_on_filter(AVFilterContext *filter)
{
    AVFilterLink *link = NULL;
    int format, bps;
    int i, j;

656
    for (i = 0; i < filter->nb_inputs; i++) {
657 658 659
        link = filter->inputs[i];

        if (link->type == AVMEDIA_TYPE_AUDIO &&
660
            link->out_formats->nb_formats == 1)
661 662
            break;
    }
663
    if (i == filter->nb_inputs)
664 665 666 667 668
        return;

    format = link->out_formats->formats[0];
    bps    = av_get_bytes_per_sample(format);

669
    for (i = 0; i < filter->nb_outputs; i++) {
670
        AVFilterLink *outlink = filter->outputs[i];
671
        int best_idx = -1, best_score = INT_MIN;
672 673

        if (outlink->type != AVMEDIA_TYPE_AUDIO ||
674
            outlink->in_formats->nb_formats < 2)
675 676
            continue;

677
        for (j = 0; j < outlink->in_formats->nb_formats; j++) {
678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703
            int out_format = outlink->in_formats->formats[j];
            int out_bps    = av_get_bytes_per_sample(out_format);
            int score;

            if (av_get_packed_sample_fmt(out_format) == format ||
                av_get_planar_sample_fmt(out_format) == format) {
                best_idx   = j;
                break;
            }

            /* for s32 and float prefer double to prevent loss of information */
            if (bps == 4 && out_bps == 8) {
                best_idx = j;
                break;
            }

            /* prefer closest higher or equal bps */
            score = -abs(out_bps - bps);
            if (out_bps >= bps)
                score += INT_MAX/2;

            if (score > best_score) {
                best_score = score;
                best_idx   = j;
            }
        }
704
        av_assert0(best_idx >= 0);
705 706 707 708 709 710 711 712 713
        FFSWAP(int, outlink->in_formats->formats[0],
               outlink->in_formats->formats[best_idx]);
    }
}

static void swap_sample_fmts(AVFilterGraph *graph)
{
    int i;

714
    for (i = 0; i < graph->nb_filters; i++)
715 716 717 718
        swap_sample_fmts_on_filter(graph->filters[i]);

}

719 720 721 722
static int pick_formats(AVFilterGraph *graph)
{
    int i, j, ret;

723
    for (i = 0; i < graph->nb_filters; i++) {
Vitor Sessak's avatar
Vitor Sessak committed
724 725
        AVFilterContext *filter = graph->filters[i];

726
        for (j = 0; j < filter->nb_inputs; j++)
727 728
            if ((ret = pick_format(filter->inputs[j])) < 0)
                return ret;
729
        for (j = 0; j < filter->nb_outputs; j++)
730 731
            if ((ret = pick_format(filter->outputs[j])) < 0)
                return ret;
Vitor Sessak's avatar
Vitor Sessak committed
732
    }
733
    return 0;
Vitor Sessak's avatar
Vitor Sessak committed
734 735
}

736 737 738 739
/**
 * Configure the formats of all the links in the graph.
 */
static int graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
Vitor Sessak's avatar
Vitor Sessak committed
740
{
741 742
    int ret;

743
    /* find supported formats from sub-filters, and merge along links */
744 745
    if ((ret = query_formats(graph, log_ctx)) < 0)
        return ret;
Vitor Sessak's avatar
Vitor Sessak committed
746 747

    /* Once everything is merged, it's possible that we'll still have
748 749 750 751
     * multiple valid media format choices. We try to minimize the amount
     * of format conversion inside filters */
    reduce_formats(graph);

752
    /* for audio filters, ensure the best format, sample rate and channel layout
753
     * is selected */
754
    swap_sample_fmts(graph);
755 756 757 758 759
    swap_samplerates(graph);
    swap_channel_layouts(graph);

    if ((ret = pick_formats(graph)) < 0)
        return ret;
Vitor Sessak's avatar
Vitor Sessak committed
760 761 762 763

    return 0;
}

764 765 766 767 768 769
static int graph_insert_fifos(AVFilterGraph *graph, AVClass *log_ctx)
{
    AVFilterContext *f;
    int i, j, ret;
    int fifo_count = 0;

770
    for (i = 0; i < graph->nb_filters; i++) {
771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801
        f = graph->filters[i];

        for (j = 0; j < f->nb_inputs; j++) {
            AVFilterLink *link = f->inputs[j];
            AVFilterContext *fifo_ctx;
            AVFilter *fifo;
            char name[32];

            if (!link->dstpad->needs_fifo)
                continue;

            fifo = f->inputs[j]->type == AVMEDIA_TYPE_VIDEO ?
                   avfilter_get_by_name("fifo") :
                   avfilter_get_by_name("afifo");

            snprintf(name, sizeof(name), "auto-inserted fifo %d", fifo_count++);

            ret = avfilter_graph_create_filter(&fifo_ctx, fifo, name, NULL,
                                               NULL, graph);
            if (ret < 0)
                return ret;

            ret = avfilter_insert_filter(link, fifo_ctx, 0, 0);
            if (ret < 0)
                return ret;
        }
    }

    return 0;
}

802
int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
803 804 805
{
    int ret;

806
    if ((ret = graph_check_validity(graphctx, log_ctx)))
807
        return ret;
808 809
    if ((ret = graph_insert_fifos(graphctx, log_ctx)) < 0)
        return ret;
810
    if ((ret = graph_config_formats(graphctx, log_ctx)))
811
        return ret;
812
    if ((ret = graph_config_links(graphctx, log_ctx)))
813 814 815 816
        return ret;

    return 0;
}