FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/avfiltergraph.c
Date: 2022-12-05 03:11:11
Exec Total Coverage
Lines: 544 701 77.6%
Functions: 34 37 91.9%
Branches: 441 643 68.6%

Line Branch Exec Source
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
70 void ff_graph_thread_free(AVFilterGraph *graph)
71 {
72 }
73
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
82 6418 AVFilterGraph *avfilter_graph_alloc(void)
83 {
84 6418 AVFilterGraph *ret = av_mallocz(sizeof(*ret));
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6418 times.
6418 if (!ret)
86 return NULL;
87
88 6418 ret->internal = av_mallocz(sizeof(*ret->internal));
89
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6418 times.
6418 if (!ret->internal) {
90 av_freep(&ret);
91 return NULL;
92 }
93
94 6418 ret->av_class = &filtergraph_class;
95 6418 av_opt_set_defaults(ret);
96 6418 ff_framequeue_global_init(&ret->internal->frame_queues);
97
98 6418 return ret;
99 }
100
101 31695 void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter)
102 {
103 int i, j;
104
1/2
✓ Branch 0 taken 31695 times.
✗ Branch 1 not taken.
31695 for (i = 0; i < graph->nb_filters; i++) {
105
1/2
✓ Branch 0 taken 31695 times.
✗ Branch 1 not taken.
31695 if (graph->filters[i] == filter) {
106 31695 FFSWAP(AVFilterContext*, graph->filters[i],
107 graph->filters[graph->nb_filters - 1]);
108 31695 graph->nb_filters--;
109 31695 filter->graph = NULL;
110
2/2
✓ Branch 0 taken 25467 times.
✓ Branch 1 taken 31695 times.
57162 for (j = 0; j<filter->nb_outputs; j++)
111
2/2
✓ Branch 0 taken 12495 times.
✓ Branch 1 taken 12972 times.
25467 if (filter->outputs[j])
112 12495 filter->outputs[j]->graph = NULL;
113
114 31695 return;
115 }
116 }
117 }
118
119 12591 void avfilter_graph_free(AVFilterGraph **graph)
120 {
121
2/2
✓ Branch 0 taken 6173 times.
✓ Branch 1 taken 6418 times.
12591 if (!*graph)
122 6173 return;
123
124
2/2
✓ Branch 0 taken 31629 times.
✓ Branch 1 taken 6418 times.
38047 while ((*graph)->nb_filters)
125 31629 avfilter_free((*graph)->filters[0]);
126
127 6418 ff_graph_thread_free(*graph);
128
129 6418 av_freep(&(*graph)->sink_links);
130
131 6418 av_opt_free(*graph);
132
133 6418 av_freep(&(*graph)->filters);
134 6418 av_freep(&(*graph)->internal);
135 6418 av_freep(graph);
136 }
137
138 18848 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 18848 *filt_ctx = avfilter_graph_alloc_filter(graph_ctx, filt, name);
145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18848 times.
18848 if (!*filt_ctx)
146 return AVERROR(ENOMEM);
147
148 18848 ret = avfilter_init_str(*filt_ctx, args);
149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18848 times.
18848 if (ret < 0)
150 goto fail;
151
152 18848 return 0;
153
154 fail:
155 avfilter_free(*filt_ctx);
156 *filt_ctx = NULL;
157 return ret;
158 }
159
160 4522 void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
161 {
162 4522 graph->disable_auto_convert = flags;
163 4522 }
164
165 31695 AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph,
166 const AVFilter *filter,
167 const char *name)
168 {
169 AVFilterContext **filters, *s;
170
171
4/4
✓ Branch 0 taken 14656 times.
✓ Branch 1 taken 17039 times.
✓ Branch 2 taken 6418 times.
✓ Branch 3 taken 8238 times.
31695 if (graph->thread_type && !graph->internal->thread_execute) {
172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6418 times.
6418 if (graph->execute) {
173 graph->internal->thread_execute = graph->execute;
174 } else {
175 6418 int ret = ff_graph_thread_init(graph);
176
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6418 times.
6418 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 31695 filters = av_realloc_array(graph->filters, graph->nb_filters + 1, sizeof(*filters));
184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31695 times.
31695 if (!filters)
185 return NULL;
186 31695 graph->filters = filters;
187
188 31695 s = ff_filter_alloc(filter, name);
189
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31695 times.
31695 if (!s)
190 return NULL;
191
192 31695 graph->filters[graph->nb_filters++] = s;
193
194 31695 s->graph = graph;
195
196 31695 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 */
207 6254 static int graph_check_validity(AVFilterGraph *graph, void *log_ctx)
208 {
209 AVFilterContext *filt;
210 int i, j;
211
212
2/2
✓ Branch 0 taken 30421 times.
✓ Branch 1 taken 6254 times.
36675 for (i = 0; i < graph->nb_filters; i++) {
213 const AVFilterPad *pad;
214 30421 filt = graph->filters[i];
215
216
2/2
✓ Branch 0 taken 24174 times.
✓ Branch 1 taken 30421 times.
54595 for (j = 0; j < filt->nb_inputs; j++) {
217
2/4
✓ Branch 0 taken 24174 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24174 times.
24174 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
2/2
✓ Branch 0 taken 24174 times.
✓ Branch 1 taken 30421 times.
54595 for (j = 0; j < filt->nb_outputs; j++) {
227
2/4
✓ Branch 0 taken 24174 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24174 times.
24174 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 6254 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 */
245 6254 static int graph_config_links(AVFilterGraph *graph, void *log_ctx)
246 {
247 AVFilterContext *filt;
248 int i, ret;
249
250
2/2
✓ Branch 0 taken 31381 times.
✓ Branch 1 taken 6254 times.
37635 for (i = 0; i < graph->nb_filters; i++) {
251 31381 filt = graph->filters[i];
252
253
2/2
✓ Branch 0 taken 6267 times.
✓ Branch 1 taken 25114 times.
31381 if (!filt->nb_outputs) {
254
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6267 times.
6267 if ((ret = avfilter_config_links(filt)))
255 return ret;
256 }
257 }
258
259 6254 return 0;
260 }
261
262 6254 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
2/2
✓ Branch 0 taken 31381 times.
✓ Branch 1 taken 6254 times.
37635 for (i = 0; i < graph->nb_filters; i++) {
270 31381 f = graph->filters[i];
271
2/2
✓ Branch 0 taken 25134 times.
✓ Branch 1 taken 31381 times.
56515 for (j = 0; j < f->nb_outputs; j++) {
272 25134 l = f->outputs[j];
273
2/2
✓ Branch 0 taken 20021 times.
✓ Branch 1 taken 5113 times.
25134 if (l->type == AVMEDIA_TYPE_VIDEO) {
274 20021 ret = av_image_check_size2(l->w, l->h, INT64_MAX, l->format, 0, f);
275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20021 times.
20021 if (ret < 0)
276 return ret;
277 }
278 }
279 }
280 6254 return 0;
281 }
282
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
294 40800 static int filter_link_check_formats(void *log, AVFilterLink *link, AVFilterFormatsConfig *cfg)
295 {
296 int ret;
297
298
2/3
✓ Branch 0 taken 32776 times.
✓ Branch 1 taken 8024 times.
✗ Branch 2 not taken.
40800 switch (link->type) {
299
300 32776 case AVMEDIA_TYPE_VIDEO:
301
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32776 times.
32776 if ((ret = ff_formats_check_pixel_formats(log, cfg->formats)) < 0)
302 return ret;
303 32776 break;
304
305 8024 case AVMEDIA_TYPE_AUDIO:
306
2/4
✓ Branch 1 taken 8024 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8024 times.
✗ Branch 4 not taken.
16048 if ((ret = ff_formats_check_sample_formats(log, cfg->formats)) < 0 ||
307
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8024 times.
16048 (ret = ff_formats_check_sample_rates(log, cfg->samplerates)) < 0 ||
308 8024 (ret = ff_formats_check_channel_layouts(log, cfg->channel_layouts)) < 0)
309 return ret;
310 8024 break;
311
312 default:
313 av_assert0(!"reached");
314 }
315 40800 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 */
323 26653 static int filter_check_formats(AVFilterContext *ctx)
324 {
325 unsigned i;
326 int ret;
327
328
2/2
✓ Branch 0 taken 20409 times.
✓ Branch 1 taken 26653 times.
47062 for (i = 0; i < ctx->nb_inputs; i++) {
329 20409 ret = filter_link_check_formats(ctx, ctx->inputs[i], &ctx->inputs[i]->outcfg);
330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20409 times.
20409 if (ret < 0)
331 return ret;
332 }
333
2/2
✓ Branch 0 taken 20391 times.
✓ Branch 1 taken 26653 times.
47044 for (i = 0; i < ctx->nb_outputs; i++) {
334 20391 ret = filter_link_check_formats(ctx, ctx->outputs[i], &ctx->outputs[i]->incfg);
335
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20391 times.
20391 if (ret < 0)
336 return ret;
337 }
338 26653 return 0;
339 }
340
341 26667 static int filter_query_formats(AVFilterContext *ctx)
342 {
343 int ret;
344 AVFilterFormats *formats;
345 AVFilterChannelLayouts *chlayouts;
346
3/4
✓ Branch 0 taken 20377 times.
✓ Branch 1 taken 6290 times.
✓ Branch 2 taken 20377 times.
✗ Branch 3 not taken.
32957 enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
347
2/4
✓ Branch 0 taken 6290 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6290 times.
✗ Branch 3 not taken.
6290 ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
348 AVMEDIA_TYPE_VIDEO;
349
350
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 26653 times.
26667 if ((ret = ctx->filter->formats.query_func(ctx)) < 0) {
351
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 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 14 return ret;
355 }
356 26653 ret = filter_check_formats(ctx);
357
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26653 times.
26653 if (ret < 0)
358 return ret;
359
360 26653 formats = ff_all_formats(type);
361
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26653 times.
26653 if ((ret = ff_set_common_formats(ctx, formats)) < 0)
362 return ret;
363
2/2
✓ Branch 0 taken 5216 times.
✓ Branch 1 taken 21437 times.
26653 if (type == AVMEDIA_TYPE_AUDIO) {
364
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5216 times.
5216 if ((ret = ff_set_common_all_samplerates(ctx)) < 0)
365 return ret;
366 5216 chlayouts = ff_all_channel_layouts();
367
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5216 times.
5216 if ((ret = ff_set_common_channel_layouts(ctx, chlayouts)) < 0)
368 return ret;
369 }
370 26653 return 0;
371 }
372
373 30479 static int formats_declared(AVFilterContext *f)
374 {
375 int i;
376
377
2/2
✓ Branch 0 taken 24154 times.
✓ Branch 1 taken 6360 times.
30514 for (i = 0; i < f->nb_inputs; i++) {
378
2/2
✓ Branch 0 taken 24119 times.
✓ Branch 1 taken 35 times.
24154 if (!f->inputs[i]->outcfg.formats)
379 24119 return 0;
380
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 33 times.
35 if (f->inputs[i]->type == AVMEDIA_TYPE_AUDIO &&
381
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 !(f->inputs[i]->outcfg.samplerates &&
382
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 f->inputs[i]->outcfg.channel_layouts))
383 return 0;
384 }
385
2/2
✓ Branch 0 taken 6350 times.
✓ Branch 1 taken 44 times.
6394 for (i = 0; i < f->nb_outputs; i++) {
386
2/2
✓ Branch 0 taken 6316 times.
✓ Branch 1 taken 34 times.
6350 if (!f->outputs[i]->incfg.formats)
387 6316 return 0;
388
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 31 times.
34 if (f->outputs[i]->type == AVMEDIA_TYPE_AUDIO &&
389
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 !(f->outputs[i]->incfg.samplerates &&
390
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 f->outputs[i]->incfg.channel_layouts))
391 return 0;
392 }
393 44 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 */
406 6268 static int query_formats(AVFilterGraph *graph, void *log_ctx)
407 {
408 int i, j, ret;
409 6268 int converter_count = 0;
410 6268 int count_queried = 0; /* successful calls to query_formats() */
411 6268 int count_merged = 0; /* successful merge of formats lists */
412 6268 int count_already_merged = 0; /* lists already merged */
413 6268 int count_delayed = 0; /* lists that need to be merged later */
414
415
2/2
✓ Branch 0 taken 30479 times.
✓ Branch 1 taken 6268 times.
36747 for (i = 0; i < graph->nb_filters; i++) {
416 30479 AVFilterContext *f = graph->filters[i];
417
2/2
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 30435 times.
30479 if (formats_declared(f))
418 44 continue;
419
2/2
✓ Branch 0 taken 25707 times.
✓ Branch 1 taken 4728 times.
30435 if (f->filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC)
420 25707 ret = filter_query_formats(f);
421 else
422 4728 ret = ff_default_query_formats(f);
423
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 30421 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
30435 if (ret < 0 && ret != AVERROR(EAGAIN))
424 return ret;
425 /* note: EAGAIN could indicate a partial success, not counted yet */
426 30435 count_queried += ret >= 0;
427 }
428
429 /* go through and merge as many format lists as possible */
430
2/2
✓ Branch 0 taken 31439 times.
✓ Branch 1 taken 6268 times.
37707 for (i = 0; i < graph->nb_filters; i++) {
431 31439 AVFilterContext *filter = graph->filters[i];
432
433
2/2
✓ Branch 0 taken 25182 times.
✓ Branch 1 taken 31439 times.
56621 for (j = 0; j < filter->nb_inputs; j++) {
434 25182 AVFilterLink *link = filter->inputs[j];
435 const AVFilterNegotiation *neg;
436 unsigned neg_step;
437 25182 int convert_needed = 0;
438
439
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25182 times.
25182 if (!link)
440 continue;
441
442 25182 neg = ff_filter_get_negotiation(link);
443
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25182 times.
25182 av_assert0(neg);
444
2/2
✓ Branch 0 taken 10217 times.
✓ Branch 1 taken 24776 times.
34993 for (neg_step = 1; neg_step < neg->nb_mergers; neg_step++) {
445 10217 const AVFilterFormatsMerger *m = &neg->mergers[neg_step];
446 10217 void *a = FF_FIELD_AT(void *, m->offset, link->incfg);
447 10217 void *b = FF_FIELD_AT(void *, m->offset, link->outcfg);
448
8/8
✓ Branch 0 taken 10215 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 10211 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 9395 times.
✓ Branch 5 taken 816 times.
✓ Branch 7 taken 406 times.
✓ Branch 8 taken 8989 times.
10217 if (a && b && a != b && !m->can_merge(a, b)) {
449 406 convert_needed = 1;
450 406 break;
451 }
452 }
453
2/2
✓ Branch 0 taken 35416 times.
✓ Branch 1 taken 25182 times.
60598 for (neg_step = 0; neg_step < neg->nb_mergers; neg_step++) {
454 35416 const AVFilterFormatsMerger *m = &neg->mergers[neg_step];
455 35416 void *a = FF_FIELD_AT(void *, m->offset, link->incfg);
456 35416 void *b = FF_FIELD_AT(void *, m->offset, link->outcfg);
457
4/4
✓ Branch 0 taken 35400 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 35383 times.
35416 if (!(a && b)) {
458 33 count_delayed++;
459
2/2
✓ Branch 0 taken 1799 times.
✓ Branch 1 taken 33584 times.
35383 } else if (a == b) {
460 1799 count_already_merged++;
461
2/2
✓ Branch 0 taken 32364 times.
✓ Branch 1 taken 1220 times.
33584 } else if (!convert_needed) {
462 32364 count_merged++;
463 32364 ret = m->merge(a, b);
464
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32364 times.
32364 if (ret < 0)
465 return ret;
466
2/2
✓ Branch 0 taken 554 times.
✓ Branch 1 taken 31810 times.
32364 if (!ret)
467 554 convert_needed = 1;
468 }
469 }
470
471
2/2
✓ Branch 0 taken 960 times.
✓ Branch 1 taken 24222 times.
25182 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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 960 times.
960 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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 960 times.
960 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 960 snprintf(inst_name, sizeof(inst_name), "auto_%s_%d",
494 960 neg->conversion_filter, converter_count++);
495 960 opts = FF_FIELD_AT(char *, neg->conversion_opts_offset, *graph);
496 960 ret = avfilter_graph_create_filter(&convert, filter, inst_name, opts, NULL, graph);
497
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 960 times.
960 if (ret < 0)
498 return ret;
499
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 960 times.
960 if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
500 return ret;
501
502
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 960 times.
960 if ((ret = filter_query_formats(convert)) < 0)
503 return ret;
504
505 960 inlink = convert->inputs[0];
506 960 outlink = convert->outputs[0];
507
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 960 times.
960 av_assert0( inlink->incfg.formats->refcount > 0);
508
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 960 times.
960 av_assert0( inlink->outcfg.formats->refcount > 0);
509
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 960 times.
960 av_assert0(outlink->incfg.formats->refcount > 0);
510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 960 times.
960 av_assert0(outlink->outcfg.formats->refcount > 0);
511
2/2
✓ Branch 0 taken 407 times.
✓ Branch 1 taken 553 times.
960 if (outlink->type == AVMEDIA_TYPE_AUDIO) {
512
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 407 times.
407 av_assert0( inlink-> incfg.samplerates->refcount > 0);
513
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 407 times.
407 av_assert0( inlink->outcfg.samplerates->refcount > 0);
514
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 407 times.
407 av_assert0(outlink-> incfg.samplerates->refcount > 0);
515
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 407 times.
407 av_assert0(outlink->outcfg.samplerates->refcount > 0);
516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 407 times.
407 av_assert0( inlink-> incfg.channel_layouts->refcount > 0);
517
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 407 times.
407 av_assert0( inlink->outcfg.channel_layouts->refcount > 0);
518
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 407 times.
407 av_assert0(outlink-> incfg.channel_layouts->refcount > 0);
519
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 407 times.
407 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
2/2
✓ Branch 0 taken 1774 times.
✓ Branch 1 taken 960 times.
2734 for (neg_step = 0; neg_step < neg->nb_mergers; neg_step++) {
525 1774 const AVFilterFormatsMerger *m = &neg->mergers[neg_step];
526
2/4
✓ Branch 1 taken 1774 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1774 times.
3548 if ((ret = MERGE(m, inlink)) <= 0 ||
527 1774 (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 6268 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
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 6254 times.
6268 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
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 if (count_queried || count_merged)
552 14 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 6254 return 0;
565 }
566
567 296 static int get_fmt_score(enum AVSampleFormat dst_fmt, enum AVSampleFormat src_fmt)
568 {
569 296 int score = 0;
570
571
2/2
✓ Branch 2 taken 254 times.
✓ Branch 3 taken 42 times.
296 if (av_sample_fmt_is_planar(dst_fmt) != av_sample_fmt_is_planar(src_fmt))
572 254 score ++;
573
574
2/2
✓ Branch 2 taken 100 times.
✓ Branch 3 taken 196 times.
296 if (av_get_bytes_per_sample(dst_fmt) < av_get_bytes_per_sample(src_fmt)) {
575 100 score += 100 * (av_get_bytes_per_sample(src_fmt) - av_get_bytes_per_sample(dst_fmt));
576 }else
577 196 score += 10 * (av_get_bytes_per_sample(dst_fmt) - av_get_bytes_per_sample(src_fmt));
578
579
3/4
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 260 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 36 times.
332 if (av_get_packed_sample_fmt(dst_fmt) == AV_SAMPLE_FMT_S32 &&
580 36 av_get_packed_sample_fmt(src_fmt) == AV_SAMPLE_FMT_FLT)
581 score += 20;
582
583
3/4
✓ Branch 1 taken 42 times.
✓ Branch 2 taken 254 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 42 times.
338 if (av_get_packed_sample_fmt(dst_fmt) == AV_SAMPLE_FMT_FLT &&
584 42 av_get_packed_sample_fmt(src_fmt) == AV_SAMPLE_FMT_S32)
585 score += 2;
586
587 296 return score;
588 }
589
590 148 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 148 score1 = get_fmt_score(dst_fmt1, src_fmt);
596 148 score2 = get_fmt_score(dst_fmt2, src_fmt);
597
598
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 36 times.
148 return score1 < score2 ? dst_fmt1 : dst_fmt2;
599 }
600
601 75360 static int pick_format(AVFilterLink *link, AVFilterLink *ref)
602 {
603
3/4
✓ Branch 0 taken 75360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 50226 times.
✓ Branch 3 taken 25134 times.
75360 if (!link || !link->incfg.formats)
604 50226 return 0;
605
606
2/2
✓ Branch 0 taken 20021 times.
✓ Branch 1 taken 5113 times.
25134 if (link->type == AVMEDIA_TYPE_VIDEO) {
607
3/4
✓ Branch 0 taken 97 times.
✓ Branch 1 taken 19924 times.
✓ Branch 2 taken 97 times.
✗ Branch 3 not taken.
20021 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 97 int has_alpha= av_pix_fmt_desc_get(ref->format)->nb_components % 2 == 0;
610 97 enum AVPixelFormat best= AV_PIX_FMT_NONE;
611 int i;
612
2/2
✓ Branch 0 taken 950 times.
✓ Branch 1 taken 97 times.
1047 for (i = 0; i < link->incfg.formats->nb_formats; i++) {
613 950 enum AVPixelFormat p = link->incfg.formats->formats[i];
614 950 best= av_find_best_pix_fmt_of_2(best, p, ref->format, has_alpha, NULL);
615 }
616 97 av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s alpha:%d\n",
617 97 av_get_pix_fmt_name(best), link->incfg.formats->nb_formats,
618 97 av_get_pix_fmt_name(ref->format), has_alpha);
619 97 link->incfg.formats->formats[0] = best;
620 }
621
1/2
✓ Branch 0 taken 5113 times.
✗ Branch 1 not taken.
5113 } else if (link->type == AVMEDIA_TYPE_AUDIO) {
622
3/4
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 5077 times.
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
5113 if(ref && ref->type == AVMEDIA_TYPE_AUDIO){
623 36 enum AVSampleFormat best= AV_SAMPLE_FMT_NONE;
624 int i;
625
2/2
✓ Branch 0 taken 148 times.
✓ Branch 1 taken 36 times.
184 for (i = 0; i < link->incfg.formats->nb_formats; i++) {
626 148 enum AVSampleFormat p = link->incfg.formats->formats[i];
627 148 best = find_best_sample_fmt_of_2(best, p, ref->format);
628 }
629 36 av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s\n",
630 36 av_get_sample_fmt_name(best), link->incfg.formats->nb_formats,
631 36 av_get_sample_fmt_name(ref->format));
632 36 link->incfg.formats->formats[0] = best;
633 }
634 }
635
636 25134 link->incfg.formats->nb_formats = 1;
637 25134 link->format = link->incfg.formats->formats[0];
638
639
2/2
✓ Branch 0 taken 5113 times.
✓ Branch 1 taken 20021 times.
25134 if (link->type == AVMEDIA_TYPE_AUDIO) {
640 int ret;
641
642
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5113 times.
5113 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 5113 link->incfg.samplerates->nb_formats = 1;
649 5113 link->sample_rate = link->incfg.samplerates->formats[0];
650
651
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5113 times.
5113 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 5113 link->incfg.channel_layouts->nb_channel_layouts = 1;
662 5113 ret = av_channel_layout_copy(&link->ch_layout, &link->incfg.channel_layouts->channel_layouts[0]);
663
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5113 times.
5113 if (ret < 0)
664 return ret;
665 #if FF_API_OLD_CHANNEL_LAYOUT
666 FF_DISABLE_DEPRECATION_WARNINGS
667 5113 link->channel_layout = link->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ?
668
2/2
✓ Branch 0 taken 5067 times.
✓ Branch 1 taken 46 times.
5113 link->ch_layout.u.mask : 0;
669 FF_ENABLE_DEPRECATION_WARNINGS
670 #endif
671 }
672
673 25134 ff_formats_unref(&link->incfg.formats);
674 25134 ff_formats_unref(&link->outcfg.formats);
675 25134 ff_formats_unref(&link->incfg.samplerates);
676 25134 ff_formats_unref(&link->outcfg.samplerates);
677 25134 ff_channel_layouts_unref(&link->incfg.channel_layouts);
678 25134 ff_channel_layouts_unref(&link->outcfg.channel_layouts);
679
680 25134 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
720 34325 static int reduce_formats_on_filter(AVFilterContext *filter)
721 {
722 34325 int i, j, k, ret = 0;
723
724
16/20
✓ Branch 0 taken 27470 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 402 times.
✓ Branch 3 taken 27068 times.
✓ Branch 4 taken 20388 times.
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 20154 times.
✓ Branch 7 taken 234 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 234 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 51 times.
✓ Branch 14 taken 2506 times.
✓ Branch 15 taken 2557 times.
✓ Branch 16 taken 183 times.
✓ Branch 17 taken 20400 times.
✓ Branch 18 taken 27068 times.
✓ Branch 19 taken 27470 times.
✓ Branch 20 taken 34325 times.
84701 REDUCE_FORMATS(int, AVFilterFormats, formats, formats,
725 nb_formats, ff_add_format);
726
18/20
✓ Branch 0 taken 7228 times.
✓ Branch 1 taken 20242 times.
✓ Branch 2 taken 766 times.
✓ Branch 3 taken 6462 times.
✓ Branch 4 taken 5068 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 4481 times.
✓ Branch 7 taken 587 times.
✓ Branch 8 taken 551 times.
✓ Branch 9 taken 36 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 551 times.
✓ Branch 13 taken 36 times.
✓ Branch 14 taken 71 times.
✓ Branch 15 taken 107 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 5074 times.
✓ Branch 18 taken 5911 times.
✓ Branch 19 taken 27470 times.
✓ Branch 20 taken 34325 times.
66389 REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats,
727 nb_formats, ff_add_format);
728
729 /* reduce channel layouts */
730
2/2
✓ Branch 0 taken 27470 times.
✓ Branch 1 taken 34325 times.
61795 for (i = 0; i < filter->nb_inputs; i++) {
731 27470 AVFilterLink *inlink = filter->inputs[i];
732 const AVChannelLayout *fmt;
733
734
2/2
✓ Branch 0 taken 7228 times.
✓ Branch 1 taken 20242 times.
27470 if (!inlink->outcfg.channel_layouts ||
735
2/2
✓ Branch 0 taken 780 times.
✓ Branch 1 taken 6448 times.
7228 inlink->outcfg.channel_layouts->nb_channel_layouts != 1)
736 21022 continue;
737 6448 fmt = &inlink->outcfg.channel_layouts->channel_layouts[0];
738
739
2/2
✓ Branch 0 taken 5067 times.
✓ Branch 1 taken 5271 times.
10338 for (j = 0; j < filter->nb_outputs; j++) {
740 5067 AVFilterLink *outlink = filter->outputs[j];
741 AVFilterChannelLayouts *fmts;
742
743 5067 fmts = outlink->incfg.channel_layouts;
744
4/4
✓ Branch 0 taken 5061 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 3845 times.
✓ Branch 3 taken 1216 times.
5067 if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1)
745 3851 continue;
746
747
2/2
✓ Branch 0 taken 1177 times.
✓ Branch 1 taken 39 times.
1216 if (fmts->all_layouts &&
748
4/6
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1172 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
1177 (KNOWN(fmt) || fmts->all_counts)) {
749 /* Turn the infinite list into a singleton */
750 1177 fmts->all_layouts = fmts->all_counts = 0;
751
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1177 times.
1177 if (ff_add_channel_layout(&outlink->incfg.channel_layouts, fmt) < 0)
752 ret = 1;
753 1177 break;
754 }
755
756
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 4 times.
94 for (k = 0; k < outlink->incfg.channel_layouts->nb_channel_layouts; k++) {
757
2/2
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 55 times.
90 if (!av_channel_layout_compare(&fmts->channel_layouts[k], fmt)) {
758 35 ret = av_channel_layout_copy(&fmts->channel_layouts[0], fmt);
759
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
35 if (ret < 0)
760 return ret;
761 35 fmts->nb_channel_layouts = 1;
762 35 ret = 1;
763 35 break;
764 }
765 }
766 }
767 }
768
769 34325 return ret;
770 }
771
772 6254 static int reduce_formats(AVFilterGraph *graph)
773 {
774 int i, reduced, ret;
775
776 do {
777 6862 reduced = 0;
778
779
2/2
✓ Branch 0 taken 34325 times.
✓ Branch 1 taken 6862 times.
41187 for (i = 0; i < graph->nb_filters; i++) {
780
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 34325 times.
34325 if ((ret = reduce_formats_on_filter(graph->filters[i])) < 0)
781 return ret;
782 34325 reduced |= ret;
783 }
784
2/2
✓ Branch 0 taken 608 times.
✓ Branch 1 taken 6254 times.
6862 } while (reduced);
785
786 6254 return 0;
787 }
788
789 31381 static void swap_samplerates_on_filter(AVFilterContext *filter)
790 {
791 31381 AVFilterLink *link = NULL;
792 int sample_rate;
793 int i, j;
794
795
2/2
✓ Branch 0 taken 25116 times.
✓ Branch 1 taken 26282 times.
51398 for (i = 0; i < filter->nb_inputs; i++) {
796 25116 link = filter->inputs[i];
797
798
2/2
✓ Branch 0 taken 5099 times.
✓ Branch 1 taken 20017 times.
25116 if (link->type == AVMEDIA_TYPE_AUDIO &&
799
1/2
✓ Branch 0 taken 5099 times.
✗ Branch 1 not taken.
5099 link->outcfg.samplerates->nb_formats== 1)
800 5099 break;
801 }
802
2/2
✓ Branch 0 taken 26282 times.
✓ Branch 1 taken 5099 times.
31381 if (i == filter->nb_inputs)
803 26282 return;
804
805 5099 sample_rate = link->outcfg.samplerates->formats[0];
806
807
2/2
✓ Branch 0 taken 3899 times.
✓ Branch 1 taken 5099 times.
8998 for (i = 0; i < filter->nb_outputs; i++) {
808 3899 AVFilterLink *outlink = filter->outputs[i];
809 3899 int best_idx, best_diff = INT_MAX;
810
811
2/2
✓ Branch 0 taken 3897 times.
✓ Branch 1 taken 2 times.
3899 if (outlink->type != AVMEDIA_TYPE_AUDIO ||
812
1/2
✓ Branch 0 taken 3897 times.
✗ Branch 1 not taken.
3897 outlink->incfg.samplerates->nb_formats < 2)
813 3899 continue;
814
815 for (j = 0; j < outlink->incfg.samplerates->nb_formats; j++) {
816 int diff = abs(sample_rate - outlink->incfg.samplerates->formats[j]);
817
818 av_assert0(diff < INT_MAX); // This would lead to the use of uninitialized best_diff but is only possible with invalid sample rates
819
820 if (diff < best_diff) {
821 best_diff = diff;
822 best_idx = j;
823 }
824 }
825 FFSWAP(int, outlink->incfg.samplerates->formats[0],
826 outlink->incfg.samplerates->formats[best_idx]);
827 }
828 }
829
830 6254 static void swap_samplerates(AVFilterGraph *graph)
831 {
832 int i;
833
834
2/2
✓ Branch 0 taken 31381 times.
✓ Branch 1 taken 6254 times.
37635 for (i = 0; i < graph->nb_filters; i++)
835 31381 swap_samplerates_on_filter(graph->filters[i]);
836 6254 }
837
838 #define CH_CENTER_PAIR (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)
839 #define CH_FRONT_PAIR (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT)
840 #define CH_STEREO_PAIR (AV_CH_STEREO_LEFT | AV_CH_STEREO_RIGHT)
841 #define CH_WIDE_PAIR (AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT)
842 #define CH_SIDE_PAIR (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT)
843 #define CH_DIRECT_PAIR (AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT)
844 #define CH_BACK_PAIR (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT)
845
846 /* allowable substitutions for channel pairs when comparing layouts,
847 * ordered by priority for both values */
848 static const uint64_t ch_subst[][2] = {
849 { CH_FRONT_PAIR, CH_CENTER_PAIR },
850 { CH_FRONT_PAIR, CH_WIDE_PAIR },
851 { CH_FRONT_PAIR, AV_CH_FRONT_CENTER },
852 { CH_CENTER_PAIR, CH_FRONT_PAIR },
853 { CH_CENTER_PAIR, CH_WIDE_PAIR },
854 { CH_CENTER_PAIR, AV_CH_FRONT_CENTER },
855 { CH_WIDE_PAIR, CH_FRONT_PAIR },
856 { CH_WIDE_PAIR, CH_CENTER_PAIR },
857 { CH_WIDE_PAIR, AV_CH_FRONT_CENTER },
858 { AV_CH_FRONT_CENTER, CH_FRONT_PAIR },
859 { AV_CH_FRONT_CENTER, CH_CENTER_PAIR },
860 { AV_CH_FRONT_CENTER, CH_WIDE_PAIR },
861 { CH_SIDE_PAIR, CH_DIRECT_PAIR },
862 { CH_SIDE_PAIR, CH_BACK_PAIR },
863 { CH_SIDE_PAIR, AV_CH_BACK_CENTER },
864 { CH_BACK_PAIR, CH_DIRECT_PAIR },
865 { CH_BACK_PAIR, CH_SIDE_PAIR },
866 { CH_BACK_PAIR, AV_CH_BACK_CENTER },
867 { AV_CH_BACK_CENTER, CH_BACK_PAIR },
868 { AV_CH_BACK_CENTER, CH_DIRECT_PAIR },
869 { AV_CH_BACK_CENTER, CH_SIDE_PAIR },
870 };
871
872 31381 static void swap_channel_layouts_on_filter(AVFilterContext *filter)
873 {
874 31381 AVFilterLink *link = NULL;
875 int i, j, k;
876
877
2/2
✓ Branch 0 taken 25116 times.
✓ Branch 1 taken 26286 times.
51402 for (i = 0; i < filter->nb_inputs; i++) {
878 25116 link = filter->inputs[i];
879
880
2/2
✓ Branch 0 taken 5099 times.
✓ Branch 1 taken 20017 times.
25116 if (link->type == AVMEDIA_TYPE_AUDIO &&
881
2/2
✓ Branch 0 taken 5095 times.
✓ Branch 1 taken 4 times.
5099 link->outcfg.channel_layouts->nb_channel_layouts == 1)
882 5095 break;
883 }
884
2/2
✓ Branch 0 taken 26286 times.
✓ Branch 1 taken 5095 times.
31381 if (i == filter->nb_inputs)
885 26286 return;
886
887
2/2
✓ Branch 0 taken 3897 times.
✓ Branch 1 taken 5095 times.
8992 for (i = 0; i < filter->nb_outputs; i++) {
888 3897 AVFilterLink *outlink = filter->outputs[i];
889 3897 int best_idx = -1, best_score = INT_MIN, best_count_diff = INT_MAX;
890
891
2/2
✓ Branch 0 taken 3895 times.
✓ Branch 1 taken 2 times.
3897 if (outlink->type != AVMEDIA_TYPE_AUDIO ||
892
2/2
✓ Branch 0 taken 3893 times.
✓ Branch 1 taken 2 times.
3895 outlink->incfg.channel_layouts->nb_channel_layouts < 2)
893 3895 continue;
894
895
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2 times.
20 for (j = 0; j < outlink->incfg.channel_layouts->nb_channel_layouts; j++) {
896 18 AVChannelLayout in_chlayout = { 0 }, out_chlayout = { 0 };
897 int in_channels;
898 int out_channels;
899 int count_diff;
900 int matched_channels, extra_channels;
901 18 int score = 100000;
902
903 18 av_channel_layout_copy(&in_chlayout, &link->outcfg.channel_layouts->channel_layouts[0]);
904 18 av_channel_layout_copy(&out_chlayout, &outlink->incfg.channel_layouts->channel_layouts[j]);
905 18 in_channels = in_chlayout.nb_channels;
906 18 out_channels = out_chlayout.nb_channels;
907 18 count_diff = out_channels - in_channels;
908
4/8
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
18 if (!KNOWN(&in_chlayout) || !KNOWN(&out_chlayout)) {
909 /* Compute score in case the input or output layout encodes
910 a channel count; in this case the score is not altered by
911 the computation afterwards, as in_chlayout and
912 out_chlayout have both been set to 0 */
913
2/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
16 if (!KNOWN(&in_chlayout))
914
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 in_channels = FF_LAYOUT2COUNT(&in_chlayout);
915
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 if (!KNOWN(&out_chlayout))
916 out_channels = FF_LAYOUT2COUNT(&out_chlayout);
917 32 score -= 10000 + FFABS(out_channels - in_channels) +
918
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 (in_channels > out_channels ? 10000 : 0);
919 16 av_channel_layout_uninit(&in_chlayout);
920 16 av_channel_layout_uninit(&out_chlayout);
921 /* Let the remaining computation run, even if the score
922 value is not altered */
923 }
924
925 /* channel substitution */
926
2/2
✓ Branch 0 taken 378 times.
✓ Branch 1 taken 18 times.
396 for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) {
927 378 uint64_t cmp0 = ch_subst[k][0];
928 378 uint64_t cmp1 = ch_subst[k][1];
929
4/4
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 354 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 6 times.
402 if ( av_channel_layout_subset(& in_chlayout, cmp0) &&
930
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 16 times.
42 !av_channel_layout_subset(&out_chlayout, cmp0) &&
931
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
20 av_channel_layout_subset(&out_chlayout, cmp1) &&
932 2 !av_channel_layout_subset(& in_chlayout, cmp1)) {
933 av_channel_layout_from_mask(&in_chlayout, av_channel_layout_subset(& in_chlayout, ~cmp0));
934 av_channel_layout_from_mask(&out_chlayout, av_channel_layout_subset(&out_chlayout, ~cmp1));
935 /* add score for channel match, minus a deduction for
936 having to do the substitution */
937 score += 10 * av_popcount64(cmp1) - 2;
938 }
939 }
940
941 /* no penalty for LFE channel mismatch */
942
3/4
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
20 if (av_channel_layout_channel_from_index(&in_chlayout, AV_CHAN_LOW_FREQUENCY) >= 0 &&
943 2 av_channel_layout_channel_from_index(&out_chlayout, AV_CHAN_LOW_FREQUENCY) >= 0)
944 score += 10;
945 18 av_channel_layout_from_mask(&in_chlayout, av_channel_layout_subset(&in_chlayout, ~AV_CH_LOW_FREQUENCY));
946 18 av_channel_layout_from_mask(&out_chlayout, av_channel_layout_subset(&out_chlayout, ~AV_CH_LOW_FREQUENCY));
947
948 18 matched_channels = av_popcount64(in_chlayout.u.mask & out_chlayout.u.mask);
949 18 extra_channels = av_popcount64(out_chlayout.u.mask & (~in_chlayout.u.mask));
950 18 score += 10 * matched_channels - 5 * extra_channels;
951
952
3/4
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
18 if (score > best_score ||
953 (count_diff < best_count_diff && score == best_score)) {
954 3 best_score = score;
955 3 best_idx = j;
956 3 best_count_diff = count_diff;
957 }
958 }
959
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 av_assert0(best_idx >= 0);
960 2 FFSWAP(AVChannelLayout, outlink->incfg.channel_layouts->channel_layouts[0],
961 outlink->incfg.channel_layouts->channel_layouts[best_idx]);
962 }
963
964 }
965
966 6254 static void swap_channel_layouts(AVFilterGraph *graph)
967 {
968 int i;
969
970
2/2
✓ Branch 0 taken 31381 times.
✓ Branch 1 taken 6254 times.
37635 for (i = 0; i < graph->nb_filters; i++)
971 31381 swap_channel_layouts_on_filter(graph->filters[i]);
972 6254 }
973
974 31381 static void swap_sample_fmts_on_filter(AVFilterContext *filter)
975 {
976 31381 AVFilterLink *link = NULL;
977 int format, bps;
978 int i, j;
979
980
2/2
✓ Branch 0 taken 25120 times.
✓ Branch 1 taken 26345 times.
51465 for (i = 0; i < filter->nb_inputs; i++) {
981 25120 link = filter->inputs[i];
982
983
2/2
✓ Branch 0 taken 5103 times.
✓ Branch 1 taken 20017 times.
25120 if (link->type == AVMEDIA_TYPE_AUDIO &&
984
2/2
✓ Branch 0 taken 5036 times.
✓ Branch 1 taken 67 times.
5103 link->outcfg.formats->nb_formats == 1)
985 5036 break;
986 }
987
2/2
✓ Branch 0 taken 26345 times.
✓ Branch 1 taken 5036 times.
31381 if (i == filter->nb_inputs)
988 26345 return;
989
990 5036 format = link->outcfg.formats->formats[0];
991 5036 bps = av_get_bytes_per_sample(format);
992
993
2/2
✓ Branch 0 taken 3860 times.
✓ Branch 1 taken 5036 times.
8896 for (i = 0; i < filter->nb_outputs; i++) {
994 3860 AVFilterLink *outlink = filter->outputs[i];
995 3860 int best_idx = -1, best_score = INT_MIN;
996
997
2/2
✓ Branch 0 taken 3858 times.
✓ Branch 1 taken 2 times.
3860 if (outlink->type != AVMEDIA_TYPE_AUDIO ||
998
2/2
✓ Branch 0 taken 3818 times.
✓ Branch 1 taken 40 times.
3858 outlink->incfg.formats->nb_formats < 2)
999 3820 continue;
1000
1001
2/2
✓ Branch 0 taken 125 times.
✓ Branch 1 taken 7 times.
132 for (j = 0; j < outlink->incfg.formats->nb_formats; j++) {
1002 125 int out_format = outlink->incfg.formats->formats[j];
1003 125 int out_bps = av_get_bytes_per_sample(out_format);
1004 int score;
1005
1006
4/4
✓ Branch 1 taken 106 times.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 92 times.
231 if (av_get_packed_sample_fmt(out_format) == format ||
1007 106 av_get_planar_sample_fmt(out_format) == format) {
1008 33 best_idx = j;
1009 33 break;
1010 }
1011
1012 /* for s32 and float prefer double to prevent loss of information */
1013
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
92 if (bps == 4 && out_bps == 8) {
1014 best_idx = j;
1015 break;
1016 }
1017
1018 /* prefer closest higher or equal bps */
1019 92 score = -abs(out_bps - bps);
1020
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 64 times.
92 if (out_bps >= bps)
1021 28 score += INT_MAX/2;
1022
1023
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 34 times.
92 if (score > best_score) {
1024 58 best_score = score;
1025 58 best_idx = j;
1026 }
1027 }
1028
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 av_assert0(best_idx >= 0);
1029 40 FFSWAP(int, outlink->incfg.formats->formats[0],
1030 outlink->incfg.formats->formats[best_idx]);
1031 }
1032 }
1033
1034 6254 static void swap_sample_fmts(AVFilterGraph *graph)
1035 {
1036 int i;
1037
1038
2/2
✓ Branch 0 taken 31381 times.
✓ Branch 1 taken 6254 times.
37635 for (i = 0; i < graph->nb_filters; i++)
1039 31381 swap_sample_fmts_on_filter(graph->filters[i]);
1040
1041 6254 }
1042
1043 6254 static int pick_formats(AVFilterGraph *graph)
1044 {
1045 int i, j, ret;
1046 int change;
1047
1048 do{
1049 12545 change = 0;
1050
2/2
✓ Branch 0 taken 63021 times.
✓ Branch 1 taken 12545 times.
75566 for (i = 0; i < graph->nb_filters; i++) {
1051 63021 AVFilterContext *filter = graph->filters[i];
1052
2/2
✓ Branch 0 taken 50352 times.
✓ Branch 1 taken 12669 times.
63021 if (filter->nb_inputs){
1053
2/2
✓ Branch 0 taken 50495 times.
✓ Branch 1 taken 50352 times.
100847 for (j = 0; j < filter->nb_inputs; j++){
1054
4/4
✓ Branch 0 taken 12412 times.
✓ Branch 1 taken 38083 times.
✓ Branch 2 taken 12204 times.
✓ Branch 3 taken 208 times.
50495 if (filter->inputs[j]->incfg.formats && filter->inputs[j]->incfg.formats->nb_formats == 1) {
1055
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12204 times.
12204 if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
1056 return ret;
1057 12204 change = 1;
1058 }
1059 }
1060 }
1061
2/2
✓ Branch 0 taken 50450 times.
✓ Branch 1 taken 12571 times.
63021 if (filter->nb_outputs){
1062
2/2
✓ Branch 0 taken 50495 times.
✓ Branch 1 taken 50450 times.
100945 for (j = 0; j < filter->nb_outputs; j++){
1063
4/4
✓ Branch 0 taken 13015 times.
✓ Branch 1 taken 37480 times.
✓ Branch 2 taken 12755 times.
✓ Branch 3 taken 260 times.
50495 if (filter->outputs[j]->incfg.formats && filter->outputs[j]->incfg.formats->nb_formats == 1) {
1064
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12755 times.
12755 if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
1065 return ret;
1066 12755 change = 1;
1067 }
1068 }
1069 }
1070
6/6
✓ Branch 0 taken 50352 times.
✓ Branch 1 taken 12669 times.
✓ Branch 2 taken 37781 times.
✓ Branch 3 taken 12571 times.
✓ Branch 4 taken 37674 times.
✓ Branch 5 taken 107 times.
63021 if (filter->nb_inputs && filter->nb_outputs && filter->inputs[0]->format>=0) {
1071
2/2
✓ Branch 0 taken 37717 times.
✓ Branch 1 taken 37674 times.
75391 for (j = 0; j < filter->nb_outputs; j++) {
1072
2/2
✓ Branch 0 taken 133 times.
✓ Branch 1 taken 37584 times.
37717 if (filter->outputs[j]->format<0) {
1073
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 133 times.
133 if ((ret = pick_format(filter->outputs[j], filter->inputs[0])) < 0)
1074 return ret;
1075 133 change = 1;
1076 }
1077 }
1078 }
1079 }
1080
2/2
✓ Branch 0 taken 6291 times.
✓ Branch 1 taken 6254 times.
12545 }while(change);
1081
1082
2/2
✓ Branch 0 taken 31381 times.
✓ Branch 1 taken 6254 times.
37635 for (i = 0; i < graph->nb_filters; i++) {
1083 31381 AVFilterContext *filter = graph->filters[i];
1084
1085
2/2
✓ Branch 0 taken 25134 times.
✓ Branch 1 taken 31381 times.
56515 for (j = 0; j < filter->nb_inputs; j++)
1086
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 25134 times.
25134 if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
1087 return ret;
1088
2/2
✓ Branch 0 taken 25134 times.
✓ Branch 1 taken 31381 times.
56515 for (j = 0; j < filter->nb_outputs; j++)
1089
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 25134 times.
25134 if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
1090 return ret;
1091 }
1092 6254 return 0;
1093 }
1094
1095 /**
1096 * Configure the formats of all the links in the graph.
1097 */
1098 6254 static int graph_config_formats(AVFilterGraph *graph, void *log_ctx)
1099 {
1100 int ret;
1101
1102 /* find supported formats from sub-filters, and merge along links */
1103
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 6254 times.
6268 while ((ret = query_formats(graph, log_ctx)) == AVERROR(EAGAIN))
1104 14 av_log(graph, AV_LOG_DEBUG, "query_formats not finished\n");
1105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6254 times.
6254 if (ret < 0)
1106 return ret;
1107
1108 /* Once everything is merged, it's possible that we'll still have
1109 * multiple valid media format choices. We try to minimize the amount
1110 * of format conversion inside filters */
1111
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6254 times.
6254 if ((ret = reduce_formats(graph)) < 0)
1112 return ret;
1113
1114 /* for audio filters, ensure the best format, sample rate and channel layout
1115 * is selected */
1116 6254 swap_sample_fmts(graph);
1117 6254 swap_samplerates(graph);
1118 6254 swap_channel_layouts(graph);
1119
1120
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6254 times.
6254 if ((ret = pick_formats(graph)) < 0)
1121 return ret;
1122
1123 6254 return 0;
1124 }
1125
1126 6254 static int graph_config_pointers(AVFilterGraph *graph, void *log_ctx)
1127 {
1128 unsigned i, j;
1129 6254 int sink_links_count = 0, n = 0;
1130 AVFilterContext *f;
1131 AVFilterLink **sinks;
1132
1133
2/2
✓ Branch 0 taken 31381 times.
✓ Branch 1 taken 6254 times.
37635 for (i = 0; i < graph->nb_filters; i++) {
1134 31381 f = graph->filters[i];
1135
2/2
✓ Branch 0 taken 25134 times.
✓ Branch 1 taken 31381 times.
56515 for (j = 0; j < f->nb_inputs; j++) {
1136 25134 f->inputs[j]->graph = graph;
1137 25134 f->inputs[j]->age_index = -1;
1138 }
1139
2/2
✓ Branch 0 taken 25134 times.
✓ Branch 1 taken 31381 times.
56515 for (j = 0; j < f->nb_outputs; j++) {
1140 25134 f->outputs[j]->graph = graph;
1141 25134 f->outputs[j]->age_index= -1;
1142 }
1143
2/2
✓ Branch 0 taken 6267 times.
✓ Branch 1 taken 25114 times.
31381 if (!f->nb_outputs) {
1144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6267 times.
6267 if (f->nb_inputs > INT_MAX - sink_links_count)
1145 return AVERROR(EINVAL);
1146 6267 sink_links_count += f->nb_inputs;
1147 }
1148 }
1149 6254 sinks = av_calloc(sink_links_count, sizeof(*sinks));
1150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6254 times.
6254 if (!sinks)
1151 return AVERROR(ENOMEM);
1152
2/2
✓ Branch 0 taken 31381 times.
✓ Branch 1 taken 6254 times.
37635 for (i = 0; i < graph->nb_filters; i++) {
1153 31381 f = graph->filters[i];
1154
2/2
✓ Branch 0 taken 6267 times.
✓ Branch 1 taken 25114 times.
31381 if (!f->nb_outputs) {
1155
2/2
✓ Branch 0 taken 6267 times.
✓ Branch 1 taken 6267 times.
12534 for (j = 0; j < f->nb_inputs; j++) {
1156 6267 sinks[n] = f->inputs[j];
1157 6267 f->inputs[j]->age_index = n++;
1158 }
1159 }
1160 }
1161
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6254 times.
6254 av_assert0(n == sink_links_count);
1162 6254 graph->sink_links = sinks;
1163 6254 graph->sink_links_count = sink_links_count;
1164 6254 return 0;
1165 }
1166
1167 6254 int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
1168 {
1169 int ret;
1170
1171
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6254 times.
6254 if ((ret = graph_check_validity(graphctx, log_ctx)))
1172 return ret;
1173
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6254 times.
6254 if ((ret = graph_config_formats(graphctx, log_ctx)))
1174 return ret;
1175
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6254 times.
6254 if ((ret = graph_config_links(graphctx, log_ctx)))
1176 return ret;
1177
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6254 times.
6254 if ((ret = graph_check_links(graphctx, log_ctx)))
1178 return ret;
1179
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6254 times.
6254 if ((ret = graph_config_pointers(graphctx, log_ctx)))
1180 return ret;
1181
1182 6254 return 0;
1183 }
1184
1185 int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags)
1186 {
1187 int i, r = AVERROR(ENOSYS);
1188
1189 if (!graph)
1190 return r;
1191
1192 if ((flags & AVFILTER_CMD_FLAG_ONE) && !(flags & AVFILTER_CMD_FLAG_FAST)) {
1193 r = avfilter_graph_send_command(graph, target, cmd, arg, res, res_len, flags | AVFILTER_CMD_FLAG_FAST);
1194 if (r != AVERROR(ENOSYS))
1195 return r;
1196 }
1197
1198 if (res_len && res)
1199 res[0] = 0;
1200
1201 for (i = 0; i < graph->nb_filters; i++) {
1202 AVFilterContext *filter = graph->filters[i];
1203 if (!strcmp(target, "all") || (filter->name && !strcmp(target, filter->name)) || !strcmp(target, filter->filter->name)) {
1204 r = avfilter_process_command(filter, cmd, arg, res, res_len, flags);
1205 if (r != AVERROR(ENOSYS)) {
1206 if ((flags & AVFILTER_CMD_FLAG_ONE) || r < 0)
1207 return r;
1208 }
1209 }
1210 }
1211
1212 return r;
1213 }
1214
1215 int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *command, const char *arg, int flags, double ts)
1216 {
1217 int i;
1218
1219 if(!graph)
1220 return 0;
1221
1222 for (i = 0; i < graph->nb_filters; i++) {
1223 AVFilterContext *filter = graph->filters[i];
1224 if(filter && (!strcmp(target, "all") || !strcmp(target, filter->name) || !strcmp(target, filter->filter->name))){
1225 AVFilterCommand **queue = &filter->command_queue, *next;
1226 while (*queue && (*queue)->time <= ts)
1227 queue = &(*queue)->next;
1228 next = *queue;
1229 *queue = av_mallocz(sizeof(AVFilterCommand));
1230 if (!*queue)
1231 return AVERROR(ENOMEM);
1232
1233 (*queue)->command = av_strdup(command);
1234 (*queue)->arg = av_strdup(arg);
1235 (*queue)->time = ts;
1236 (*queue)->flags = flags;
1237 (*queue)->next = next;
1238 if(flags & AVFILTER_CMD_FLAG_ONE)
1239 return 0;
1240 }
1241 }
1242
1243 return 0;
1244 }
1245
1246 435426 static void heap_bubble_up(AVFilterGraph *graph,
1247 AVFilterLink *link, int index)
1248 {
1249 435426 AVFilterLink **links = graph->sink_links;
1250
1251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 435426 times.
435426 av_assert0(index >= 0);
1252
1253
2/2
✓ Branch 0 taken 793 times.
✓ Branch 1 taken 435426 times.
436219 while (index) {
1254 793 int parent = (index - 1) >> 1;
1255
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 793 times.
793 if (links[parent]->current_pts_us >= link->current_pts_us)
1256 break;
1257 793 links[index] = links[parent];
1258 793 links[index]->age_index = index;
1259 793 index = parent;
1260 }
1261 435426 links[index] = link;
1262 435426 link->age_index = index;
1263 435426 }
1264
1265 435430 static void heap_bubble_down(AVFilterGraph *graph,
1266 AVFilterLink *link, int index)
1267 {
1268 435430 AVFilterLink **links = graph->sink_links;
1269
1270
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 435430 times.
435430 av_assert0(index >= 0);
1271
1272 3258 while (1) {
1273 438688 int child = 2 * index + 1;
1274
2/2
✓ Branch 0 taken 435127 times.
✓ Branch 1 taken 3561 times.
438688 if (child >= graph->sink_links_count)
1275 435127 break;
1276
2/2
✓ Branch 0 taken 2107 times.
✓ Branch 1 taken 1454 times.
3561 if (child + 1 < graph->sink_links_count &&
1277
2/2
✓ Branch 0 taken 655 times.
✓ Branch 1 taken 1452 times.
2107 links[child + 1]->current_pts_us < links[child]->current_pts_us)
1278 655 child++;
1279
2/2
✓ Branch 0 taken 303 times.
✓ Branch 1 taken 3258 times.
3561 if (link->current_pts_us < links[child]->current_pts_us)
1280 303 break;
1281 3258 links[index] = links[child];
1282 3258 links[index]->age_index = index;
1283 3258 index = child;
1284 }
1285 435430 links[index] = link;
1286 435430 link->age_index = index;
1287 435430 }
1288
1289 435426 void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link)
1290 {
1291 435426 heap_bubble_up (graph, link, link->age_index);
1292 435426 heap_bubble_down(graph, link, link->age_index);
1293 435426 }
1294
1295 384932 int avfilter_graph_request_oldest(AVFilterGraph *graph)
1296 {
1297 384932 AVFilterLink *oldest = graph->sink_links[0];
1298 int64_t frame_count;
1299 int r;
1300
1301
2/2
✓ Branch 0 taken 384942 times.
✓ Branch 1 taken 3596 times.
388538 while (graph->sink_links_count) {
1302 384942 oldest = graph->sink_links[0];
1303
2/2
✓ Branch 0 taken 384937 times.
✓ Branch 1 taken 5 times.
384942 if (oldest->dst->filter->activate) {
1304 /* For now, buffersink is the only filter implementing activate. */
1305 384937 r = av_buffersink_get_frame_flags(oldest->dst, NULL,
1306 AV_BUFFERSINK_FLAG_PEEK);
1307
2/2
✓ Branch 0 taken 381331 times.
✓ Branch 1 taken 3606 times.
384937 if (r != AVERROR_EOF)
1308 381331 return r;
1309 } else {
1310 5 r = ff_request_frame(oldest);
1311 }
1312
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 3606 times.
3611 if (r != AVERROR_EOF)
1313 5 break;
1314 3606 av_log(oldest->dst, AV_LOG_DEBUG, "EOF on sink link %s:%s.\n",
1315 3606 oldest->dst->name,
1316 3606 oldest->dstpad->name);
1317 /* EOF: remove the link from the heap */
1318
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3602 times.
3606 if (oldest->age_index < --graph->sink_links_count)
1319 4 heap_bubble_down(graph, graph->sink_links[graph->sink_links_count],
1320 oldest->age_index);
1321 3606 oldest->age_index = -1;
1322 }
1323
2/2
✓ Branch 0 taken 3596 times.
✓ Branch 1 taken 5 times.
3601 if (!graph->sink_links_count)
1324 3596 return AVERROR_EOF;
1325 av_assert1(!oldest->dst->filter->activate);
1326 av_assert1(oldest->age_index >= 0);
1327 5 frame_count = oldest->frame_count_out;
1328
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 5 times.
34 while (frame_count == oldest->frame_count_out) {
1329 29 r = ff_filter_graph_run_once(graph);
1330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
29 if (r == AVERROR(EAGAIN) &&
1331 !oldest->frame_wanted_out && !oldest->frame_blocked_in &&
1332 !oldest->status_in)
1333 ff_request_frame(oldest);
1334
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
29 else if (r < 0)
1335 return r;
1336 }
1337 5 return 0;
1338 }
1339
1340 4147367 int ff_filter_graph_run_once(AVFilterGraph *graph)
1341 {
1342 AVFilterContext *filter;
1343 unsigned i;
1344
1345
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4147367 times.
4147367 av_assert0(graph->nb_filters);
1346 4147367 filter = graph->filters[0];
1347
2/2
✓ Branch 0 taken 15319774 times.
✓ Branch 1 taken 4147367 times.
19467141 for (i = 1; i < graph->nb_filters; i++)
1348
2/2
✓ Branch 0 taken 2549887 times.
✓ Branch 1 taken 12769887 times.
15319774 if (graph->filters[i]->ready > filter->ready)
1349 2549887 filter = graph->filters[i];
1350
2/2
✓ Branch 0 taken 418534 times.
✓ Branch 1 taken 3728833 times.
4147367 if (!filter->ready)
1351 418534 return AVERROR(EAGAIN);
1352 3728833 return ff_filter_activate(filter);
1353 }
1354