+ int i, j;
+ int scaler_count = 0;
+ char inst_name[30];
+
+ /* ask all the sub-filters for their supported media formats */
+ for(i = 0; i < graph->filter_count; i ++) {
+ if(graph->filters[i]->filter->query_formats)
+ graph->filters[i]->filter->query_formats(graph->filters[i]);
+ else
+ avfilter_default_query_formats(graph->filters[i]);
+ }
+
+ /* go through and merge as many format lists as possible */
+ for(i = 0; i < graph->filter_count; i ++) {
+ AVFilterContext *filter = graph->filters[i];
+
+ for(j = 0; j < filter->input_count; j ++) {
+ AVFilterLink *link = filter->inputs[j];
+ if(link && link->in_formats != link->out_formats) {
+ if(!avfilter_merge_formats(link->in_formats,
+ link->out_formats)) {
+ AVFilterContext *scale;
+ char scale_args[256];
+ /* couldn't merge format lists. auto-insert scale filter */
+ snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
+ scaler_count++);
+ avfilter_open(&scale, avfilter_get_by_name("scale"), inst_name);
+
+ snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts);
+ if(!scale || scale->filter->init(scale, scale_args, NULL) ||
+ avfilter_insert_filter(link, scale, 0, 0)) {
+ avfilter_destroy(scale);
+ return -1;
+ }
+
+ if (avfilter_graph_add_filter(graph, scale) < 0)
+ return -1;
+
+ scale->filter->query_formats(scale);
+ if (((link = scale-> inputs[0]) &&
+ !avfilter_merge_formats(link->in_formats, link->out_formats)) ||
+ ((link = scale->outputs[0]) &&
+ !avfilter_merge_formats(link->in_formats, link->out_formats))) {
+ 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 -1;
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void pick_format(AVFilterLink *link)
+{
+ if(!link || !link->in_formats)
+ return;
+
+ link->in_formats->format_count = 1;
+ link->format = link->in_formats->formats[0];
+
+ avfilter_formats_unref(&link->in_formats);
+ avfilter_formats_unref(&link->out_formats);
+}
+
+static void pick_formats(AVFilterGraph *graph)
+{
+ int i, j;
+
+ for(i = 0; i < graph->filter_count; i ++) {
+ AVFilterContext *filter = graph->filters[i];
+
+ for(j = 0; j < filter->input_count; j ++)
+ pick_format(filter->inputs[j]);
+ for(j = 0; j < filter->output_count; j ++)
+ pick_format(filter->outputs[j]);
+ }