Merge remote-tracking branch 'qatar/master'
[ffmpeg.git] / libavfilter / avfiltergraph.c
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 <ctype.h>
24 #include <string.h>
25
26 #include "libavutil/audioconvert.h"
27 #include "libavutil/avassert.h"
28 #include "libavutil/pixdesc.h"
29 #include "avfilter.h"
30 #include "avfiltergraph.h"
31 #include "formats.h"
32 #include "internal.h"
33
34 #include "libavutil/audioconvert.h"
35 #include "libavutil/log.h"
36
37 static const AVClass filtergraph_class = {
38     .class_name = "AVFilterGraph",
39     .item_name  = av_default_item_name,
40     .version    = LIBAVUTIL_VERSION_INT,
41 };
42
43 AVFilterGraph *avfilter_graph_alloc(void)
44 {
45     AVFilterGraph *ret = av_mallocz(sizeof(AVFilterGraph));
46     if (!ret)
47         return NULL;
48 #if FF_API_GRAPH_AVCLASS
49     ret->av_class = &filtergraph_class;
50 #endif
51     return ret;
52 }
53
54 void avfilter_graph_free(AVFilterGraph **graph)
55 {
56     if (!*graph)
57         return;
58     for (; (*graph)->filter_count > 0; (*graph)->filter_count--)
59         avfilter_free((*graph)->filters[(*graph)->filter_count - 1]);
60     av_freep(&(*graph)->sink_links);
61     av_freep(&(*graph)->scale_sws_opts);
62     av_freep(&(*graph)->filters);
63     av_freep(graph);
64 }
65
66 int avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)
67 {
68     AVFilterContext **filters = av_realloc(graph->filters,
69                                            sizeof(AVFilterContext*) * (graph->filter_count+1));
70     if (!filters)
71         return AVERROR(ENOMEM);
72
73     graph->filters = filters;
74     graph->filters[graph->filter_count++] = filter;
75
76     return 0;
77 }
78
79 int avfilter_graph_create_filter(AVFilterContext **filt_ctx, AVFilter *filt,
80                                  const char *name, const char *args, void *opaque,
81                                  AVFilterGraph *graph_ctx)
82 {
83     int ret;
84
85     if ((ret = avfilter_open(filt_ctx, filt, name)) < 0)
86         goto fail;
87     if ((ret = avfilter_init_filter(*filt_ctx, args, opaque)) < 0)
88         goto fail;
89     if ((ret = avfilter_graph_add_filter(graph_ctx, *filt_ctx)) < 0)
90         goto fail;
91     return 0;
92
93 fail:
94     if (*filt_ctx)
95         avfilter_free(*filt_ctx);
96     *filt_ctx = NULL;
97     return ret;
98 }
99
100 void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
101 {
102     graph->disable_auto_convert = flags;
103 }
104
105 /**
106  * Check for the validity of graph.
107  *
108  * A graph is considered valid if all its input and output pads are
109  * connected.
110  *
111  * @return 0 in case of success, a negative value otherwise
112  */
113 static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
114 {
115     AVFilterContext *filt;
116     int i, j;
117
118     for (i = 0; i < graph->filter_count; i++) {
119         filt = graph->filters[i];
120
121         for (j = 0; j < filt->input_count; j++) {
122             if (!filt->inputs[j] || !filt->inputs[j]->src) {
123                 av_log(log_ctx, AV_LOG_ERROR,
124                        "Input pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any source\n",
125                        filt->input_pads[j].name, filt->name, filt->filter->name);
126                 return AVERROR(EINVAL);
127             }
128         }
129
130         for (j = 0; j < filt->output_count; j++) {
131             if (!filt->outputs[j] || !filt->outputs[j]->dst) {
132                 av_log(log_ctx, AV_LOG_ERROR,
133                        "Output pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any destination\n",
134                        filt->output_pads[j].name, filt->name, filt->filter->name);
135                 return AVERROR(EINVAL);
136             }
137         }
138     }
139
140     return 0;
141 }
142
143 /**
144  * Configure all the links of graphctx.
145  *
146  * @return 0 in case of success, a negative value otherwise
147  */
148 static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
149 {
150     AVFilterContext *filt;
151     int i, ret;
152
153     for (i=0; i < graph->filter_count; i++) {
154         filt = graph->filters[i];
155
156         if (!filt->output_count) {
157             if ((ret = avfilter_config_links(filt)))
158                 return ret;
159         }
160     }
161
162     return 0;
163 }
164
165 AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name)
166 {
167     int i;
168
169     for (i = 0; i < graph->filter_count; i++)
170         if (graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
171             return graph->filters[i];
172
173     return NULL;
174 }
175
176 static int insert_conv_filter(AVFilterGraph *graph, AVFilterLink *link,
177                               const char *filt_name, const char *filt_args)
178 {
179     static int auto_count = 0, ret;
180     char inst_name[32];
181     AVFilterContext *filt_ctx;
182
183     if (graph->disable_auto_convert) {
184         av_log(NULL, AV_LOG_ERROR,
185                "The filters '%s' and '%s' do not have a common format "
186                "and automatic conversion is disabled.\n",
187                link->src->name, link->dst->name);
188         return AVERROR(EINVAL);
189     }
190
191     snprintf(inst_name, sizeof(inst_name), "auto-inserted %s %d",
192             filt_name, auto_count++);
193
194     if ((ret = avfilter_graph_create_filter(&filt_ctx,
195                                             avfilter_get_by_name(filt_name),
196                                             inst_name, filt_args, NULL, graph)) < 0)
197         return ret;
198     if ((ret = avfilter_insert_filter(link, filt_ctx, 0, 0)) < 0)
199         return ret;
200
201     filt_ctx->filter->query_formats(filt_ctx);
202
203     if ( ((link = filt_ctx-> inputs[0]) &&
204            !avfilter_merge_formats(link->in_formats, link->out_formats)) ||
205          ((link = filt_ctx->outputs[0]) &&
206            !avfilter_merge_formats(link->in_formats, link->out_formats))
207        ) {
208         av_log(NULL, AV_LOG_ERROR,
209                "Impossible to convert between the formats supported by the filter "
210                "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
211         return AVERROR(EINVAL);
212     }
213
214     if (link->type == AVMEDIA_TYPE_AUDIO &&
215          (((link = filt_ctx-> inputs[0]) &&
216            !ff_merge_channel_layouts(link->in_channel_layouts, link->out_channel_layouts)) ||
217          ((link = filt_ctx->outputs[0]) &&
218            !ff_merge_channel_layouts(link->in_channel_layouts, link->out_channel_layouts)))
219        ) {
220         av_log(NULL, AV_LOG_ERROR,
221                "Impossible to convert between the channel layouts formats supported by the filter "
222                "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
223         return AVERROR(EINVAL);
224     }
225
226     return 0;
227 }
228
229 static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
230 {
231     int i, j, ret;
232     char filt_args[128];
233     AVFilterFormats *formats;
234     AVFilterChannelLayouts *chlayouts;
235     AVFilterFormats *samplerates;
236     int scaler_count = 0, resampler_count = 0;
237
238     /* ask all the sub-filters for their supported media formats */
239     for (i = 0; i < graph->filter_count; i++) {
240         if (graph->filters[i]->filter->query_formats)
241             graph->filters[i]->filter->query_formats(graph->filters[i]);
242         else
243             ff_default_query_formats(graph->filters[i]);
244     }
245
246     /* go through and merge as many format lists as possible */
247     for (i = 0; i < graph->filter_count; i++) {
248         AVFilterContext *filter = graph->filters[i];
249
250         for (j = 0; j < filter->input_count; j++) {
251             AVFilterLink *link = filter->inputs[j];
252 #if 0
253             if (!link) continue;
254
255             if (!link->in_formats || !link->out_formats)
256                 return AVERROR(EINVAL);
257
258             if (link->type == AVMEDIA_TYPE_VIDEO &&
259                 !avfilter_merge_formats(link->in_formats, link->out_formats)) {
260
261                 /* couldn't merge format lists, auto-insert scale filter */
262                 snprintf(filt_args, sizeof(filt_args), "0:0:%s",
263                          graph->scale_sws_opts);
264                 if (ret = insert_conv_filter(graph, link, "scale", filt_args))
265                     return ret;
266             }
267             else if (link->type == AVMEDIA_TYPE_AUDIO) {
268                 if (!link->in_channel_layouts || !link->out_channel_layouts)
269                     return AVERROR(EINVAL);
270
271                 /* Merge all three list before checking: that way, in all
272                  * three categories, aconvert will use a common format
273                  * whenever possible. */
274                 formats   = avfilter_merge_formats(link->in_formats,   link->out_formats);
275                 chlayouts   = ff_merge_channel_layouts(link->in_channel_layouts  , link->out_channel_layouts);
276                 samplerates = ff_merge_samplerates    (link->in_samplerates, link->out_samplerates);
277
278                 if (!formats || !chlayouts || !samplerates)
279                     if (ret = insert_conv_filter(graph, link, "aresample", NULL))
280                        return ret;
281 #else
282             int convert_needed = 0;
283
284             if (!link)
285                 continue;
286
287             if (link->in_formats != link->out_formats &&
288                 !avfilter_merge_formats(link->in_formats,
289                                         link->out_formats))
290                 convert_needed = 1;
291             if (link->type == AVMEDIA_TYPE_AUDIO) {
292                 if (link->in_channel_layouts != link->out_channel_layouts &&
293                     !ff_merge_channel_layouts(link->in_channel_layouts,
294                                               link->out_channel_layouts))
295                     convert_needed = 1;
296                 if (link->in_samplerates != link->out_samplerates &&
297                     !ff_merge_samplerates(link->in_samplerates,
298                                           link->out_samplerates))
299                     convert_needed = 1;
300             }
301
302             if (convert_needed) {
303                 AVFilterContext *convert;
304                 AVFilter *filter;
305                 AVFilterLink *inlink, *outlink;
306                 char scale_args[256];
307                 char inst_name[30];
308
309                 /* couldn't merge format lists. auto-insert conversion filter */
310                 switch (link->type) {
311                 case AVMEDIA_TYPE_VIDEO:
312                     snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
313                              scaler_count++);
314                     snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts);
315                     if ((ret = avfilter_graph_create_filter(&convert,
316                                                             avfilter_get_by_name("scale"),
317                                                             inst_name, scale_args, NULL,
318                                                             graph)) < 0)
319                         return ret;
320                     break;
321                 case AVMEDIA_TYPE_AUDIO:
322                     if (!(filter = avfilter_get_by_name("aresample"))) {
323                         av_log(log_ctx, AV_LOG_ERROR, "'resample' filter "
324                                "not present, cannot convert audio formats.\n");
325                         return AVERROR(EINVAL);
326                     }
327
328                     snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d",
329                              resampler_count++);
330                     if ((ret = avfilter_graph_create_filter(&convert,
331                                                             avfilter_get_by_name("aresample"),
332                                                             inst_name, NULL, NULL, graph)) < 0)
333                         return ret;
334                     break;
335                 default:
336                     return AVERROR(EINVAL);
337                 }
338
339                 if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
340                     return ret;
341
342                 convert->filter->query_formats(convert);
343                 inlink  = convert->inputs[0];
344                 outlink = convert->outputs[0];
345                 if (!avfilter_merge_formats( inlink->in_formats,  inlink->out_formats) ||
346                     !avfilter_merge_formats(outlink->in_formats, outlink->out_formats))
347                     ret |= AVERROR(ENOSYS);
348                 if (inlink->type == AVMEDIA_TYPE_AUDIO &&
349                     (!ff_merge_samplerates(inlink->in_samplerates,
350                                            inlink->out_samplerates) ||
351                      !ff_merge_channel_layouts(inlink->in_channel_layouts,
352                                                inlink->out_channel_layouts)))
353                     ret |= AVERROR(ENOSYS);
354                 if (outlink->type == AVMEDIA_TYPE_AUDIO &&
355                     (!ff_merge_samplerates(outlink->in_samplerates,
356                                            outlink->out_samplerates) ||
357                      !ff_merge_channel_layouts(outlink->in_channel_layouts,
358                                                outlink->out_channel_layouts)))
359                     ret |= AVERROR(ENOSYS);
360
361                 if (ret < 0) {
362                     av_log(log_ctx, AV_LOG_ERROR,
363                            "Impossible to convert between the formats supported by the filter "
364                            "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
365                     return ret;
366                 }
367 #endif
368             }
369         }
370     }
371
372     return 0;
373 }
374
375 static int pick_format(AVFilterLink *link, AVFilterLink *ref)
376 {
377     if (!link || !link->in_formats)
378         return 0;
379
380     if (link->type == AVMEDIA_TYPE_VIDEO) {
381         if(ref && ref->type == AVMEDIA_TYPE_VIDEO){
382             int has_alpha= av_pix_fmt_descriptors[ref->format].nb_components % 2 == 0;
383             enum PixelFormat best= PIX_FMT_NONE;
384             int i;
385             for (i=0; i<link->in_formats->format_count; i++) {
386                 enum PixelFormat p = link->in_formats->formats[i];
387                 best= avcodec_find_best_pix_fmt2(best, p, ref->format, has_alpha, NULL);
388             }
389             link->in_formats->formats[0] = best;
390         }
391     }
392
393     link->in_formats->format_count = 1;
394     link->format = link->in_formats->formats[0];
395
396     if (link->type == AVMEDIA_TYPE_AUDIO) {
397         if (!link->in_samplerates->format_count) {
398             av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
399                    " the link between filters %s and %s.\n", link->src->name,
400                    link->dst->name);
401             return AVERROR(EINVAL);
402         }
403         link->in_samplerates->format_count = 1;
404         link->sample_rate = link->in_samplerates->formats[0];
405
406         if (!link->in_channel_layouts->nb_channel_layouts) {
407             av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
408                    "the link between filters %s and %s.\n", link->src->name,
409                    link->dst->name);
410             return AVERROR(EINVAL);
411         }
412         link->in_channel_layouts->nb_channel_layouts = 1;
413         link->channel_layout = link->in_channel_layouts->channel_layouts[0];
414     }
415
416     avfilter_formats_unref(&link->in_formats);
417     avfilter_formats_unref(&link->out_formats);
418     avfilter_formats_unref(&link->in_samplerates);
419     avfilter_formats_unref(&link->out_samplerates);
420     ff_channel_layouts_unref(&link->in_channel_layouts);
421     ff_channel_layouts_unref(&link->out_channel_layouts);
422
423     return 0;
424 }
425
426 #define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format) \
427 do {                                                                   \
428     for (i = 0; i < filter->input_count; i++) {                        \
429         AVFilterLink *link = filter->inputs[i];                        \
430         fmt_type fmt;                                                  \
431                                                                        \
432         if (!link->out_ ## list || link->out_ ## list->nb != 1)        \
433             continue;                                                  \
434         fmt = link->out_ ## list->var[0];                              \
435                                                                        \
436         for (j = 0; j < filter->output_count; j++) {                   \
437             AVFilterLink *out_link = filter->outputs[j];               \
438             list_type *fmts;                                           \
439                                                                        \
440             if (link->type != out_link->type ||                        \
441                 out_link->in_ ## list->nb == 1)                        \
442                 continue;                                              \
443             fmts = out_link->in_ ## list;                              \
444                                                                        \
445             if (!out_link->in_ ## list->nb) {                          \
446                 add_format(&out_link->in_ ##list, fmt);                \
447                 break;                                                 \
448             }                                                          \
449                                                                        \
450             for (k = 0; k < out_link->in_ ## list->nb; k++)            \
451                 if (fmts->var[k] == fmt) {                             \
452                     fmts->var[0]  = fmt;                               \
453                     fmts->nb = 1;                                      \
454                     ret = 1;                                           \
455                     break;                                             \
456                 }                                                      \
457         }                                                              \
458     }                                                                  \
459 } while (0)
460
461 static int reduce_formats_on_filter(AVFilterContext *filter)
462 {
463     int i, j, k, ret = 0;
464
465     REDUCE_FORMATS(int,      AVFilterFormats,        formats,         formats,
466                    format_count, avfilter_add_format);
467     REDUCE_FORMATS(int,      AVFilterFormats,        samplerates,     formats,
468                    format_count, avfilter_add_format);
469     REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts,
470                    channel_layouts, nb_channel_layouts, ff_add_channel_layout);
471
472     return ret;
473 }
474
475 static void reduce_formats(AVFilterGraph *graph)
476 {
477     int i, reduced;
478
479     do {
480         reduced = 0;
481
482         for (i = 0; i < graph->filter_count; i++)
483             reduced |= reduce_formats_on_filter(graph->filters[i]);
484     } while (reduced);
485 }
486
487 static void swap_samplerates_on_filter(AVFilterContext *filter)
488 {
489     AVFilterLink *link = NULL;
490     int sample_rate;
491     int i, j;
492
493     for (i = 0; i < filter->input_count; i++) {
494         link = filter->inputs[i];
495
496         if (link->type == AVMEDIA_TYPE_AUDIO &&
497             link->out_samplerates->format_count == 1)
498             break;
499     }
500     if (i == filter->input_count)
501         return;
502
503     sample_rate = link->out_samplerates->formats[0];
504
505     for (i = 0; i < filter->output_count; i++) {
506         AVFilterLink *outlink = filter->outputs[i];
507         int best_idx, best_diff = INT_MAX;
508
509         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
510             outlink->in_samplerates->format_count < 2)
511             continue;
512
513         for (j = 0; j < outlink->in_samplerates->format_count; j++) {
514             int diff = abs(sample_rate - outlink->in_samplerates->formats[j]);
515
516             if (diff < best_diff) {
517                 best_diff = diff;
518                 best_idx  = j;
519             }
520         }
521         FFSWAP(int, outlink->in_samplerates->formats[0],
522                outlink->in_samplerates->formats[best_idx]);
523     }
524 }
525
526 static void swap_samplerates(AVFilterGraph *graph)
527 {
528     int i;
529
530     for (i = 0; i < graph->filter_count; i++)
531         swap_samplerates_on_filter(graph->filters[i]);
532 }
533
534 static void swap_channel_layouts_on_filter(AVFilterContext *filter)
535 {
536     AVFilterLink *link = NULL;
537     uint64_t chlayout;
538     int i, j;
539
540     for (i = 0; i < filter->input_count; i++) {
541         link = filter->inputs[i];
542
543         if (link->type == AVMEDIA_TYPE_AUDIO &&
544             link->out_channel_layouts->nb_channel_layouts == 1)
545             break;
546     }
547     if (i == filter->input_count)
548         return;
549
550     chlayout = link->out_channel_layouts->channel_layouts[0];
551
552     for (i = 0; i < filter->output_count; i++) {
553         AVFilterLink *outlink = filter->outputs[i];
554         int best_idx, best_score = INT_MIN;
555
556         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
557             outlink->in_channel_layouts->nb_channel_layouts < 2)
558             continue;
559
560         for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts; j++) {
561             uint64_t out_chlayout = outlink->in_channel_layouts->channel_layouts[j];
562             int matched_channels  = av_get_channel_layout_nb_channels(chlayout &
563                                                                       out_chlayout);
564             int extra_channels     = av_get_channel_layout_nb_channels(out_chlayout &
565                                                                        (~chlayout));
566             int score = matched_channels - extra_channels;
567
568             if (score > best_score) {
569                 best_score = score;
570                 best_idx   = j;
571             }
572         }
573         FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0],
574                outlink->in_channel_layouts->channel_layouts[best_idx]);
575     }
576
577 }
578
579 static void swap_channel_layouts(AVFilterGraph *graph)
580 {
581     int i;
582
583     for (i = 0; i < graph->filter_count; i++)
584         swap_channel_layouts_on_filter(graph->filters[i]);
585 }
586
587 static void swap_sample_fmts_on_filter(AVFilterContext *filter)
588 {
589     AVFilterLink *link = NULL;
590     int format, bps;
591     int i, j;
592
593     for (i = 0; i < filter->input_count; i++) {
594         link = filter->inputs[i];
595
596         if (link->type == AVMEDIA_TYPE_AUDIO &&
597             link->out_formats->format_count == 1)
598             break;
599     }
600     if (i == filter->input_count)
601         return;
602
603     format = link->out_formats->formats[0];
604     bps    = av_get_bytes_per_sample(format);
605
606     for (i = 0; i < filter->output_count; i++) {
607         AVFilterLink *outlink = filter->outputs[i];
608         int best_idx, best_score = INT_MIN;
609
610         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
611             outlink->in_formats->format_count < 2)
612             continue;
613
614         for (j = 0; j < outlink->in_formats->format_count; j++) {
615             int out_format = outlink->in_formats->formats[j];
616             int out_bps    = av_get_bytes_per_sample(out_format);
617             int score;
618
619             if (av_get_packed_sample_fmt(out_format) == format ||
620                 av_get_planar_sample_fmt(out_format) == format) {
621                 best_idx   = j;
622                 break;
623             }
624
625             /* for s32 and float prefer double to prevent loss of information */
626             if (bps == 4 && out_bps == 8) {
627                 best_idx = j;
628                 break;
629             }
630
631             /* prefer closest higher or equal bps */
632             score = -abs(out_bps - bps);
633             if (out_bps >= bps)
634                 score += INT_MAX/2;
635
636             if (score > best_score) {
637                 best_score = score;
638                 best_idx   = j;
639             }
640         }
641         FFSWAP(int, outlink->in_formats->formats[0],
642                outlink->in_formats->formats[best_idx]);
643     }
644 }
645
646 static void swap_sample_fmts(AVFilterGraph *graph)
647 {
648     int i;
649
650     for (i = 0; i < graph->filter_count; i++)
651         swap_sample_fmts_on_filter(graph->filters[i]);
652
653 }
654
655 static int pick_formats(AVFilterGraph *graph)
656 {
657     int i, j, ret;
658     int change;
659
660     do{
661         change = 0;
662         for (i = 0; i < graph->filter_count; i++) {
663             AVFilterContext *filter = graph->filters[i];
664             if (filter->input_count){
665                 for (j = 0; j < filter->input_count; j++){
666                     if(filter->inputs[j]->in_formats && filter->inputs[j]->in_formats->format_count == 1) {
667                         pick_format(filter->inputs[j], NULL);
668                         change = 1;
669                     }
670                 }
671             }
672             if (filter->output_count){
673                 for (j = 0; j < filter->output_count; j++){
674                     if(filter->outputs[j]->in_formats && filter->outputs[j]->in_formats->format_count == 1) {
675                         pick_format(filter->outputs[j], NULL);
676                         change = 1;
677                     }
678                 }
679             }
680             if (filter->input_count && filter->output_count && filter->inputs[0]->format>=0) {
681                 for (j = 0; j < filter->output_count; j++) {
682                     if(filter->outputs[j]->format<0) {
683                         pick_format(filter->outputs[j], filter->inputs[0]);
684                         change = 1;
685                     }
686                 }
687             }
688         }
689     }while(change);
690
691     for (i = 0; i < graph->filter_count; i++) {
692         AVFilterContext *filter = graph->filters[i];
693
694         for (j = 0; j < filter->input_count; j++)
695             if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
696                 return ret;
697         for (j = 0; j < filter->output_count; j++)
698             if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
699                 return ret;
700     }
701     return 0;
702 }
703
704 /**
705  * Configure the formats of all the links in the graph.
706  */
707 static int graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
708 {
709     int ret;
710
711     /* find supported formats from sub-filters, and merge along links */
712     if ((ret = query_formats(graph, log_ctx)) < 0)
713         return ret;
714
715     /* Once everything is merged, it's possible that we'll still have
716      * multiple valid media format choices. We try to minimize the amount
717      * of format conversion inside filters */
718     reduce_formats(graph);
719
720     /* for audio filters, ensure the best format, sample rate and channel layout
721      * is selected */
722     swap_sample_fmts(graph);
723     swap_samplerates(graph);
724     swap_channel_layouts(graph);
725
726     if ((ret = pick_formats(graph)) < 0)
727         return ret;
728
729     return 0;
730 }
731
732 static int ff_avfilter_graph_config_pointers(AVFilterGraph *graph,
733                                              AVClass *log_ctx)
734 {
735     unsigned i, j;
736     int sink_links_count = 0, n = 0;
737     AVFilterContext *f;
738     AVFilterLink **sinks;
739
740     for (i = 0; i < graph->filter_count; i++) {
741         f = graph->filters[i];
742         for (j = 0; j < f->input_count; j++) {
743             f->inputs[j]->graph     = graph;
744             f->inputs[j]->age_index = -1;
745         }
746         for (j = 0; j < f->output_count; j++) {
747             f->outputs[j]->graph    = graph;
748             f->outputs[j]->age_index= -1;
749         }
750         if (!f->output_count) {
751             if (f->input_count > INT_MAX - sink_links_count)
752                 return AVERROR(EINVAL);
753             sink_links_count += f->input_count;
754         }
755     }
756     sinks = av_calloc(sink_links_count, sizeof(*sinks));
757     if (!sinks)
758         return AVERROR(ENOMEM);
759     for (i = 0; i < graph->filter_count; i++) {
760         f = graph->filters[i];
761         if (!f->output_count) {
762             for (j = 0; j < f->input_count; j++) {
763                 sinks[n] = f->inputs[j];
764                 f->inputs[j]->age_index = n++;
765             }
766         }
767     }
768     av_assert0(n == sink_links_count);
769     graph->sink_links       = sinks;
770     graph->sink_links_count = sink_links_count;
771     return 0;
772 }
773
774 int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
775 {
776     int ret;
777
778     if ((ret = graph_check_validity(graphctx, log_ctx)))
779         return ret;
780     if ((ret = graph_config_formats(graphctx, log_ctx)))
781         return ret;
782     if ((ret = graph_config_links(graphctx, log_ctx)))
783         return ret;
784     if ((ret = ff_avfilter_graph_config_pointers(graphctx, log_ctx)))
785         return ret;
786
787     return 0;
788 }
789
790 int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags)
791 {
792     int i, r = AVERROR(ENOSYS);
793
794     if(!graph)
795         return r;
796
797     if((flags & AVFILTER_CMD_FLAG_ONE) && !(flags & AVFILTER_CMD_FLAG_FAST)) {
798         r=avfilter_graph_send_command(graph, target, cmd, arg, res, res_len, flags | AVFILTER_CMD_FLAG_FAST);
799         if(r != AVERROR(ENOSYS))
800             return r;
801     }
802
803     if(res_len && res)
804         res[0]= 0;
805
806     for (i = 0; i < graph->filter_count; i++) {
807         AVFilterContext *filter = graph->filters[i];
808         if(!strcmp(target, "all") || (filter->name && !strcmp(target, filter->name)) || !strcmp(target, filter->filter->name)){
809             r = avfilter_process_command(filter, cmd, arg, res, res_len, flags);
810             if(r != AVERROR(ENOSYS)) {
811                 if((flags & AVFILTER_CMD_FLAG_ONE) || r<0)
812                     return r;
813             }
814         }
815     }
816
817     return r;
818 }
819
820 int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *command, const char *arg, int flags, double ts)
821 {
822     int i;
823
824     if(!graph)
825         return 0;
826
827     for (i = 0; i < graph->filter_count; i++) {
828         AVFilterContext *filter = graph->filters[i];
829         if(filter && (!strcmp(target, "all") || !strcmp(target, filter->name) || !strcmp(target, filter->filter->name))){
830             AVFilterCommand **que = &filter->command_queue, *next;
831             while(*que && (*que)->time <= ts)
832                 que = &(*que)->next;
833             next= *que;
834             *que= av_mallocz(sizeof(AVFilterCommand));
835             (*que)->command = av_strdup(command);
836             (*que)->arg     = av_strdup(arg);
837             (*que)->time    = ts;
838             (*que)->flags   = flags;
839             (*que)->next    = next;
840             if(flags & AVFILTER_CMD_FLAG_ONE)
841                 return 0;
842         }
843     }
844
845     return 0;
846 }
847
848 static void heap_bubble_up(AVFilterGraph *graph,
849                            AVFilterLink *link, int index)
850 {
851     AVFilterLink **links = graph->sink_links;
852
853     while (index) {
854         int parent = (index - 1) >> 1;
855         if (links[parent]->current_pts >= link->current_pts)
856             break;
857         links[index] = links[parent];
858         links[index]->age_index = index;
859         index = parent;
860     }
861     links[index] = link;
862     link->age_index = index;
863 }
864
865 static void heap_bubble_down(AVFilterGraph *graph,
866                              AVFilterLink *link, int index)
867 {
868     AVFilterLink **links = graph->sink_links;
869
870     while (1) {
871         int child = 2 * index + 1;
872         if (child >= graph->sink_links_count)
873             break;
874         if (child + 1 < graph->sink_links_count &&
875             links[child + 1]->current_pts < links[child]->current_pts)
876             child++;
877         if (link->current_pts < links[child]->current_pts)
878             break;
879         links[index] = links[child];
880         links[index]->age_index = index;
881         index = child;
882     }
883     links[index] = link;
884     link->age_index = index;
885 }
886
887 void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link)
888 {
889     heap_bubble_up  (graph, link, link->age_index);
890     heap_bubble_down(graph, link, link->age_index);
891 }
892
893
894 int avfilter_graph_request_oldest(AVFilterGraph *graph)
895 {
896     while (graph->sink_links_count) {
897         AVFilterLink *oldest = graph->sink_links[0];
898         int r = avfilter_request_frame(oldest);
899         if (r != AVERROR_EOF)
900             return r;
901         /* EOF: remove the link from the heap */
902         if (oldest->age_index < --graph->sink_links_count)
903             heap_bubble_down(graph, graph->sink_links[graph->sink_links_count],
904                              oldest->age_index);
905         oldest->age_index = -1;
906     }
907     return AVERROR_EOF;
908 }