static int configure_audio_filters(FilterGraph *fg, AVFilterContext **in_filter,
                                   AVFilterContext **out_filter)
{
    InputStream  *ist = fg->inputs[0]->ist;
    OutputStream *ost = fg->outputs[0]->ost;
    AVCodecContext *codec  = ost->st->codec;
    AVCodecContext *icodec = ist->st->codec;
    char *sample_fmts, *sample_rates, *channel_layouts;
    char args[256];
    int ret;

    avfilter_graph_free(&fg->graph);
    if (!(fg->graph = avfilter_graph_alloc()))
        return AVERROR(ENOMEM);

    snprintf(args, sizeof(args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:"
             "channel_layout=0x%"PRIx64, ist->st->time_base.num,
             ist->st->time_base.den, icodec->sample_rate,
             av_get_sample_fmt_name(icodec->sample_fmt), icodec->channel_layout);
    ret = avfilter_graph_create_filter(&fg->inputs[0]->filter,
                                       avfilter_get_by_name("abuffer"),
                                       "src", args, NULL, fg->graph);
    if (ret < 0)
        return ret;

    ret = avfilter_graph_create_filter(&fg->outputs[0]->filter,
                                       avfilter_get_by_name("abuffersink"),
                                       "out", NULL, NULL, fg->graph);
    if (ret < 0)
        return ret;

    *in_filter  = fg->inputs[0]->filter;
    *out_filter = fg->outputs[0]->filter;

    if (codec->channels && !codec->channel_layout)
        codec->channel_layout = av_get_default_channel_layout(codec->channels);

    sample_fmts     = choose_sample_fmts(ost);
    sample_rates    = choose_sample_rates(ost);
    channel_layouts = choose_channel_layouts(ost);
    if (sample_fmts || sample_rates || channel_layouts) {
        AVFilterContext *format;
        char args[256];
        int len = 0;

        if (sample_fmts)
            len += snprintf(args + len, sizeof(args) - len, "sample_fmts=%s:",
                            sample_fmts);
        if (sample_rates)
            len += snprintf(args + len, sizeof(args) - len, "sample_rates=%s:",
                            sample_rates);
        if (channel_layouts)
            len += snprintf(args + len, sizeof(args) - len, "channel_layouts=%s:",
                            channel_layouts);
        args[len - 1] = 0;

        av_freep(&sample_fmts);
        av_freep(&sample_rates);
        av_freep(&channel_layouts);

        ret = avfilter_graph_create_filter(&format,
                                           avfilter_get_by_name("aformat"),
                                           "aformat", args, NULL, fg->graph);
        if (ret < 0)
            return ret;

        ret = avfilter_link(format, 0, fg->outputs[0]->filter, 0);
        if (ret < 0)
            return ret;

        *out_filter = format;
    }

    return 0;
}