• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "config.h"
24 
25 #include <string.h>
26 
27 #include "libavutil/avassert.h"
28 #include "libavutil/bprint.h"
29 #include "libavutil/channel_layout.h"
30 #include "libavutil/imgutils.h"
31 #include "libavutil/opt.h"
32 #include "libavutil/pixdesc.h"
33 
34 #define FF_INTERNAL_FIELDS 1
35 #include "framequeue.h"
36 
37 #include "avfilter.h"
38 #include "buffersink.h"
39 #include "formats.h"
40 #include "internal.h"
41 #include "thread.h"
42 
43 #define OFFSET(x) offsetof(AVFilterGraph, x)
44 #define F AV_OPT_FLAG_FILTERING_PARAM
45 #define V AV_OPT_FLAG_VIDEO_PARAM
46 #define A AV_OPT_FLAG_AUDIO_PARAM
47 static const AVOption filtergraph_options[] = {
48     { "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,
49         { .i64 = AVFILTER_THREAD_SLICE }, 0, INT_MAX, F|V|A, "thread_type" },
50         { "slice", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVFILTER_THREAD_SLICE }, .flags = F|V|A, .unit = "thread_type" },
51     { "threads",     "Maximum number of threads", OFFSET(nb_threads), AV_OPT_TYPE_INT,
52         { .i64 = 0 }, 0, INT_MAX, F|V|A, "threads"},
53         {"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, .flags = F|V|A, .unit = "threads"},
54     {"scale_sws_opts"       , "default scale filter options"        , OFFSET(scale_sws_opts)        ,
55         AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, F|V },
56     {"aresample_swr_opts"   , "default aresample filter options"    , OFFSET(aresample_swr_opts)    ,
57         AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, F|A },
58     { NULL },
59 };
60 
61 static const AVClass filtergraph_class = {
62     .class_name = "AVFilterGraph",
63     .item_name  = av_default_item_name,
64     .version    = LIBAVUTIL_VERSION_INT,
65     .option     = filtergraph_options,
66     .category   = AV_CLASS_CATEGORY_FILTER,
67 };
68 
69 #if !HAVE_THREADS
ff_graph_thread_free(AVFilterGraph * graph)70 void ff_graph_thread_free(AVFilterGraph *graph)
71 {
72 }
73 
ff_graph_thread_init(AVFilterGraph * graph)74 int ff_graph_thread_init(AVFilterGraph *graph)
75 {
76     graph->thread_type = 0;
77     graph->nb_threads  = 1;
78     return 0;
79 }
80 #endif
81 
avfilter_graph_alloc(void)82 AVFilterGraph *avfilter_graph_alloc(void)
83 {
84     AVFilterGraph *ret = av_mallocz(sizeof(*ret));
85     if (!ret)
86         return NULL;
87 
88     ret->internal = av_mallocz(sizeof(*ret->internal));
89     if (!ret->internal) {
90         av_freep(&ret);
91         return NULL;
92     }
93 
94     ret->av_class = &filtergraph_class;
95     av_opt_set_defaults(ret);
96     ff_framequeue_global_init(&ret->internal->frame_queues);
97 
98     return ret;
99 }
100 
ff_filter_graph_remove_filter(AVFilterGraph * graph,AVFilterContext * filter)101 void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter)
102 {
103     int i, j;
104     for (i = 0; i < graph->nb_filters; i++) {
105         if (graph->filters[i] == filter) {
106             FFSWAP(AVFilterContext*, graph->filters[i],
107                    graph->filters[graph->nb_filters - 1]);
108             graph->nb_filters--;
109             filter->graph = NULL;
110             for (j = 0; j<filter->nb_outputs; j++)
111                 if (filter->outputs[j])
112                     filter->outputs[j]->graph = NULL;
113 
114             return;
115         }
116     }
117 }
118 
avfilter_graph_free(AVFilterGraph ** graph)119 void avfilter_graph_free(AVFilterGraph **graph)
120 {
121     if (!*graph)
122         return;
123 
124     while ((*graph)->nb_filters)
125         avfilter_free((*graph)->filters[0]);
126 
127     ff_graph_thread_free(*graph);
128 
129     av_freep(&(*graph)->sink_links);
130 
131     av_opt_free(*graph);
132 
133     av_freep(&(*graph)->filters);
134     av_freep(&(*graph)->internal);
135     av_freep(graph);
136 }
137 
avfilter_graph_create_filter(AVFilterContext ** filt_ctx,const AVFilter * filt,const char * name,const char * args,void * opaque,AVFilterGraph * graph_ctx)138 int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt,
139                                  const char *name, const char *args, void *opaque,
140                                  AVFilterGraph *graph_ctx)
141 {
142     int ret;
143 
144     *filt_ctx = avfilter_graph_alloc_filter(graph_ctx, filt, name);
145     if (!*filt_ctx)
146         return AVERROR(ENOMEM);
147 
148     ret = avfilter_init_str(*filt_ctx, args);
149     if (ret < 0)
150         goto fail;
151 
152     return 0;
153 
154 fail:
155     avfilter_free(*filt_ctx);
156     *filt_ctx = NULL;
157     return ret;
158 }
159 
avfilter_graph_set_auto_convert(AVFilterGraph * graph,unsigned flags)160 void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
161 {
162     graph->disable_auto_convert = flags;
163 }
164 
avfilter_graph_alloc_filter(AVFilterGraph * graph,const AVFilter * filter,const char * name)165 AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph,
166                                              const AVFilter *filter,
167                                              const char *name)
168 {
169     AVFilterContext **filters, *s;
170 
171     if (graph->thread_type && !graph->internal->thread_execute) {
172         if (graph->execute) {
173             graph->internal->thread_execute = graph->execute;
174         } else {
175             int ret = ff_graph_thread_init(graph);
176             if (ret < 0) {
177                 av_log(graph, AV_LOG_ERROR, "Error initializing threading: %s.\n", av_err2str(ret));
178                 return NULL;
179             }
180         }
181     }
182 
183     filters = av_realloc_array(graph->filters, graph->nb_filters + 1, sizeof(*filters));
184     if (!filters)
185         return NULL;
186     graph->filters = filters;
187 
188     s = ff_filter_alloc(filter, name);
189     if (!s)
190         return NULL;
191 
192     graph->filters[graph->nb_filters++] = s;
193 
194     s->graph = graph;
195 
196     return s;
197 }
198 
199 /**
200  * Check for the validity of graph.
201  *
202  * A graph is considered valid if all its input and output pads are
203  * connected.
204  *
205  * @return >= 0 in case of success, a negative value otherwise
206  */
graph_check_validity(AVFilterGraph * graph,void * log_ctx)207 static int graph_check_validity(AVFilterGraph *graph, void *log_ctx)
208 {
209     AVFilterContext *filt;
210     int i, j;
211 
212     for (i = 0; i < graph->nb_filters; i++) {
213         const AVFilterPad *pad;
214         filt = graph->filters[i];
215 
216         for (j = 0; j < filt->nb_inputs; j++) {
217             if (!filt->inputs[j] || !filt->inputs[j]->src) {
218                 pad = &filt->input_pads[j];
219                 av_log(log_ctx, AV_LOG_ERROR,
220                        "Input pad \"%s\" with type %s of the filter instance \"%s\" of %s not connected to any source\n",
221                        pad->name, av_get_media_type_string(pad->type), filt->name, filt->filter->name);
222                 return AVERROR(EINVAL);
223             }
224         }
225 
226         for (j = 0; j < filt->nb_outputs; j++) {
227             if (!filt->outputs[j] || !filt->outputs[j]->dst) {
228                 pad = &filt->output_pads[j];
229                 av_log(log_ctx, AV_LOG_ERROR,
230                        "Output pad \"%s\" with type %s of the filter instance \"%s\" of %s not connected to any destination\n",
231                        pad->name, av_get_media_type_string(pad->type), filt->name, filt->filter->name);
232                 return AVERROR(EINVAL);
233             }
234         }
235     }
236 
237     return 0;
238 }
239 
240 /**
241  * Configure all the links of graphctx.
242  *
243  * @return >= 0 in case of success, a negative value otherwise
244  */
graph_config_links(AVFilterGraph * graph,void * log_ctx)245 static int graph_config_links(AVFilterGraph *graph, void *log_ctx)
246 {
247     AVFilterContext *filt;
248     int i, ret;
249 
250     for (i = 0; i < graph->nb_filters; i++) {
251         filt = graph->filters[i];
252 
253         if (!filt->nb_outputs) {
254             if ((ret = avfilter_config_links(filt)))
255                 return ret;
256         }
257     }
258 
259     return 0;
260 }
261 
graph_check_links(AVFilterGraph * graph,void * log_ctx)262 static int graph_check_links(AVFilterGraph *graph, void *log_ctx)
263 {
264     AVFilterContext *f;
265     AVFilterLink *l;
266     unsigned i, j;
267     int ret;
268 
269     for (i = 0; i < graph->nb_filters; i++) {
270         f = graph->filters[i];
271         for (j = 0; j < f->nb_outputs; j++) {
272             l = f->outputs[j];
273             if (l->type == AVMEDIA_TYPE_VIDEO) {
274                 ret = av_image_check_size2(l->w, l->h, INT64_MAX, l->format, 0, f);
275                 if (ret < 0)
276                     return ret;
277             }
278         }
279     }
280     return 0;
281 }
282 
avfilter_graph_get_filter(AVFilterGraph * graph,const char * name)283 AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, const char *name)
284 {
285     int i;
286 
287     for (i = 0; i < graph->nb_filters; i++)
288         if (graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
289             return graph->filters[i];
290 
291     return NULL;
292 }
293 
filter_link_check_formats(void * log,AVFilterLink * link,AVFilterFormatsConfig * cfg)294 static int filter_link_check_formats(void *log, AVFilterLink *link, AVFilterFormatsConfig *cfg)
295 {
296     int ret;
297 
298     switch (link->type) {
299 
300     case AVMEDIA_TYPE_VIDEO:
301         if ((ret = ff_formats_check_pixel_formats(log, cfg->formats)) < 0)
302             return ret;
303         break;
304 
305     case AVMEDIA_TYPE_AUDIO:
306         if ((ret = ff_formats_check_sample_formats(log, cfg->formats)) < 0 ||
307             (ret = ff_formats_check_sample_rates(log, cfg->samplerates)) < 0 ||
308             (ret = ff_formats_check_channel_layouts(log, cfg->channel_layouts)) < 0)
309             return ret;
310         break;
311 
312     default:
313         av_assert0(!"reached");
314     }
315     return 0;
316 }
317 
318 /**
319  * Check the validity of the formats / etc. lists set by query_formats().
320  *
321  * In particular, check they do not contain any redundant element.
322  */
filter_check_formats(AVFilterContext * ctx)323 static int filter_check_formats(AVFilterContext *ctx)
324 {
325     unsigned i;
326     int ret;
327 
328     for (i = 0; i < ctx->nb_inputs; i++) {
329         ret = filter_link_check_formats(ctx, ctx->inputs[i], &ctx->inputs[i]->outcfg);
330         if (ret < 0)
331             return ret;
332     }
333     for (i = 0; i < ctx->nb_outputs; i++) {
334         ret = filter_link_check_formats(ctx, ctx->outputs[i], &ctx->outputs[i]->incfg);
335         if (ret < 0)
336             return ret;
337     }
338     return 0;
339 }
340 
filter_query_formats(AVFilterContext * ctx)341 static int filter_query_formats(AVFilterContext *ctx)
342 {
343     int ret;
344     AVFilterFormats *formats;
345     AVFilterChannelLayouts *chlayouts;
346     enum AVMediaType type = ctx->inputs  && ctx->inputs [0] ? ctx->inputs [0]->type :
347                             ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
348                             AVMEDIA_TYPE_VIDEO;
349 
350     if ((ret = ctx->filter->formats.query_func(ctx)) < 0) {
351         if (ret != AVERROR(EAGAIN))
352             av_log(ctx, AV_LOG_ERROR, "Query format failed for '%s': %s\n",
353                    ctx->name, av_err2str(ret));
354         return ret;
355     }
356     ret = filter_check_formats(ctx);
357     if (ret < 0)
358         return ret;
359 
360     formats = ff_all_formats(type);
361     if ((ret = ff_set_common_formats(ctx, formats)) < 0)
362         return ret;
363     if (type == AVMEDIA_TYPE_AUDIO) {
364         if ((ret = ff_set_common_all_samplerates(ctx)) < 0)
365             return ret;
366         chlayouts = ff_all_channel_layouts();
367         if ((ret = ff_set_common_channel_layouts(ctx, chlayouts)) < 0)
368             return ret;
369     }
370     return 0;
371 }
372 
formats_declared(AVFilterContext * f)373 static int formats_declared(AVFilterContext *f)
374 {
375     int i;
376 
377     for (i = 0; i < f->nb_inputs; i++) {
378         if (!f->inputs[i]->outcfg.formats)
379             return 0;
380         if (f->inputs[i]->type == AVMEDIA_TYPE_AUDIO &&
381             !(f->inputs[i]->outcfg.samplerates &&
382               f->inputs[i]->outcfg.channel_layouts))
383             return 0;
384     }
385     for (i = 0; i < f->nb_outputs; i++) {
386         if (!f->outputs[i]->incfg.formats)
387             return 0;
388         if (f->outputs[i]->type == AVMEDIA_TYPE_AUDIO &&
389             !(f->outputs[i]->incfg.samplerates &&
390               f->outputs[i]->incfg.channel_layouts))
391             return 0;
392     }
393     return 1;
394 }
395 
396 /**
397  * Perform one round of query_formats() and merging formats lists on the
398  * filter graph.
399  * @return  >=0 if all links formats lists could be queried and merged;
400  *          AVERROR(EAGAIN) some progress was made in the queries or merging
401  *          and a later call may succeed;
402  *          AVERROR(EIO) (may be changed) plus a log message if no progress
403  *          was made and the negotiation is stuck;
404  *          a negative error code if some other error happened
405  */
query_formats(AVFilterGraph * graph,void * log_ctx)406 static int query_formats(AVFilterGraph *graph, void *log_ctx)
407 {
408     int i, j, ret;
409     int converter_count = 0;
410     int count_queried = 0;        /* successful calls to query_formats() */
411     int count_merged = 0;         /* successful merge of formats lists */
412     int count_already_merged = 0; /* lists already merged */
413     int count_delayed = 0;        /* lists that need to be merged later */
414 
415     for (i = 0; i < graph->nb_filters; i++) {
416         AVFilterContext *f = graph->filters[i];
417         if (formats_declared(f))
418             continue;
419         if (f->filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC)
420             ret = filter_query_formats(f);
421         else
422             ret = ff_default_query_formats(f);
423         if (ret < 0 && ret != AVERROR(EAGAIN))
424             return ret;
425         /* note: EAGAIN could indicate a partial success, not counted yet */
426         count_queried += ret >= 0;
427     }
428 
429     /* go through and merge as many format lists as possible */
430     for (i = 0; i < graph->nb_filters; i++) {
431         AVFilterContext *filter = graph->filters[i];
432 
433         for (j = 0; j < filter->nb_inputs; j++) {
434             AVFilterLink *link = filter->inputs[j];
435             const AVFilterNegotiation *neg;
436             unsigned neg_step;
437             int convert_needed = 0;
438 
439             if (!link)
440                 continue;
441 
442             neg = ff_filter_get_negotiation(link);
443             av_assert0(neg);
444             for (neg_step = 1; neg_step < neg->nb_mergers; neg_step++) {
445                 const AVFilterFormatsMerger *m = &neg->mergers[neg_step];
446                 void *a = FF_FIELD_AT(void *, m->offset, link->incfg);
447                 void *b = FF_FIELD_AT(void *, m->offset, link->outcfg);
448                 if (a && b && a != b && !m->can_merge(a, b)) {
449                     convert_needed = 1;
450                     break;
451                 }
452             }
453             for (neg_step = 0; neg_step < neg->nb_mergers; neg_step++) {
454                 const AVFilterFormatsMerger *m = &neg->mergers[neg_step];
455                 void *a = FF_FIELD_AT(void *, m->offset, link->incfg);
456                 void *b = FF_FIELD_AT(void *, m->offset, link->outcfg);
457                 if (!(a && b)) {
458                     count_delayed++;
459                 } else if (a == b) {
460                     count_already_merged++;
461                 } else if (!convert_needed) {
462                     count_merged++;
463                     ret = m->merge(a, b);
464                     if (ret < 0)
465                         return ret;
466                     if (!ret)
467                         convert_needed = 1;
468                 }
469             }
470 
471             if (convert_needed) {
472                 AVFilterContext *convert;
473                 const AVFilter *filter;
474                 AVFilterLink *inlink, *outlink;
475                 char inst_name[30];
476                 const char *opts;
477 
478                 if (graph->disable_auto_convert) {
479                     av_log(log_ctx, AV_LOG_ERROR,
480                            "The filters '%s' and '%s' do not have a common format "
481                            "and automatic conversion is disabled.\n",
482                            link->src->name, link->dst->name);
483                     return AVERROR(EINVAL);
484                 }
485 
486                 /* couldn't merge format lists. auto-insert conversion filter */
487                 if (!(filter = avfilter_get_by_name(neg->conversion_filter))) {
488                     av_log(log_ctx, AV_LOG_ERROR,
489                            "'%s' filter not present, cannot convert formats.\n",
490                            neg->conversion_filter);
491                     return AVERROR(EINVAL);
492                 }
493                 snprintf(inst_name, sizeof(inst_name), "auto_%s_%d",
494                          neg->conversion_filter, converter_count++);
495                 opts = FF_FIELD_AT(char *, neg->conversion_opts_offset, *graph);
496                 ret = avfilter_graph_create_filter(&convert, filter, inst_name, opts, NULL, graph);
497                 if (ret < 0)
498                     return ret;
499                 if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
500                     return ret;
501 
502                 if ((ret = filter_query_formats(convert)) < 0)
503                     return ret;
504 
505                 inlink  = convert->inputs[0];
506                 outlink = convert->outputs[0];
507                 av_assert0( inlink->incfg.formats->refcount > 0);
508                 av_assert0( inlink->outcfg.formats->refcount > 0);
509                 av_assert0(outlink->incfg.formats->refcount > 0);
510                 av_assert0(outlink->outcfg.formats->refcount > 0);
511                 if (outlink->type == AVMEDIA_TYPE_AUDIO) {
512                     av_assert0( inlink-> incfg.samplerates->refcount > 0);
513                     av_assert0( inlink->outcfg.samplerates->refcount > 0);
514                     av_assert0(outlink-> incfg.samplerates->refcount > 0);
515                     av_assert0(outlink->outcfg.samplerates->refcount > 0);
516                     av_assert0( inlink-> incfg.channel_layouts->refcount > 0);
517                     av_assert0( inlink->outcfg.channel_layouts->refcount > 0);
518                     av_assert0(outlink-> incfg.channel_layouts->refcount > 0);
519                     av_assert0(outlink->outcfg.channel_layouts->refcount > 0);
520                 }
521 #define MERGE(merger, link)                                                  \
522     ((merger)->merge(FF_FIELD_AT(void *, (merger)->offset, (link)->incfg),   \
523                      FF_FIELD_AT(void *, (merger)->offset, (link)->outcfg)))
524                 for (neg_step = 0; neg_step < neg->nb_mergers; neg_step++) {
525                     const AVFilterFormatsMerger *m = &neg->mergers[neg_step];
526                     if ((ret = MERGE(m,  inlink)) <= 0 ||
527                         (ret = MERGE(m, outlink)) <= 0) {
528                         if (ret < 0)
529                             return ret;
530                         av_log(log_ctx, AV_LOG_ERROR,
531                                "Impossible to convert between the formats supported by the filter "
532                                "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
533                         return AVERROR(ENOSYS);
534                     }
535                 }
536             }
537         }
538     }
539 
540     av_log(graph, AV_LOG_DEBUG, "query_formats: "
541            "%d queried, %d merged, %d already done, %d delayed\n",
542            count_queried, count_merged, count_already_merged, count_delayed);
543     if (count_delayed) {
544         AVBPrint bp;
545 
546         /* if count_queried > 0, one filter at least did set its formats,
547            that will give additional information to its neighbour;
548            if count_merged > 0, one pair of formats lists at least was merged,
549            that will give additional information to all connected filters;
550            in both cases, progress was made and a new round must be done */
551         if (count_queried || count_merged)
552             return AVERROR(EAGAIN);
553         av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
554         for (i = 0; i < graph->nb_filters; i++)
555             if (!formats_declared(graph->filters[i]))
556                 av_bprintf(&bp, "%s%s", bp.len ? ", " : "",
557                           graph->filters[i]->name);
558         av_log(graph, AV_LOG_ERROR,
559                "The following filters could not choose their formats: %s\n"
560                "Consider inserting the (a)format filter near their input or "
561                "output.\n", bp.str);
562         return AVERROR(EIO);
563     }
564     return 0;
565 }
566 
get_fmt_score(enum AVSampleFormat dst_fmt,enum AVSampleFormat src_fmt)567 static int get_fmt_score(enum AVSampleFormat dst_fmt, enum AVSampleFormat src_fmt)
568 {
569     int score = 0;
570 
571     if (av_sample_fmt_is_planar(dst_fmt) != av_sample_fmt_is_planar(src_fmt))
572         score ++;
573 
574     if (av_get_bytes_per_sample(dst_fmt) < av_get_bytes_per_sample(src_fmt)) {
575         score += 100 * (av_get_bytes_per_sample(src_fmt) - av_get_bytes_per_sample(dst_fmt));
576     }else
577         score += 10  * (av_get_bytes_per_sample(dst_fmt) - av_get_bytes_per_sample(src_fmt));
578 
579     if (av_get_packed_sample_fmt(dst_fmt) == AV_SAMPLE_FMT_S32 &&
580         av_get_packed_sample_fmt(src_fmt) == AV_SAMPLE_FMT_FLT)
581         score += 20;
582 
583     if (av_get_packed_sample_fmt(dst_fmt) == AV_SAMPLE_FMT_FLT &&
584         av_get_packed_sample_fmt(src_fmt) == AV_SAMPLE_FMT_S32)
585         score += 2;
586 
587     return score;
588 }
589 
find_best_sample_fmt_of_2(enum AVSampleFormat dst_fmt1,enum AVSampleFormat dst_fmt2,enum AVSampleFormat src_fmt)590 static enum AVSampleFormat find_best_sample_fmt_of_2(enum AVSampleFormat dst_fmt1, enum AVSampleFormat dst_fmt2,
591                                                      enum AVSampleFormat src_fmt)
592 {
593     int score1, score2;
594 
595     score1 = get_fmt_score(dst_fmt1, src_fmt);
596     score2 = get_fmt_score(dst_fmt2, src_fmt);
597 
598     return score1 < score2 ? dst_fmt1 : dst_fmt2;
599 }
600 
pick_format(AVFilterLink * link,AVFilterLink * ref)601 static int pick_format(AVFilterLink *link, AVFilterLink *ref)
602 {
603     if (!link || !link->incfg.formats)
604         return 0;
605 
606     if (link->type == AVMEDIA_TYPE_VIDEO) {
607         if(ref && ref->type == AVMEDIA_TYPE_VIDEO){
608             //FIXME: This should check for AV_PIX_FMT_FLAG_ALPHA after PAL8 pixel format without alpha is implemented
609             int has_alpha= av_pix_fmt_desc_get(ref->format)->nb_components % 2 == 0;
610             enum AVPixelFormat best= AV_PIX_FMT_NONE;
611             int i;
612             for (i = 0; i < link->incfg.formats->nb_formats; i++) {
613                 enum AVPixelFormat p = link->incfg.formats->formats[i];
614                 best= av_find_best_pix_fmt_of_2(best, p, ref->format, has_alpha, NULL);
615             }
616             av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s alpha:%d\n",
617                    av_get_pix_fmt_name(best), link->incfg.formats->nb_formats,
618                    av_get_pix_fmt_name(ref->format), has_alpha);
619             link->incfg.formats->formats[0] = best;
620         }
621     } else if (link->type == AVMEDIA_TYPE_AUDIO) {
622         if(ref && ref->type == AVMEDIA_TYPE_AUDIO){
623             enum AVSampleFormat best= AV_SAMPLE_FMT_NONE;
624             int i;
625             for (i = 0; i < link->incfg.formats->nb_formats; i++) {
626                 enum AVSampleFormat p = link->incfg.formats->formats[i];
627                 best = find_best_sample_fmt_of_2(best, p, ref->format);
628             }
629             av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s\n",
630                    av_get_sample_fmt_name(best), link->incfg.formats->nb_formats,
631                    av_get_sample_fmt_name(ref->format));
632             link->incfg.formats->formats[0] = best;
633         }
634     }
635 
636     link->incfg.formats->nb_formats = 1;
637     link->format = link->incfg.formats->formats[0];
638 
639     if (link->type == AVMEDIA_TYPE_AUDIO) {
640         int ret;
641 
642         if (!link->incfg.samplerates->nb_formats) {
643             av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
644                    " the link between filters %s and %s.\n", link->src->name,
645                    link->dst->name);
646             return AVERROR(EINVAL);
647         }
648         link->incfg.samplerates->nb_formats = 1;
649         link->sample_rate = link->incfg.samplerates->formats[0];
650 
651         if (link->incfg.channel_layouts->all_layouts) {
652             av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
653                    " the link between filters %s and %s.\n", link->src->name,
654                    link->dst->name);
655             if (!link->incfg.channel_layouts->all_counts)
656                 av_log(link->src, AV_LOG_ERROR, "Unknown channel layouts not "
657                        "supported, try specifying a channel layout using "
658                        "'aformat=channel_layouts=something'.\n");
659             return AVERROR(EINVAL);
660         }
661         link->incfg.channel_layouts->nb_channel_layouts = 1;
662         ret = av_channel_layout_copy(&link->ch_layout, &link->incfg.channel_layouts->channel_layouts[0]);
663         if (ret < 0)
664             return ret;
665 #if FF_API_OLD_CHANNEL_LAYOUT
666 FF_DISABLE_DEPRECATION_WARNINGS
667         link->channel_layout = link->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ?
668                                link->ch_layout.u.mask : 0;
669 FF_ENABLE_DEPRECATION_WARNINGS
670 #endif
671     }
672 
673     ff_formats_unref(&link->incfg.formats);
674     ff_formats_unref(&link->outcfg.formats);
675     ff_formats_unref(&link->incfg.samplerates);
676     ff_formats_unref(&link->outcfg.samplerates);
677     ff_channel_layouts_unref(&link->incfg.channel_layouts);
678     ff_channel_layouts_unref(&link->outcfg.channel_layouts);
679 
680     return 0;
681 }
682 
683 #define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format) \
684 do {                                                                   \
685     for (i = 0; i < filter->nb_inputs; i++) {                          \
686         AVFilterLink *link = filter->inputs[i];                        \
687         fmt_type fmt;                                                  \
688                                                                        \
689         if (!link->outcfg.list || link->outcfg.list->nb != 1)          \
690             continue;                                                  \
691         fmt = link->outcfg.list->var[0];                               \
692                                                                        \
693         for (j = 0; j < filter->nb_outputs; j++) {                     \
694             AVFilterLink *out_link = filter->outputs[j];               \
695             list_type *fmts;                                           \
696                                                                        \
697             if (link->type != out_link->type ||                        \
698                 out_link->incfg.list->nb == 1)                         \
699                 continue;                                              \
700             fmts = out_link->incfg.list;                               \
701                                                                        \
702             if (!out_link->incfg.list->nb) {                           \
703                 if ((ret = add_format(&out_link->incfg.list, fmt)) < 0)\
704                     return ret;                                        \
705                 ret = 1;                                               \
706                 break;                                                 \
707             }                                                          \
708                                                                        \
709             for (k = 0; k < out_link->incfg.list->nb; k++)             \
710                 if (fmts->var[k] == fmt) {                             \
711                     fmts->var[0]  = fmt;                               \
712                     fmts->nb = 1;                                      \
713                     ret = 1;                                           \
714                     break;                                             \
715                 }                                                      \
716         }                                                              \
717     }                                                                  \
718 } while (0)
719 
reduce_formats_on_filter(AVFilterContext * filter)720 static int reduce_formats_on_filter(AVFilterContext *filter)
721 {
722     int i, j, k, ret = 0;
723 
724     REDUCE_FORMATS(int,      AVFilterFormats,        formats,         formats,
725                    nb_formats, ff_add_format);
726     REDUCE_FORMATS(int,      AVFilterFormats,        samplerates,     formats,
727                    nb_formats, ff_add_format);
728 
729     /* reduce channel layouts */
730     for (i = 0; i < filter->nb_inputs; i++) {
731         AVFilterLink *inlink = filter->inputs[i];
732         AVChannelLayout fmt = { 0 };
733 
734         if (!inlink->outcfg.channel_layouts ||
735             inlink->outcfg.channel_layouts->nb_channel_layouts != 1)
736             continue;
737         av_channel_layout_copy(&fmt, &inlink->outcfg.channel_layouts->channel_layouts[0]);
738 
739         for (j = 0; j < filter->nb_outputs; j++) {
740             AVFilterLink *outlink = filter->outputs[j];
741             AVFilterChannelLayouts *fmts;
742 
743             fmts = outlink->incfg.channel_layouts;
744             if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1)
745                 continue;
746 
747             if (fmts->all_layouts &&
748                 (KNOWN(&fmt) || fmts->all_counts)) {
749                 /* Turn the infinite list into a singleton */
750                 fmts->all_layouts = fmts->all_counts  = 0;
751                 if (ff_add_channel_layout(&outlink->incfg.channel_layouts, &fmt) < 0)
752                     ret = 1;
753                 break;
754             }
755 
756             for (k = 0; k < outlink->incfg.channel_layouts->nb_channel_layouts; k++) {
757                 if (!av_channel_layout_compare(&fmts->channel_layouts[k], &fmt)) {
758                     av_channel_layout_copy(&fmts->channel_layouts[0], &fmt);
759                     fmts->nb_channel_layouts = 1;
760                     ret = 1;
761                     break;
762                 }
763             }
764         }
765         av_channel_layout_uninit(&fmt);
766     }
767 
768     return ret;
769 }
770 
reduce_formats(AVFilterGraph * graph)771 static int reduce_formats(AVFilterGraph *graph)
772 {
773     int i, reduced, ret;
774 
775     do {
776         reduced = 0;
777 
778         for (i = 0; i < graph->nb_filters; i++) {
779             if ((ret = reduce_formats_on_filter(graph->filters[i])) < 0)
780                 return ret;
781             reduced |= ret;
782         }
783     } while (reduced);
784 
785     return 0;
786 }
787 
swap_samplerates_on_filter(AVFilterContext * filter)788 static void swap_samplerates_on_filter(AVFilterContext *filter)
789 {
790     AVFilterLink *link = NULL;
791     int sample_rate;
792     int i, j;
793 
794     for (i = 0; i < filter->nb_inputs; i++) {
795         link = filter->inputs[i];
796 
797         if (link->type == AVMEDIA_TYPE_AUDIO &&
798             link->outcfg.samplerates->nb_formats== 1)
799             break;
800     }
801     if (i == filter->nb_inputs)
802         return;
803 
804     sample_rate = link->outcfg.samplerates->formats[0];
805 
806     for (i = 0; i < filter->nb_outputs; i++) {
807         AVFilterLink *outlink = filter->outputs[i];
808         int best_idx, best_diff = INT_MAX;
809 
810         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
811             outlink->incfg.samplerates->nb_formats < 2)
812             continue;
813 
814         for (j = 0; j < outlink->incfg.samplerates->nb_formats; j++) {
815             int diff = abs(sample_rate - outlink->incfg.samplerates->formats[j]);
816 
817             av_assert0(diff < INT_MAX); // This would lead to the use of uninitialized best_diff but is only possible with invalid sample rates
818 
819             if (diff < best_diff) {
820                 best_diff = diff;
821                 best_idx  = j;
822             }
823         }
824         FFSWAP(int, outlink->incfg.samplerates->formats[0],
825                outlink->incfg.samplerates->formats[best_idx]);
826     }
827 }
828 
swap_samplerates(AVFilterGraph * graph)829 static void swap_samplerates(AVFilterGraph *graph)
830 {
831     int i;
832 
833     for (i = 0; i < graph->nb_filters; i++)
834         swap_samplerates_on_filter(graph->filters[i]);
835 }
836 
837 #define CH_CENTER_PAIR (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)
838 #define CH_FRONT_PAIR  (AV_CH_FRONT_LEFT           | AV_CH_FRONT_RIGHT)
839 #define CH_STEREO_PAIR (AV_CH_STEREO_LEFT          | AV_CH_STEREO_RIGHT)
840 #define CH_WIDE_PAIR   (AV_CH_WIDE_LEFT            | AV_CH_WIDE_RIGHT)
841 #define CH_SIDE_PAIR   (AV_CH_SIDE_LEFT            | AV_CH_SIDE_RIGHT)
842 #define CH_DIRECT_PAIR (AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT)
843 #define CH_BACK_PAIR   (AV_CH_BACK_LEFT            | AV_CH_BACK_RIGHT)
844 
845 /* allowable substitutions for channel pairs when comparing layouts,
846  * ordered by priority for both values */
847 static const uint64_t ch_subst[][2] = {
848     { CH_FRONT_PAIR,      CH_CENTER_PAIR     },
849     { CH_FRONT_PAIR,      CH_WIDE_PAIR       },
850     { CH_FRONT_PAIR,      AV_CH_FRONT_CENTER },
851     { CH_CENTER_PAIR,     CH_FRONT_PAIR      },
852     { CH_CENTER_PAIR,     CH_WIDE_PAIR       },
853     { CH_CENTER_PAIR,     AV_CH_FRONT_CENTER },
854     { CH_WIDE_PAIR,       CH_FRONT_PAIR      },
855     { CH_WIDE_PAIR,       CH_CENTER_PAIR     },
856     { CH_WIDE_PAIR,       AV_CH_FRONT_CENTER },
857     { AV_CH_FRONT_CENTER, CH_FRONT_PAIR      },
858     { AV_CH_FRONT_CENTER, CH_CENTER_PAIR     },
859     { AV_CH_FRONT_CENTER, CH_WIDE_PAIR       },
860     { CH_SIDE_PAIR,       CH_DIRECT_PAIR     },
861     { CH_SIDE_PAIR,       CH_BACK_PAIR       },
862     { CH_SIDE_PAIR,       AV_CH_BACK_CENTER  },
863     { CH_BACK_PAIR,       CH_DIRECT_PAIR     },
864     { CH_BACK_PAIR,       CH_SIDE_PAIR       },
865     { CH_BACK_PAIR,       AV_CH_BACK_CENTER  },
866     { AV_CH_BACK_CENTER,  CH_BACK_PAIR       },
867     { AV_CH_BACK_CENTER,  CH_DIRECT_PAIR     },
868     { AV_CH_BACK_CENTER,  CH_SIDE_PAIR       },
869 };
870 
swap_channel_layouts_on_filter(AVFilterContext * filter)871 static void swap_channel_layouts_on_filter(AVFilterContext *filter)
872 {
873     AVFilterLink *link = NULL;
874     int i, j, k;
875 
876     for (i = 0; i < filter->nb_inputs; i++) {
877         link = filter->inputs[i];
878 
879         if (link->type == AVMEDIA_TYPE_AUDIO &&
880             link->outcfg.channel_layouts->nb_channel_layouts == 1)
881             break;
882     }
883     if (i == filter->nb_inputs)
884         return;
885 
886     for (i = 0; i < filter->nb_outputs; i++) {
887         AVFilterLink *outlink = filter->outputs[i];
888         int best_idx = -1, best_score = INT_MIN, best_count_diff = INT_MAX;
889 
890         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
891             outlink->incfg.channel_layouts->nb_channel_layouts < 2)
892             continue;
893 
894         for (j = 0; j < outlink->incfg.channel_layouts->nb_channel_layouts; j++) {
895             AVChannelLayout in_chlayout = { 0 }, out_chlayout = { 0 };
896             int  in_channels;
897             int out_channels;
898             int count_diff;
899             int matched_channels, extra_channels;
900             int score = 100000;
901 
902             av_channel_layout_copy(&in_chlayout, &link->outcfg.channel_layouts->channel_layouts[0]);
903             av_channel_layout_copy(&out_chlayout, &outlink->incfg.channel_layouts->channel_layouts[j]);
904             in_channels            = in_chlayout.nb_channels;
905             out_channels           = out_chlayout.nb_channels;
906             count_diff             = out_channels - in_channels;
907             if (!KNOWN(&in_chlayout) || !KNOWN(&out_chlayout)) {
908                 /* Compute score in case the input or output layout encodes
909                    a channel count; in this case the score is not altered by
910                    the computation afterwards, as in_chlayout and
911                    out_chlayout have both been set to 0 */
912                 if (!KNOWN(&in_chlayout))
913                     in_channels = FF_LAYOUT2COUNT(&in_chlayout);
914                 if (!KNOWN(&out_chlayout))
915                     out_channels = FF_LAYOUT2COUNT(&out_chlayout);
916                 score -= 10000 + FFABS(out_channels - in_channels) +
917                          (in_channels > out_channels ? 10000 : 0);
918                 av_channel_layout_uninit(&in_chlayout);
919                 av_channel_layout_uninit(&out_chlayout);
920                 /* Let the remaining computation run, even if the score
921                    value is not altered */
922             }
923 
924             /* channel substitution */
925             for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) {
926                 uint64_t cmp0 = ch_subst[k][0];
927                 uint64_t cmp1 = ch_subst[k][1];
928                 if ( av_channel_layout_subset(& in_chlayout, cmp0) &&
929                     !av_channel_layout_subset(&out_chlayout, cmp0) &&
930                      av_channel_layout_subset(&out_chlayout, cmp1) &&
931                     !av_channel_layout_subset(& in_chlayout, cmp1)) {
932                     av_channel_layout_from_mask(&in_chlayout, av_channel_layout_subset(& in_chlayout, ~cmp0));
933                     av_channel_layout_from_mask(&out_chlayout, av_channel_layout_subset(&out_chlayout, ~cmp1));
934                     /* add score for channel match, minus a deduction for
935                        having to do the substitution */
936                     score += 10 * av_popcount64(cmp1) - 2;
937                 }
938             }
939 
940             /* no penalty for LFE channel mismatch */
941             if (av_channel_layout_channel_from_index(&in_chlayout,  AV_CHAN_LOW_FREQUENCY) >= 0 &&
942                 av_channel_layout_channel_from_index(&out_chlayout, AV_CHAN_LOW_FREQUENCY) >= 0)
943                 score += 10;
944             av_channel_layout_from_mask(&in_chlayout, av_channel_layout_subset(&in_chlayout, ~AV_CH_LOW_FREQUENCY));
945             av_channel_layout_from_mask(&out_chlayout, av_channel_layout_subset(&out_chlayout, ~AV_CH_LOW_FREQUENCY));
946 
947             matched_channels = av_popcount64(in_chlayout.u.mask & out_chlayout.u.mask);
948             extra_channels   = av_popcount64(out_chlayout.u.mask & (~in_chlayout.u.mask));
949             score += 10 * matched_channels - 5 * extra_channels;
950 
951             if (score > best_score ||
952                 (count_diff < best_count_diff && score == best_score)) {
953                 best_score = score;
954                 best_idx   = j;
955                 best_count_diff = count_diff;
956             }
957         }
958         av_assert0(best_idx >= 0);
959         FFSWAP(AVChannelLayout, outlink->incfg.channel_layouts->channel_layouts[0],
960                outlink->incfg.channel_layouts->channel_layouts[best_idx]);
961     }
962 
963 }
964 
swap_channel_layouts(AVFilterGraph * graph)965 static void swap_channel_layouts(AVFilterGraph *graph)
966 {
967     int i;
968 
969     for (i = 0; i < graph->nb_filters; i++)
970         swap_channel_layouts_on_filter(graph->filters[i]);
971 }
972 
swap_sample_fmts_on_filter(AVFilterContext * filter)973 static void swap_sample_fmts_on_filter(AVFilterContext *filter)
974 {
975     AVFilterLink *link = NULL;
976     int format, bps;
977     int i, j;
978 
979     for (i = 0; i < filter->nb_inputs; i++) {
980         link = filter->inputs[i];
981 
982         if (link->type == AVMEDIA_TYPE_AUDIO &&
983             link->outcfg.formats->nb_formats == 1)
984             break;
985     }
986     if (i == filter->nb_inputs)
987         return;
988 
989     format = link->outcfg.formats->formats[0];
990     bps    = av_get_bytes_per_sample(format);
991 
992     for (i = 0; i < filter->nb_outputs; i++) {
993         AVFilterLink *outlink = filter->outputs[i];
994         int best_idx = -1, best_score = INT_MIN;
995 
996         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
997             outlink->incfg.formats->nb_formats < 2)
998             continue;
999 
1000         for (j = 0; j < outlink->incfg.formats->nb_formats; j++) {
1001             int out_format = outlink->incfg.formats->formats[j];
1002             int out_bps    = av_get_bytes_per_sample(out_format);
1003             int score;
1004 
1005             if (av_get_packed_sample_fmt(out_format) == format ||
1006                 av_get_planar_sample_fmt(out_format) == format) {
1007                 best_idx   = j;
1008                 break;
1009             }
1010 
1011             /* for s32 and float prefer double to prevent loss of information */
1012             if (bps == 4 && out_bps == 8) {
1013                 best_idx = j;
1014                 break;
1015             }
1016 
1017             /* prefer closest higher or equal bps */
1018             score = -abs(out_bps - bps);
1019             if (out_bps >= bps)
1020                 score += INT_MAX/2;
1021 
1022             if (score > best_score) {
1023                 best_score = score;
1024                 best_idx   = j;
1025             }
1026         }
1027         av_assert0(best_idx >= 0);
1028         FFSWAP(int, outlink->incfg.formats->formats[0],
1029                outlink->incfg.formats->formats[best_idx]);
1030     }
1031 }
1032 
swap_sample_fmts(AVFilterGraph * graph)1033 static void swap_sample_fmts(AVFilterGraph *graph)
1034 {
1035     int i;
1036 
1037     for (i = 0; i < graph->nb_filters; i++)
1038         swap_sample_fmts_on_filter(graph->filters[i]);
1039 
1040 }
1041 
pick_formats(AVFilterGraph * graph)1042 static int pick_formats(AVFilterGraph *graph)
1043 {
1044     int i, j, ret;
1045     int change;
1046 
1047     do{
1048         change = 0;
1049         for (i = 0; i < graph->nb_filters; i++) {
1050             AVFilterContext *filter = graph->filters[i];
1051             if (filter->nb_inputs){
1052                 for (j = 0; j < filter->nb_inputs; j++){
1053                     if (filter->inputs[j]->incfg.formats && filter->inputs[j]->incfg.formats->nb_formats == 1) {
1054                         if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
1055                             return ret;
1056                         change = 1;
1057                     }
1058                 }
1059             }
1060             if (filter->nb_outputs){
1061                 for (j = 0; j < filter->nb_outputs; j++){
1062                     if (filter->outputs[j]->incfg.formats && filter->outputs[j]->incfg.formats->nb_formats == 1) {
1063                         if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
1064                             return ret;
1065                         change = 1;
1066                     }
1067                 }
1068             }
1069             if (filter->nb_inputs && filter->nb_outputs && filter->inputs[0]->format>=0) {
1070                 for (j = 0; j < filter->nb_outputs; j++) {
1071                     if (filter->outputs[j]->format<0) {
1072                         if ((ret = pick_format(filter->outputs[j], filter->inputs[0])) < 0)
1073                             return ret;
1074                         change = 1;
1075                     }
1076                 }
1077             }
1078         }
1079     }while(change);
1080 
1081     for (i = 0; i < graph->nb_filters; i++) {
1082         AVFilterContext *filter = graph->filters[i];
1083 
1084         for (j = 0; j < filter->nb_inputs; j++)
1085             if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
1086                 return ret;
1087         for (j = 0; j < filter->nb_outputs; j++)
1088             if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
1089                 return ret;
1090     }
1091     return 0;
1092 }
1093 
1094 /**
1095  * Configure the formats of all the links in the graph.
1096  */
graph_config_formats(AVFilterGraph * graph,void * log_ctx)1097 static int graph_config_formats(AVFilterGraph *graph, void *log_ctx)
1098 {
1099     int ret;
1100 
1101     /* find supported formats from sub-filters, and merge along links */
1102     while ((ret = query_formats(graph, log_ctx)) == AVERROR(EAGAIN))
1103         av_log(graph, AV_LOG_DEBUG, "query_formats not finished\n");
1104     if (ret < 0)
1105         return ret;
1106 
1107     /* Once everything is merged, it's possible that we'll still have
1108      * multiple valid media format choices. We try to minimize the amount
1109      * of format conversion inside filters */
1110     if ((ret = reduce_formats(graph)) < 0)
1111         return ret;
1112 
1113     /* for audio filters, ensure the best format, sample rate and channel layout
1114      * is selected */
1115     swap_sample_fmts(graph);
1116     swap_samplerates(graph);
1117     swap_channel_layouts(graph);
1118 
1119     if ((ret = pick_formats(graph)) < 0)
1120         return ret;
1121 
1122     return 0;
1123 }
1124 
graph_config_pointers(AVFilterGraph * graph,void * log_ctx)1125 static int graph_config_pointers(AVFilterGraph *graph, void *log_ctx)
1126 {
1127     unsigned i, j;
1128     int sink_links_count = 0, n = 0;
1129     AVFilterContext *f;
1130     AVFilterLink **sinks;
1131 
1132     for (i = 0; i < graph->nb_filters; i++) {
1133         f = graph->filters[i];
1134         for (j = 0; j < f->nb_inputs; j++) {
1135             f->inputs[j]->graph     = graph;
1136             f->inputs[j]->age_index = -1;
1137         }
1138         for (j = 0; j < f->nb_outputs; j++) {
1139             f->outputs[j]->graph    = graph;
1140             f->outputs[j]->age_index= -1;
1141         }
1142         if (!f->nb_outputs) {
1143             if (f->nb_inputs > INT_MAX - sink_links_count)
1144                 return AVERROR(EINVAL);
1145             sink_links_count += f->nb_inputs;
1146         }
1147     }
1148     sinks = av_calloc(sink_links_count, sizeof(*sinks));
1149     if (!sinks)
1150         return AVERROR(ENOMEM);
1151     for (i = 0; i < graph->nb_filters; i++) {
1152         f = graph->filters[i];
1153         if (!f->nb_outputs) {
1154             for (j = 0; j < f->nb_inputs; j++) {
1155                 sinks[n] = f->inputs[j];
1156                 f->inputs[j]->age_index = n++;
1157             }
1158         }
1159     }
1160     av_assert0(n == sink_links_count);
1161     graph->sink_links       = sinks;
1162     graph->sink_links_count = sink_links_count;
1163     return 0;
1164 }
1165 
avfilter_graph_config(AVFilterGraph * graphctx,void * log_ctx)1166 int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
1167 {
1168     int ret;
1169 
1170     if ((ret = graph_check_validity(graphctx, log_ctx)))
1171         return ret;
1172     if ((ret = graph_config_formats(graphctx, log_ctx)))
1173         return ret;
1174     if ((ret = graph_config_links(graphctx, log_ctx)))
1175         return ret;
1176     if ((ret = graph_check_links(graphctx, log_ctx)))
1177         return ret;
1178     if ((ret = graph_config_pointers(graphctx, log_ctx)))
1179         return ret;
1180 
1181     return 0;
1182 }
1183 
avfilter_graph_send_command(AVFilterGraph * graph,const char * target,const char * cmd,const char * arg,char * res,int res_len,int flags)1184 int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags)
1185 {
1186     int i, r = AVERROR(ENOSYS);
1187 
1188     if (!graph)
1189         return r;
1190 
1191     if ((flags & AVFILTER_CMD_FLAG_ONE) && !(flags & AVFILTER_CMD_FLAG_FAST)) {
1192         r = avfilter_graph_send_command(graph, target, cmd, arg, res, res_len, flags | AVFILTER_CMD_FLAG_FAST);
1193         if (r != AVERROR(ENOSYS))
1194             return r;
1195     }
1196 
1197     if (res_len && res)
1198         res[0] = 0;
1199 
1200     for (i = 0; i < graph->nb_filters; i++) {
1201         AVFilterContext *filter = graph->filters[i];
1202         if (!strcmp(target, "all") || (filter->name && !strcmp(target, filter->name)) || !strcmp(target, filter->filter->name)) {
1203             r = avfilter_process_command(filter, cmd, arg, res, res_len, flags);
1204             if (r != AVERROR(ENOSYS)) {
1205                 if ((flags & AVFILTER_CMD_FLAG_ONE) || r < 0)
1206                     return r;
1207             }
1208         }
1209     }
1210 
1211     return r;
1212 }
1213 
avfilter_graph_queue_command(AVFilterGraph * graph,const char * target,const char * command,const char * arg,int flags,double ts)1214 int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *command, const char *arg, int flags, double ts)
1215 {
1216     int i;
1217 
1218     if(!graph)
1219         return 0;
1220 
1221     for (i = 0; i < graph->nb_filters; i++) {
1222         AVFilterContext *filter = graph->filters[i];
1223         if(filter && (!strcmp(target, "all") || !strcmp(target, filter->name) || !strcmp(target, filter->filter->name))){
1224             AVFilterCommand **queue = &filter->command_queue, *next;
1225             while (*queue && (*queue)->time <= ts)
1226                 queue = &(*queue)->next;
1227             next = *queue;
1228             *queue = av_mallocz(sizeof(AVFilterCommand));
1229             if (!*queue)
1230                 return AVERROR(ENOMEM);
1231 
1232             (*queue)->command = av_strdup(command);
1233             (*queue)->arg     = av_strdup(arg);
1234             (*queue)->time    = ts;
1235             (*queue)->flags   = flags;
1236             (*queue)->next    = next;
1237             if(flags & AVFILTER_CMD_FLAG_ONE)
1238                 return 0;
1239         }
1240     }
1241 
1242     return 0;
1243 }
1244 
heap_bubble_up(AVFilterGraph * graph,AVFilterLink * link,int index)1245 static void heap_bubble_up(AVFilterGraph *graph,
1246                            AVFilterLink *link, int index)
1247 {
1248     AVFilterLink **links = graph->sink_links;
1249 
1250     av_assert0(index >= 0);
1251 
1252     while (index) {
1253         int parent = (index - 1) >> 1;
1254         if (links[parent]->current_pts_us >= link->current_pts_us)
1255             break;
1256         links[index] = links[parent];
1257         links[index]->age_index = index;
1258         index = parent;
1259     }
1260     links[index] = link;
1261     link->age_index = index;
1262 }
1263 
heap_bubble_down(AVFilterGraph * graph,AVFilterLink * link,int index)1264 static void heap_bubble_down(AVFilterGraph *graph,
1265                              AVFilterLink *link, int index)
1266 {
1267     AVFilterLink **links = graph->sink_links;
1268 
1269     av_assert0(index >= 0);
1270 
1271     while (1) {
1272         int child = 2 * index + 1;
1273         if (child >= graph->sink_links_count)
1274             break;
1275         if (child + 1 < graph->sink_links_count &&
1276             links[child + 1]->current_pts_us < links[child]->current_pts_us)
1277             child++;
1278         if (link->current_pts_us < links[child]->current_pts_us)
1279             break;
1280         links[index] = links[child];
1281         links[index]->age_index = index;
1282         index = child;
1283     }
1284     links[index] = link;
1285     link->age_index = index;
1286 }
1287 
ff_avfilter_graph_update_heap(AVFilterGraph * graph,AVFilterLink * link)1288 void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link)
1289 {
1290     heap_bubble_up  (graph, link, link->age_index);
1291     heap_bubble_down(graph, link, link->age_index);
1292 }
1293 
avfilter_graph_request_oldest(AVFilterGraph * graph)1294 int avfilter_graph_request_oldest(AVFilterGraph *graph)
1295 {
1296     AVFilterLink *oldest = graph->sink_links[0];
1297     int64_t frame_count;
1298     int r;
1299 
1300     while (graph->sink_links_count) {
1301         oldest = graph->sink_links[0];
1302         if (oldest->dst->filter->activate) {
1303             /* For now, buffersink is the only filter implementing activate. */
1304             r = av_buffersink_get_frame_flags(oldest->dst, NULL,
1305                                               AV_BUFFERSINK_FLAG_PEEK);
1306             if (r != AVERROR_EOF)
1307                 return r;
1308         } else {
1309             r = ff_request_frame(oldest);
1310         }
1311         if (r != AVERROR_EOF)
1312             break;
1313         av_log(oldest->dst, AV_LOG_DEBUG, "EOF on sink link %s:%s.\n",
1314                oldest->dst->name,
1315                oldest->dstpad->name);
1316         /* EOF: remove the link from the heap */
1317         if (oldest->age_index < --graph->sink_links_count)
1318             heap_bubble_down(graph, graph->sink_links[graph->sink_links_count],
1319                              oldest->age_index);
1320         oldest->age_index = -1;
1321     }
1322     if (!graph->sink_links_count)
1323         return AVERROR_EOF;
1324     av_assert1(!oldest->dst->filter->activate);
1325     av_assert1(oldest->age_index >= 0);
1326     frame_count = oldest->frame_count_out;
1327     while (frame_count == oldest->frame_count_out) {
1328         r = ff_filter_graph_run_once(graph);
1329         if (r == AVERROR(EAGAIN) &&
1330             !oldest->frame_wanted_out && !oldest->frame_blocked_in &&
1331             !oldest->status_in)
1332             ff_request_frame(oldest);
1333         else if (r < 0)
1334             return r;
1335     }
1336     return 0;
1337 }
1338 
ff_filter_graph_run_once(AVFilterGraph * graph)1339 int ff_filter_graph_run_once(AVFilterGraph *graph)
1340 {
1341     AVFilterContext *filter;
1342     unsigned i;
1343 
1344     av_assert0(graph->nb_filters);
1345     filter = graph->filters[0];
1346     for (i = 1; i < graph->nb_filters; i++)
1347         if (graph->filters[i]->ready > filter->ready)
1348             filter = graph->filters[i];
1349     if (!filter->ready)
1350         return AVERROR(EAGAIN);
1351     return ff_filter_activate(filter);
1352 }
1353