+static int filter_query_formats(AVFilterContext *ctx)
+{
+ int ret;
+ AVFilterFormats *formats;
+ AVFilterChannelLayouts *chlayouts;
+ AVFilterFormats *samplerates;
+ enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
+ ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
+ AVMEDIA_TYPE_VIDEO;
+
+ if ((ret = ctx->filter->query_formats(ctx)) < 0)
+ return ret;
+
+ formats = ff_all_formats(type);
+ if (!formats)
+ return AVERROR(ENOMEM);
+ ff_set_common_formats(ctx, formats);
+ if (type == AVMEDIA_TYPE_AUDIO) {
+ samplerates = ff_all_samplerates();
+ if (!samplerates)
+ return AVERROR(ENOMEM);
+ ff_set_common_samplerates(ctx, samplerates);
+ chlayouts = ff_all_channel_layouts();
+ if (!chlayouts)
+ return AVERROR(ENOMEM);
+ ff_set_common_channel_layouts(ctx, chlayouts);
+ }
+ return 0;
+}
+
+static int insert_conv_filter(AVFilterGraph *graph, AVFilterLink *link,
+ const char *filt_name, const char *filt_args)
+{
+ static int auto_count = 0, ret;
+ char inst_name[32];
+ AVFilterContext *filt_ctx;
+
+ if (graph->disable_auto_convert) {
+ av_log(NULL, AV_LOG_ERROR,
+ "The filters '%s' and '%s' do not have a common format "
+ "and automatic conversion is disabled.\n",
+ link->src->name, link->dst->name);
+ return AVERROR(EINVAL);
+ }
+
+ snprintf(inst_name, sizeof(inst_name), "auto-inserted %s %d",
+ filt_name, auto_count++);
+
+ if ((ret = avfilter_graph_create_filter(&filt_ctx,
+ avfilter_get_by_name(filt_name),
+ inst_name, filt_args, NULL, graph)) < 0)
+ return ret;
+ if ((ret = avfilter_insert_filter(link, filt_ctx, 0, 0)) < 0)
+ return ret;
+
+ filter_query_formats(filt_ctx);
+
+ if ( ((link = filt_ctx-> inputs[0]) &&
+ !ff_merge_formats(link->in_formats, link->out_formats)) ||
+ ((link = filt_ctx->outputs[0]) &&
+ !ff_merge_formats(link->in_formats, link->out_formats))
+ ) {
+ av_log(NULL, 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 AVERROR(EINVAL);
+ }
+
+ if (link->type == AVMEDIA_TYPE_AUDIO &&
+ (((link = filt_ctx-> inputs[0]) &&
+ !ff_merge_channel_layouts(link->in_channel_layouts, link->out_channel_layouts)) ||
+ ((link = filt_ctx->outputs[0]) &&
+ !ff_merge_channel_layouts(link->in_channel_layouts, link->out_channel_layouts)))
+ ) {
+ av_log(NULL, AV_LOG_ERROR,
+ "Impossible to convert between the channel layouts formats supported by the filter "
+ "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
+ return AVERROR(EINVAL);
+ }
+
+ return 0;
+}
+