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