FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/avfiltergraph.c
Date: 2026-10-30 17:37:53
Exec Total Coverage
Lines: 693 915 75.7%
Functions: 38 42 90.5%
Branches: 606 881 68.8%

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/mem.h"
32 #include "libavutil/opt.h"
33 #include "libavutil/pixdesc.h"
34
35
36 #include "avfilter.h"
37 #include "avfilter_internal.h"
38 #include "buffersink.h"
39 #include "filters.h"
40 #include "formats.h"
41 #include "framequeue.h"
42 #include "video.h"
43
44 #define OFFSET(x) offsetof(AVFilterGraph, x)
45 #define F AV_OPT_FLAG_FILTERING_PARAM
46 #define V AV_OPT_FLAG_VIDEO_PARAM
47 #define A AV_OPT_FLAG_AUDIO_PARAM
48 FF_DISABLE_DEPRECATION_WARNINGS
49 static const AVOption filtergraph_options[] = {
50 { "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,
51 { .i64 = AVFILTER_THREAD_SLICE }, 0, INT_MAX, F|V|A, .unit = "thread_type" },
52 { "slice", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVFILTER_THREAD_SLICE }, .flags = F|V|A, .unit = "thread_type" },
53 { "threads", "Maximum number of threads", OFFSET(nb_threads), AV_OPT_TYPE_INT,
54 { .i64 = 0 }, 0, INT_MAX, F|V|A, .unit = "threads"},
55 {"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, .flags = F|V|A, .unit = "threads"},
56 {"scale_sws_opts" , "default scale filter options" , OFFSET(scale_sws_opts) ,
57 AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, F|V },
58 {"aresample_swr_opts" , "default aresample filter options" , OFFSET(aresample_swr_opts) ,
59 AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, F|A },
60 #if FF_API_MAX_BUFFERED_FRAMES
61 {"max_buffered_frames" , "maximum number of buffered frames allowed", OFFSET(max_buffered_frames),
62 AV_OPT_TYPE_UINT, {.i64 = 0}, 0, UINT_MAX, F|V|A|AV_OPT_FLAG_DEPRECATED },
63 #endif
64 { NULL },
65 };
66 FF_ENABLE_DEPRECATION_WARNINGS
67
68 static const AVClass filtergraph_class = {
69 .class_name = "AVFilterGraph",
70 .item_name = av_default_item_name,
71 .version = LIBAVUTIL_VERSION_INT,
72 .option = filtergraph_options,
73 .category = AV_CLASS_CATEGORY_FILTER,
74 };
75
76 #if !HAVE_THREADS
77 void ff_graph_thread_free(FFFilterGraph *graph)
78 {
79 }
80
81 int ff_graph_thread_init(FFFilterGraph *graph)
82 {
83 graph->p.thread_type = 0;
84 graph->p.nb_threads = 1;
85 return 0;
86 }
87 #endif
88
89 16973 AVFilterGraph *avfilter_graph_alloc(void)
90 {
91 16973 FFFilterGraph *graph = av_mallocz(sizeof(*graph));
92 AVFilterGraph *ret;
93
94
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16973 times.
16973 if (!graph)
95 ✗ return NULL;
96
97 16973 ret = &graph->p;
98 16973 ret->av_class = &filtergraph_class;
99 16973 av_opt_set_defaults(ret);
100
2/2
✓ Branch 0 taken 84865 times.
✓ Branch 1 taken 16973 times.
101838 for (int i = 0; i < FF_ARRAY_ELEMS(graph->frame_queues); i++)
101 84865 ff_framequeue_global_init(&graph->frame_queues[i]);
102
103 16973 return ret;
104 }
105
106 66292 void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter)
107 {
108 int i, j;
109
1/2
✓ Branch 0 taken 66292 times.
✗ Branch 1 not taken.
66292 for (i = 0; i < graph->nb_filters; i++) {
110
1/2
✓ Branch 0 taken 66292 times.
✗ Branch 1 not taken.
66292 if (graph->filters[i] == filter) {
111 66292 FFSWAP(AVFilterContext*, graph->filters[i],
112 graph->filters[graph->nb_filters - 1]);
113 66292 graph->nb_filters--;
114 66292 filter->graph = NULL;
115
2/2
✓ Branch 0 taken 57953 times.
✓ Branch 1 taken 66292 times.
124245 for (j = 0; j<filter->nb_outputs; j++)
116
2/2
✓ Branch 0 taken 22088 times.
✓ Branch 1 taken 35865 times.
57953 if (filter->outputs[j])
117 22088 ff_filter_link(filter->outputs[j])->graph = NULL;
118
119 66292 return;
120 }
121 }
122 }
123
124 25357 void avfilter_graph_free(AVFilterGraph **graphp)
125 {
126 25357 AVFilterGraph *graph = *graphp;
127 25357 FFFilterGraph *graphi = fffiltergraph(graph);
128
129
2/2
✓ Branch 0 taken 8384 times.
✓ Branch 1 taken 16973 times.
25357 if (!graph)
130 8384 return;
131
132
2/2
✓ Branch 0 taken 66226 times.
✓ Branch 1 taken 16973 times.
83199 while (graph->nb_filters)
133 66226 avfilter_free(graph->filters[0]);
134
135 16973 ff_graph_thread_free(graphi);
136
137 16973 av_freep(&graphi->sink_links);
138
139 16973 av_opt_free(graph);
140
141 16973 av_freep(&graph->filters);
142 16973 av_freep(graphp);
143 }
144
145 20614 int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt,
146 const char *name, const char *args, void *opaque,
147 AVFilterGraph *graph_ctx)
148 {
149 int ret;
150
151 20614 *filt_ctx = avfilter_graph_alloc_filter(graph_ctx, filt, name);
152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20614 times.
20614 if (!*filt_ctx)
153 ✗ return AVERROR(ENOMEM);
154
155 20614 ret = avfilter_init_str(*filt_ctx, args);
156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20614 times.
20614 if (ret < 0)
157 ✗ goto fail;
158
159 20614 return 0;
160
161 ✗ fail:
162 ✗ avfilter_free(*filt_ctx);
163 ✗ *filt_ctx = NULL;
164 ✗ return ret;
165 }
166
167 6500 void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
168 {
169 6500 fffiltergraph(graph)->disable_auto_convert = flags;
170 6500 }
171
172 5 int avfilter_graph_set_max_buffered_frames(AVFilterGraph *graph,
173 enum AVMediaType type,
174 unsigned frames)
175 {
176 5 FFFilterGraph *graphi = fffiltergraph(graph);
177
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
5 if (type < 0 || type >= FF_ARRAY_ELEMS(graphi->frame_queues))
178 ✗ return AVERROR(EINVAL);
179
180 5 FFFrameQueueGlobal *fqg = &graphi->frame_queues[type];
181
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 size_t max_queued = frames ? frames : SIZE_MAX;
182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (fqg->queued > max_queued)
183 ✗ return AVERROR(EINVAL);
184 5 fqg->max_queued = max_queued;
185 5 graphi->max_queued_set[type] = 1;
186 5 return 0;
187 }
188
189 66292 AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph,
190 const AVFilter *filter,
191 const char *name)
192 {
193 AVFilterContext **filters, *s;
194 66292 FFFilterGraph *graphi = fffiltergraph(graph);
195
196
4/4
✓ Branch 0 taken 35596 times.
✓ Branch 1 taken 30696 times.
✓ Branch 2 taken 16973 times.
✓ Branch 3 taken 18623 times.
66292 if (graph->thread_type && !graphi->thread_execute) {
197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16973 times.
16973 if (graph->execute) {
198 ✗ graphi->thread_execute = graph->execute;
199 } else {
200 16973 int ret = ff_graph_thread_init(graphi);
201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16973 times.
16973 if (ret < 0) {
202 ✗ av_log(graph, AV_LOG_ERROR, "Error initializing threading: %s.\n", av_err2str(ret));
203 ✗ return NULL;
204 }
205 }
206 }
207
208 66292 filters = av_realloc_array(graph->filters, graph->nb_filters + 1, sizeof(*filters));
209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66292 times.
66292 if (!filters)
210 ✗ return NULL;
211 66292 graph->filters = filters;
212
213 66292 s = ff_filter_alloc(filter, name);
214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66292 times.
66292 if (!s)
215 ✗ return NULL;
216
217 66292 graph->filters[graph->nb_filters++] = s;
218
219 66292 s->graph = graph;
220
221 66292 return s;
222 }
223
224 /**
225 * Check for the validity of graph.
226 *
227 * A graph is considered valid if all its input and output pads are
228 * connected.
229 *
230 * @return >= 0 in case of success, a negative value otherwise
231 */
232 8516 static int graph_check_validity(AVFilterGraph *graph, void *log_ctx)
233 {
234 AVFilterContext *filt;
235 int i, j;
236
237
2/2
✓ Branch 0 taken 45592 times.
✓ Branch 1 taken 8516 times.
54108 for (i = 0; i < graph->nb_filters; i++) {
238 const AVFilterPad *pad;
239 45592 filt = graph->filters[i];
240
241
2/2
✓ Branch 0 taken 37046 times.
✓ Branch 1 taken 45592 times.
82638 for (j = 0; j < filt->nb_inputs; j++) {
242
2/4
✓ Branch 0 taken 37046 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 37046 times.
37046 if (!filt->inputs[j] || !filt->inputs[j]->src) {
243 ✗ pad = &filt->input_pads[j];
244 ✗ av_log(log_ctx, AV_LOG_ERROR,
245 "Input pad \"%s\" with type %s of the filter instance \"%s\" of %s not connected to any source\n",
246 ✗ pad->name, av_get_media_type_string(pad->type), filt->name, filt->filter->name);
247 ✗ return AVERROR(EINVAL);
248 }
249 }
250
251
2/2
✓ Branch 0 taken 37046 times.
✓ Branch 1 taken 45592 times.
82638 for (j = 0; j < filt->nb_outputs; j++) {
252
2/4
✓ Branch 0 taken 37046 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 37046 times.
37046 if (!filt->outputs[j] || !filt->outputs[j]->dst) {
253 ✗ pad = &filt->output_pads[j];
254 ✗ av_log(log_ctx, AV_LOG_ERROR,
255 "Output pad \"%s\" with type %s of the filter instance \"%s\" of %s not connected to any destination\n",
256 ✗ pad->name, av_get_media_type_string(pad->type), filt->name, filt->filter->name);
257 ✗ return AVERROR(EINVAL);
258 }
259 }
260 }
261
262 8516 return 0;
263 }
264
265 /**
266 * Configure all the links of graphctx.
267 *
268 * @return >= 0 in case of success, a negative value otherwise
269 */
270 8516 static int graph_config_links(AVFilterGraph *graph, void *log_ctx)
271 {
272 AVFilterContext *filt;
273 int i, ret;
274
275
2/2
✓ Branch 0 taken 47181 times.
✓ Branch 1 taken 8514 times.
55695 for (i = 0; i < graph->nb_filters; i++) {
276 47181 filt = graph->filters[i];
277
278
2/2
✓ Branch 0 taken 8755 times.
✓ Branch 1 taken 38426 times.
47181 if (!filt->nb_outputs) {
279
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 8753 times.
8755 if ((ret = ff_filter_config_links(filt)))
280 2 return ret;
281 }
282 }
283
284 8514 return 0;
285 }
286
287 8514 static int graph_check_links(AVFilterGraph *graph, void *log_ctx)
288 {
289 AVFilterContext *f;
290 AVFilterLink *l;
291 unsigned i, j;
292 int ret;
293
294
2/2
✓ Branch 0 taken 47173 times.
✓ Branch 1 taken 8514 times.
55687 for (i = 0; i < graph->nb_filters; i++) {
295 47173 f = graph->filters[i];
296
2/2
✓ Branch 0 taken 38629 times.
✓ Branch 1 taken 47173 times.
85802 for (j = 0; j < f->nb_outputs; j++) {
297 38629 l = f->outputs[j];
298
2/2
✓ Branch 0 taken 31628 times.
✓ Branch 1 taken 7001 times.
38629 if (l->type == AVMEDIA_TYPE_VIDEO) {
299 31628 ret = av_image_check_size2(l->w, l->h, INT64_MAX, l->format, 0, f);
300
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31628 times.
31628 if (ret < 0)
301 ✗ return ret;
302 }
303 }
304 }
305 8514 return 0;
306 }
307
308 ✗ AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, const char *name)
309 {
310 int i;
311
312 ✗ for (i = 0; i < graph->nb_filters; i++)
313 ✗ if (graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
314 ✗ return graph->filters[i];
315
316 ✗ return NULL;
317 }
318
319 62893 static int filter_link_check_formats(void *log, AVFilterLink *link, AVFilterFormatsConfig *cfg)
320 {
321 int ret;
322
323
2/3
✓ Branch 0 taken 51840 times.
✓ Branch 1 taken 11053 times.
✗ Branch 2 not taken.
62893 switch (link->type) {
324
325 51840 case AVMEDIA_TYPE_VIDEO:
326
2/4
✓ Branch 1 taken 51840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 51840 times.
✗ Branch 4 not taken.
103680 if ((ret = ff_formats_check_pixel_formats(log, cfg->formats)) < 0 ||
327
1/2
✓ Branch 1 taken 51840 times.
✗ Branch 2 not taken.
103680 (ret = ff_formats_check_color_spaces(log, cfg->color_spaces)) < 0 ||
328
1/2
✓ Branch 1 taken 51840 times.
✗ Branch 2 not taken.
103680 (ret = ff_formats_check_color_ranges(log, cfg->color_ranges)) < 0 ||
329
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 51840 times.
103680 (ret = ff_formats_check_alpha_modes(log, cfg->alpha_modes)) < 0 ||
330 51840 (ret = ff_formats_check_chroma_locations(log, cfg->chroma_locations)) < 0)
331 ✗ return ret;
332 51840 break;
333
334 11053 case AVMEDIA_TYPE_AUDIO:
335
2/4
✓ Branch 1 taken 11053 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11053 times.
✗ Branch 4 not taken.
22106 if ((ret = ff_formats_check_sample_formats(log, cfg->formats)) < 0 ||
336
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11053 times.
22106 (ret = ff_formats_check_sample_rates(log, cfg->samplerates)) < 0 ||
337 11053 (ret = ff_formats_check_channel_layouts(log, cfg->channel_layouts)) < 0)
338 ✗ return ret;
339 11053 break;
340
341 ✗ default:
342 ✗ av_assert0(!"reached");
343 }
344 62893 return 0;
345 }
346
347 /**
348 * Check the validity of the formats / etc. lists set by query_formats().
349 *
350 * In particular, check they do not contain any redundant element.
351 */
352 39501 static int filter_check_formats(AVFilterContext *ctx)
353 {
354 unsigned i;
355 int ret;
356
357
2/2
✓ Branch 0 taken 32071 times.
✓ Branch 1 taken 39501 times.
71572 for (i = 0; i < ctx->nb_inputs; i++) {
358 32071 ret = filter_link_check_formats(ctx, ctx->inputs[i], &ctx->inputs[i]->outcfg);
359
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32071 times.
32071 if (ret < 0)
360 ✗ return ret;
361 }
362
2/2
✓ Branch 0 taken 30822 times.
✓ Branch 1 taken 39501 times.
70323 for (i = 0; i < ctx->nb_outputs; i++) {
363 30822 ret = filter_link_check_formats(ctx, ctx->outputs[i], &ctx->outputs[i]->incfg);
364
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30822 times.
30822 if (ret < 0)
365 ✗ return ret;
366 }
367 39501 return 0;
368 }
369
370 47202 static int filter_query_formats(AVFilterContext *ctx)
371 {
372 47202 const FFFilter *const filter = fffilter(ctx->filter);
373 int ret;
374
375
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 47167 times.
47202 if (filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC) {
376
2/2
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 18 times.
35 if ((ret = filter->formats.query_func(ctx)) < 0) {
377
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (ret != AVERROR(EAGAIN))
378 ✗ av_log(ctx, AV_LOG_ERROR, "Query format failed for '%s': %s\n",
379 ✗ ctx->name, av_err2str(ret));
380 17 return ret;
381 }
382
2/2
✓ Branch 0 taken 39483 times.
✓ Branch 1 taken 7684 times.
47167 } else if (filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC2) {
383 AVFilterFormatsConfig *cfg_in_stack[64], *cfg_out_stack[64];
384 39483 AVFilterFormatsConfig **cfg_in_dyn = NULL, **cfg_out_dyn = NULL;
385 AVFilterFormatsConfig **cfg_in, **cfg_out;
386
387
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 39482 times.
39483 if (ctx->nb_inputs > FF_ARRAY_ELEMS(cfg_in_stack)) {
388 1 cfg_in_dyn = av_malloc_array(ctx->nb_inputs, sizeof(*cfg_in_dyn));
389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!cfg_in_dyn)
390 ✗ return AVERROR(ENOMEM);
391 1 cfg_in = cfg_in_dyn;
392 } else
393
2/2
✓ Branch 0 taken 31907 times.
✓ Branch 1 taken 7575 times.
39482 cfg_in = ctx->nb_inputs ? cfg_in_stack : NULL;
394
395
2/2
✓ Branch 0 taken 32047 times.
✓ Branch 1 taken 39483 times.
71530 for (unsigned i = 0; i < ctx->nb_inputs; i++) {
396 32047 AVFilterLink *l = ctx->inputs[i];
397 32047 cfg_in[i] = &l->outcfg;
398 }
399
400
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 39482 times.
39483 if (ctx->nb_outputs > FF_ARRAY_ELEMS(cfg_out_stack)) {
401 1 cfg_out_dyn = av_malloc_array(ctx->nb_outputs, sizeof(*cfg_out_dyn));
402
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!cfg_out_dyn) {
403 ✗ av_freep(&cfg_in_dyn);
404 ✗ return AVERROR(ENOMEM);
405 }
406 1 cfg_out = cfg_out_dyn;
407 } else
408
2/2
✓ Branch 0 taken 30728 times.
✓ Branch 1 taken 8754 times.
39482 cfg_out = ctx->nb_outputs ? cfg_out_stack : NULL;
409
410
2/2
✓ Branch 0 taken 30804 times.
✓ Branch 1 taken 39483 times.
70287 for (unsigned i = 0; i < ctx->nb_outputs; i++) {
411 30804 AVFilterLink *l = ctx->outputs[i];
412 30804 cfg_out[i] = &l->incfg;
413 }
414
415 39483 ret = filter->formats.query_func2(ctx, cfg_in, cfg_out);
416 39483 av_freep(&cfg_in_dyn);
417 39483 av_freep(&cfg_out_dyn);
418
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39483 times.
39483 if (ret < 0) {
419 ✗ if (ret != AVERROR(EAGAIN))
420 ✗ av_log(ctx, AV_LOG_ERROR, "Query format failed for '%s': %s\n",
421 ✗ ctx->name, av_err2str(ret));
422 ✗ return ret;
423 }
424 }
425
426
2/2
✓ Branch 0 taken 47167 times.
✓ Branch 1 taken 18 times.
47185 if (filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC ||
427
2/2
✓ Branch 0 taken 39483 times.
✓ Branch 1 taken 7684 times.
47167 filter->formats_state == FF_FILTER_FORMATS_QUERY_FUNC2) {
428 39501 ret = filter_check_formats(ctx);
429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39501 times.
39501 if (ret < 0)
430 ✗ return ret;
431 }
432
433 47185 return ff_default_query_formats(ctx);
434 }
435
436 45666 static int formats_declared(AVFilterContext *f)
437 {
438 int i;
439
440
2/2
✓ Branch 0 taken 36924 times.
✓ Branch 1 taken 8782 times.
45706 for (i = 0; i < f->nb_inputs; i++) {
441
2/2
✓ Branch 0 taken 36882 times.
✓ Branch 1 taken 42 times.
36924 if (!f->inputs[i]->outcfg.formats)
442 36882 return 0;
443
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 9 times.
42 if (f->inputs[i]->type == AVMEDIA_TYPE_VIDEO &&
444
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 2 times.
33 !(f->inputs[i]->outcfg.color_ranges &&
445
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 f->inputs[i]->outcfg.color_spaces &&
446
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 f->inputs[i]->outcfg.alpha_modes &&
447
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 f->inputs[i]->outcfg.chroma_locations))
448 2 return 0;
449
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 31 times.
40 if (f->inputs[i]->type == AVMEDIA_TYPE_AUDIO &&
450
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 !(f->inputs[i]->outcfg.samplerates &&
451
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 f->inputs[i]->outcfg.channel_layouts))
452 ✗ return 0;
453 }
454
2/2
✓ Branch 0 taken 8771 times.
✓ Branch 1 taken 57 times.
8828 for (i = 0; i < f->nb_outputs; i++) {
455
2/2
✓ Branch 0 taken 8725 times.
✓ Branch 1 taken 46 times.
8771 if (!f->outputs[i]->incfg.formats)
456 8725 return 0;
457
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 15 times.
46 if (f->outputs[i]->type == AVMEDIA_TYPE_VIDEO &&
458
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 !(f->outputs[i]->incfg.color_ranges &&
459
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 f->outputs[i]->incfg.color_spaces &&
460
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 f->outputs[i]->incfg.alpha_modes &&
461
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 f->outputs[i]->incfg.chroma_locations))
462 ✗ return 0;
463
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 31 times.
46 if (f->outputs[i]->type == AVMEDIA_TYPE_AUDIO &&
464
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 !(f->outputs[i]->incfg.samplerates &&
465
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 f->outputs[i]->incfg.channel_layouts))
466 ✗ return 0;
467 }
468 57 return 1;
469 }
470
471 ✗ static void print_link_formats(void *log_ctx, int level, const AVFilterLink *l,
472 const AVFilterFormatsMerger *mergers[],
473 int nb_mergers)
474 {
475 ✗ if (av_log_get_level() < level)
476 ✗ return;
477
478 AVBPrint bp;
479 ✗ av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
480
481 ✗ av_log(log_ctx, level, "Link '%s.%s' -> '%s.%s':\n",
482 ✗ l->src->name, l->srcpad->name, l->dst->name, l->dstpad->name);
483
484 ✗ for (unsigned i = 0; i < nb_mergers; i++) {
485 ✗ const AVFilterFormatsMerger *m = mergers[i];
486 ✗ av_log(log_ctx, level, " %s:\n", m->name);
487 ✗ m->print_list(&bp, FF_FIELD_AT(void *, m->offset, l->incfg));
488 ✗ if (av_bprint_is_complete(&bp))
489 ✗ av_log(log_ctx, level, " src: %s\n", bp.str);
490 ✗ av_bprint_clear(&bp);
491
492 ✗ m->print_list(&bp, FF_FIELD_AT(void *, m->offset, l->outcfg));
493 ✗ if (av_bprint_is_complete(&bp))
494 ✗ av_log(log_ctx, level, " dst: %s\n", bp.str);
495 ✗ av_bprint_clear(&bp);
496 }
497
498 ✗ av_bprint_finalize(&bp, NULL);
499 }
500
501 45592 static void print_filter_formats(void *log_ctx, int level, const AVFilterContext *f)
502 {
503
1/2
✓ Branch 1 taken 45592 times.
✗ Branch 2 not taken.
45592 if (av_log_get_level() < level)
504 45592 return;
505
506 AVBPrint bp;
507 ✗ av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
508
509 ✗ av_log(log_ctx, level, "Filter '%s' formats:\n", f->name);
510 ✗ for (int i = 0; i < f->nb_inputs; i++) {
511 ✗ const AVFilterLink *in = f->inputs[i];
512 ✗ const AVFilterNegotiation *neg = ff_filter_get_negotiation(in);
513 ✗ av_log(log_ctx, level, " in[%d] '%s':\n", i, f->input_pads[i].name);
514
515 ✗ for (unsigned i = 0; i < neg->nb_mergers; i++) {
516 ✗ const AVFilterFormatsMerger *m = &neg->mergers[i];
517 ✗ m->print_list(&bp, FF_FIELD_AT(void *, m->offset, in->outcfg));
518 ✗ if (av_bprint_is_complete(&bp))
519 ✗ av_log(log_ctx, level, " %s: %s\n", m->name, bp.str);
520 ✗ av_bprint_clear(&bp);
521 }
522 }
523
524 ✗ for (int i = 0; i < f->nb_outputs; i++) {
525 ✗ const AVFilterLink *out = f->outputs[i];
526 ✗ const AVFilterNegotiation *neg = ff_filter_get_negotiation(out);
527 ✗ av_log(log_ctx, level, " out[%d] '%s':\n", i, f->output_pads[i].name);
528
529 ✗ for (unsigned i = 0; i < neg->nb_mergers; i++) {
530 ✗ const AVFilterFormatsMerger *m = &neg->mergers[i];
531 ✗ m->print_list(&bp, FF_FIELD_AT(void *, m->offset, out->incfg));
532 ✗ if (av_bprint_is_complete(&bp))
533 ✗ av_log(log_ctx, level, " %s: %s\n", m->name, bp.str);
534 ✗ av_bprint_clear(&bp);
535 }
536 }
537
538 ✗ av_bprint_finalize(&bp, NULL);
539 }
540
541 /**
542 * Perform one round of query_formats() and merging formats lists on the
543 * filter graph.
544 * @return >=0 if all links formats lists could be queried and merged;
545 * AVERROR(EAGAIN) some progress was made in the queries or merging
546 * and a later call may succeed;
547 * AVERROR(EIO) (may be changed) plus a log message if no progress
548 * was made and the negotiation is stuck;
549 * a negative error code if some other error happened
550 */
551 8531 static int query_formats(AVFilterGraph *graph, void *log_ctx)
552 {
553 int i, j, k, ret;
554 8531 int converter_count = 0;
555 8531 int count_queried = 0; /* successful calls to query_formats() */
556 8531 int count_merged = 0; /* successful merge of formats lists */
557 8531 int count_already_merged = 0; /* lists already merged */
558 8531 int count_delayed = 0; /* lists that need to be merged later */
559
560
2/2
✓ Branch 0 taken 45666 times.
✓ Branch 1 taken 8531 times.
54197 for (i = 0; i < graph->nb_filters; i++) {
561 45666 AVFilterContext *f = graph->filters[i];
562
2/2
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 45609 times.
45666 if (formats_declared(f))
563 57 continue;
564 45609 ret = filter_query_formats(f);
565
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 45592 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
45609 if (ret < 0 && ret != AVERROR(EAGAIN))
566 ✗ return ret;
567 /* note: EAGAIN could indicate a partial success, not counted yet */
568
2/2
✓ Branch 0 taken 45592 times.
✓ Branch 1 taken 17 times.
45609 if (ret >= 0) {
569 45592 print_filter_formats(log_ctx, AV_LOG_TRACE, f);
570 45592 count_queried++;
571 }
572 }
573
574 /* go through and merge as many format lists as possible */
575 8531 retry:
576
2/2
✓ Branch 0 taken 77438 times.
✓ Branch 1 taken 8531 times.
85969 for (i = 0; i < graph->nb_filters; i++) {
577 77438 AVFilterContext *filter = graph->filters[i];
578
579
2/2
✓ Branch 0 taken 64980 times.
✓ Branch 1 taken 75845 times.
140825 for (j = 0; j < filter->nb_inputs; j++) {
580 64980 AVFilterLink *link = filter->inputs[j];
581 const AVFilterNegotiation *neg;
582 AVFilterContext *conv[4];
583 const AVFilterFormatsMerger *mergers[4]; /* triggered mergers */
584 64980 const char *conv_filters[4], *conv_opts[4] = {0};
585 64980 unsigned neg_step, num_conv = 0, num_mergers = 0;
586
587
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64980 times.
64980 if (!link)
588 ✗ continue;
589
590 64980 neg = ff_filter_get_negotiation(link);
591
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64980 times.
64980 av_assert0(neg);
592
2/2
✓ Branch 0 taken 263020 times.
✓ Branch 1 taken 64980 times.
328000 for (neg_step = 0; neg_step < neg->nb_mergers; neg_step++) {
593 263020 const AVFilterFormatsMerger *m = &neg->mergers[neg_step];
594 263020 void *a = FF_FIELD_AT(void *, m->offset, link->incfg);
595 263020 void *b = FF_FIELD_AT(void *, m->offset, link->outcfg);
596
8/8
✓ Branch 0 taken 262943 times.
✓ Branch 1 taken 77 times.
✓ Branch 2 taken 262856 times.
✓ Branch 3 taken 87 times.
✓ Branch 4 taken 174326 times.
✓ Branch 5 taken 88530 times.
✓ Branch 7 taken 1688 times.
✓ Branch 8 taken 172638 times.
263020 if (a && b && a != b && !m->can_merge(a, b)) {
597
2/2
✓ Branch 0 taken 95 times.
✓ Branch 1 taken 1593 times.
1688 for (k = 0; k < num_conv; k++) {
598
1/2
✓ Branch 0 taken 95 times.
✗ Branch 1 not taken.
95 if (!strcmp(conv_filters[k], m->conversion_filter))
599 95 break;
600 }
601
2/2
✓ Branch 0 taken 1593 times.
✓ Branch 1 taken 95 times.
1688 if (k == num_conv) {
602 av_assert1(num_conv < FF_ARRAY_ELEMS(conv_filters));
603 1593 conv_filters[num_conv] = m->conversion_filter;
604
2/2
✓ Branch 0 taken 1592 times.
✓ Branch 1 taken 1 times.
1593 if (m->conversion_opts_offset)
605 1592 conv_opts[num_conv] = FF_FIELD_AT(char *, m->conversion_opts_offset, *graph);
606 1593 num_conv++;
607 }
608 av_assert1(num_mergers < FF_ARRAY_ELEMS(mergers));
609 1688 mergers[num_mergers++] = m;
610 }
611 }
612
2/2
✓ Branch 0 taken 263020 times.
✓ Branch 1 taken 64980 times.
328000 for (neg_step = 0; neg_step < neg->nb_mergers; neg_step++) {
613 263020 const AVFilterFormatsMerger *m = &neg->mergers[neg_step];
614 263020 void *a = FF_FIELD_AT(void *, m->offset, link->incfg);
615 263020 void *b = FF_FIELD_AT(void *, m->offset, link->outcfg);
616
4/4
✓ Branch 0 taken 262943 times.
✓ Branch 1 taken 77 times.
✓ Branch 2 taken 87 times.
✓ Branch 3 taken 262856 times.
263020 if (!(a && b)) {
617 164 count_delayed++;
618
2/2
✓ Branch 0 taken 94463 times.
✓ Branch 1 taken 168393 times.
262856 } else if (a == b) {
619 94463 count_already_merged++;
620
2/2
✓ Branch 0 taken 162723 times.
✓ Branch 1 taken 5670 times.
168393 } else if (!num_conv) {
621 162723 count_merged++;
622 162723 ret = m->merge(a, b);
623
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 162723 times.
162723 if (ret < 0)
624 ✗ return ret;
625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 162723 times.
162723 if (!ret) {
626 ✗ mergers[num_mergers++] = m;
627 ✗ conv_filters[num_conv] = m->conversion_filter;
628 ✗ if (m->conversion_opts_offset)
629 ✗ conv_opts[num_conv] = FF_FIELD_AT(char *, m->conversion_opts_offset, *graph);
630 ✗ num_conv++;
631 }
632 }
633 }
634
635 /**
636 * Couldn't merge format lists; auto-insert conversion filters
637 * in reverse order to keep the order consistent with the list
638 * of mergers, since they are prepended onto the existing link
639 */
640
2/2
✓ Branch 0 taken 1593 times.
✓ Branch 1 taken 64980 times.
66573 for (k = num_conv - 1; k >= 0; k--) {
641 const AVFilter *filter;
642 char inst_name[30];
643
644
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1593 times.
1593 if (fffiltergraph(graph)->disable_auto_convert) {
645 ✗ av_log(log_ctx, AV_LOG_ERROR,
646 "The filters '%s' and '%s' do not have a common format "
647 "and automatic conversion is disabled.\n",
648 ✗ link->src->name, link->dst->name);
649 ✗ print_link_formats(log_ctx, AV_LOG_ERROR, link, mergers, num_mergers);
650 ✗ return AVERROR(EINVAL);
651 }
652
653
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1593 times.
1593 if (!(filter = avfilter_get_by_name(conv_filters[k]))) {
654 ✗ av_log(log_ctx, AV_LOG_ERROR,
655 "'%s' filter not present, cannot convert formats.\n",
656 conv_filters[k]);
657 ✗ print_link_formats(log_ctx, AV_LOG_ERROR, link, mergers, num_mergers);
658 ✗ return AVERROR(EINVAL);
659 }
660 1593 snprintf(inst_name, sizeof(inst_name), "auto_%s_%d",
661 conv_filters[k], converter_count++);
662 1593 ret = avfilter_graph_create_filter(&conv[k], filter, inst_name,
663 conv_opts[k], NULL, graph);
664
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1593 times.
1593 if (ret < 0)
665 ✗ return ret;
666
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1593 times.
1593 if ((ret = avfilter_insert_filter(link, conv[k], 0, 0)) < 0)
667 ✗ return ret;
668
669
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1593 times.
1593 if ((ret = filter_query_formats(conv[k])) < 0)
670 ✗ return ret;
671 }
672
673 /* preemptively settle formats of auto filters */
674
2/2
✓ Branch 0 taken 1593 times.
✓ Branch 1 taken 64980 times.
66573 for (k = 0; k < num_conv; k++) {
675 1593 AVFilterLink *inlink = conv[k]->inputs[0];
676 1593 AVFilterLink *outlink = conv[k]->outputs[0];
677
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1593 times.
1593 av_assert0( inlink->incfg.formats->refcount > 0);
678
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1593 times.
1593 av_assert0( inlink->outcfg.formats->refcount > 0);
679
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1593 times.
1593 av_assert0(outlink->incfg.formats->refcount > 0);
680
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1593 times.
1593 av_assert0(outlink->outcfg.formats->refcount > 0);
681
2/2
✓ Branch 0 taken 775 times.
✓ Branch 1 taken 818 times.
1593 if (outlink->type == AVMEDIA_TYPE_VIDEO) {
682
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 775 times.
775 av_assert0( inlink-> incfg.color_spaces->refcount > 0);
683
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 775 times.
775 av_assert0( inlink->outcfg.color_spaces->refcount > 0);
684
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 775 times.
775 av_assert0(outlink-> incfg.color_spaces->refcount > 0);
685
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 775 times.
775 av_assert0(outlink->outcfg.color_spaces->refcount > 0);
686
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 775 times.
775 av_assert0( inlink-> incfg.color_ranges->refcount > 0);
687
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 775 times.
775 av_assert0( inlink->outcfg.color_ranges->refcount > 0);
688
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 775 times.
775 av_assert0(outlink-> incfg.color_ranges->refcount > 0);
689
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 775 times.
775 av_assert0(outlink->outcfg.color_ranges->refcount > 0);
690
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 775 times.
775 av_assert0( inlink-> incfg.alpha_modes->refcount > 0);
691
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 775 times.
775 av_assert0( inlink->outcfg.alpha_modes->refcount > 0);
692
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 775 times.
775 av_assert0(outlink-> incfg.alpha_modes->refcount > 0);
693
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 775 times.
775 av_assert0(outlink->outcfg.alpha_modes->refcount > 0);
694
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 775 times.
775 av_assert0( inlink-> incfg.chroma_locations->refcount > 0);
695
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 775 times.
775 av_assert0( inlink->outcfg.chroma_locations->refcount > 0);
696
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 775 times.
775 av_assert0(outlink-> incfg.chroma_locations->refcount > 0);
697
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 775 times.
775 av_assert0(outlink->outcfg.chroma_locations->refcount > 0);
698
1/2
✓ Branch 0 taken 818 times.
✗ Branch 1 not taken.
818 } else if (outlink->type == AVMEDIA_TYPE_AUDIO) {
699
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 818 times.
818 av_assert0( inlink-> incfg.samplerates->refcount > 0);
700
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 818 times.
818 av_assert0( inlink->outcfg.samplerates->refcount > 0);
701
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 818 times.
818 av_assert0(outlink-> incfg.samplerates->refcount > 0);
702
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 818 times.
818 av_assert0(outlink->outcfg.samplerates->refcount > 0);
703
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 818 times.
818 av_assert0( inlink-> incfg.channel_layouts->refcount > 0);
704
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 818 times.
818 av_assert0( inlink->outcfg.channel_layouts->refcount > 0);
705
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 818 times.
818 av_assert0(outlink-> incfg.channel_layouts->refcount > 0);
706
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 818 times.
818 av_assert0(outlink->outcfg.channel_layouts->refcount > 0);
707 }
708
709 #define MERGE(merger, link) \
710 ((merger)->merge(FF_FIELD_AT(void *, (merger)->offset, (link)->incfg), \
711 FF_FIELD_AT(void *, (merger)->offset, (link)->outcfg)))
712
713
2/2
✓ Branch 0 taken 6329 times.
✓ Branch 1 taken 1593 times.
7922 for (neg_step = 0; neg_step < neg->nb_mergers; neg_step++) {
714 6329 const AVFilterFormatsMerger *m = &neg->mergers[neg_step];
715
2/2
✓ Branch 0 taken 778 times.
✓ Branch 1 taken 5551 times.
6329 if (strcmp(m->conversion_filter, conv_filters[k]))
716 778 continue;
717
2/4
✓ Branch 1 taken 5551 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 5551 times.
11102 if ((ret = MERGE(m, inlink)) <= 0 ||
718 5551 (ret = MERGE(m, outlink)) <= 0) {
719 ✗ if (ret < 0)
720 ✗ return ret;
721 ✗ av_log(log_ctx, AV_LOG_ERROR,
722 "Impossible to convert between the formats supported by the filter "
723 ✗ "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
724 ✗ print_link_formats(log_ctx, AV_LOG_ERROR, inlink, &m, 1);
725 ✗ print_link_formats(log_ctx, AV_LOG_ERROR, outlink, &m, 1);
726 ✗ return AVERROR(ENOSYS);
727 } else {
728 5551 count_merged += 2;
729 }
730 }
731 }
732
733 /* if there is an auto filter, we may need another round to fully
734 * settle formats due to possible cross-incompatibilities between
735 * the auto filters themselves, or between the auto filters and
736 * a different attribute of the filter they are modifying */
737
2/2
✓ Branch 0 taken 1593 times.
✓ Branch 1 taken 63387 times.
64980 if (num_conv)
738 1593 goto retry;
739 }
740 }
741
742 8531 av_log(graph, AV_LOG_DEBUG, "query_formats: "
743 "%d queried, %d merged, %d already done, %d delayed\n",
744 count_queried, count_merged, count_already_merged, count_delayed);
745
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 8516 times.
8531 if (count_delayed) {
746 AVBPrint bp;
747
748 /* if count_queried > 0, one filter at least did set its formats,
749 that will give additional information to its neighbour;
750 if count_merged > 0, one pair of formats lists at least was merged,
751 that will give additional information to all connected filters;
752 in both cases, progress was made and a new round must be done */
753
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15 if (count_queried || count_merged)
754 15 return AVERROR(EAGAIN);
755 ✗ av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
756 ✗ for (i = 0; i < graph->nb_filters; i++)
757 ✗ if (!formats_declared(graph->filters[i]))
758 ✗ av_bprintf(&bp, "%s%s", bp.len ? ", " : "",
759 ✗ graph->filters[i]->name);
760 ✗ av_log(graph, AV_LOG_ERROR,
761 "The following filters could not choose their formats: %s\n"
762 "Consider inserting the (a)format filter near their input or "
763 "output.\n", bp.str);
764 ✗ return AVERROR(EIO);
765 }
766 8516 return 0;
767 }
768
769 1262 static int get_fmt_score(enum AVSampleFormat dst_fmt, enum AVSampleFormat src_fmt)
770 {
771 1262 int score = 0;
772
773
2/2
✓ Branch 2 taken 1162 times.
✓ Branch 3 taken 100 times.
1262 if (av_sample_fmt_is_planar(dst_fmt) != av_sample_fmt_is_planar(src_fmt))
774 1162 score ++;
775
776
2/2
✓ Branch 2 taken 299 times.
✓ Branch 3 taken 963 times.
1262 if (av_get_bytes_per_sample(dst_fmt) < av_get_bytes_per_sample(src_fmt)) {
777 299 score += 100 * (av_get_bytes_per_sample(src_fmt) - av_get_bytes_per_sample(dst_fmt));
778 }else
779 963 score += 10 * (av_get_bytes_per_sample(dst_fmt) - av_get_bytes_per_sample(src_fmt));
780
781
4/4
✓ Branch 1 taken 155 times.
✓ Branch 2 taken 1107 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 153 times.
1417 if (av_get_packed_sample_fmt(dst_fmt) == AV_SAMPLE_FMT_S32 &&
782 155 av_get_packed_sample_fmt(src_fmt) == AV_SAMPLE_FMT_FLT)
783 2 score += 20;
784
785
3/4
✓ Branch 1 taken 107 times.
✓ Branch 2 taken 1155 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 107 times.
1369 if (av_get_packed_sample_fmt(dst_fmt) == AV_SAMPLE_FMT_FLT &&
786 107 av_get_packed_sample_fmt(src_fmt) == AV_SAMPLE_FMT_S32)
787 ✗ score += 2;
788
789 1262 return score;
790 }
791
792 631 static enum AVSampleFormat find_best_sample_fmt_of_2(enum AVSampleFormat dst_fmt1, enum AVSampleFormat dst_fmt2,
793 enum AVSampleFormat src_fmt)
794 {
795 int score1, score2;
796
797 631 score1 = get_fmt_score(dst_fmt1, src_fmt);
798 631 score2 = get_fmt_score(dst_fmt2, src_fmt);
799
800
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 156 times.
631 return score1 < score2 ? dst_fmt1 : dst_fmt2;
801 }
802
803 37473 int ff_fmt_is_regular_yuv(enum AVPixelFormat fmt)
804 {
805 37473 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
806
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37473 times.
37473 if (!desc)
807 ✗ return 0;
808
2/2
✓ Branch 0 taken 1836 times.
✓ Branch 1 taken 35637 times.
37473 if (desc->nb_components < 3)
809 1836 return 0; /* Grayscale is explicitly full-range in swscale */
810 av_assert1(!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL));
811 35637 return !(desc->flags & (AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PAL |
812 AV_PIX_FMT_FLAG_XYZ | AV_PIX_FMT_FLAG_FLOAT));
813 }
814
815
816 26790 int ff_fmt_is_forced_full_range(enum AVPixelFormat fmt)
817 {
818
2/2
✓ Branch 0 taken 784 times.
✓ Branch 1 taken 26006 times.
26790 switch (fmt) {
819 784 case AV_PIX_FMT_YUVJ420P:
820 case AV_PIX_FMT_YUVJ422P:
821 case AV_PIX_FMT_YUVJ444P:
822 case AV_PIX_FMT_YUVJ440P:
823 case AV_PIX_FMT_YUVJ411P:
824 784 return 1;
825 26006 default:
826 26006 return 0;
827 }
828 }
829
830 115818 static int pick_format(AVFilterLink *link, AVFilterLink *ref)
831 {
832
3/4
✓ Branch 0 taken 115818 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 77179 times.
✓ Branch 3 taken 38639 times.
115818 if (!link || !link->incfg.formats)
833 77179 return 0;
834
835
2/2
✓ Branch 0 taken 31632 times.
✓ Branch 1 taken 7007 times.
38639 if (link->type == AVMEDIA_TYPE_VIDEO) {
836
3/4
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 31516 times.
✓ Branch 2 taken 116 times.
✗ Branch 3 not taken.
31632 if(ref && ref->type == AVMEDIA_TYPE_VIDEO){
837 //FIXME: This should check for AV_PIX_FMT_FLAG_ALPHA after PAL8 pixel format without alpha is implemented
838 116 int has_alpha= av_pix_fmt_desc_get(ref->format)->nb_components % 2 == 0;
839 116 enum AVPixelFormat best= AV_PIX_FMT_NONE;
840 int i;
841
2/2
✓ Branch 0 taken 1127 times.
✓ Branch 1 taken 116 times.
1243 for (i = 0; i < link->incfg.formats->nb_formats; i++) {
842 1127 enum AVPixelFormat p = link->incfg.formats->formats[i];
843 1127 best= av_find_best_pix_fmt_of_2(best, p, ref->format, has_alpha, NULL);
844 }
845 116 av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s alpha:%d\n",
846 116 av_get_pix_fmt_name(best), link->incfg.formats->nb_formats,
847 116 av_get_pix_fmt_name(ref->format), has_alpha);
848 116 link->incfg.formats->formats[0] = best;
849 }
850
1/2
✓ Branch 0 taken 7007 times.
✗ Branch 1 not taken.
7007 } else if (link->type == AVMEDIA_TYPE_AUDIO) {
851
3/4
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 6851 times.
✓ Branch 2 taken 156 times.
✗ Branch 3 not taken.
7007 if(ref && ref->type == AVMEDIA_TYPE_AUDIO){
852 156 enum AVSampleFormat best= AV_SAMPLE_FMT_NONE;
853 int i;
854
2/2
✓ Branch 0 taken 631 times.
✓ Branch 1 taken 156 times.
787 for (i = 0; i < link->incfg.formats->nb_formats; i++) {
855 631 enum AVSampleFormat p = link->incfg.formats->formats[i];
856 631 best = find_best_sample_fmt_of_2(best, p, ref->format);
857 }
858 156 av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s\n",
859 156 av_get_sample_fmt_name(best), link->incfg.formats->nb_formats,
860 156 av_get_sample_fmt_name(ref->format));
861 156 link->incfg.formats->formats[0] = best;
862 }
863 }
864
865 38639 link->incfg.formats->nb_formats = 1;
866 38639 link->format = link->incfg.formats->formats[0];
867
868
2/2
✓ Branch 0 taken 31632 times.
✓ Branch 1 taken 7007 times.
38639 if (link->type == AVMEDIA_TYPE_VIDEO) {
869 31632 enum AVPixelFormat swfmt = link->format;
870
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 31632 times.
31632 if (av_pix_fmt_desc_get(swfmt)->flags & AV_PIX_FMT_FLAG_HWACCEL) {
871 // FIXME: this is a hack - we'd like to use the sw_format of
872 // link->hw_frames_ctx here, but it is not yet available.
873 // To make this work properly we will need to either reorder
874 // things so that it is available here or somehow negotiate
875 // sw_format separately.
876 ✗ swfmt = AV_PIX_FMT_YUV420P;
877 }
878
879 31632 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(swfmt);
880
2/2
✓ Branch 1 taken 9960 times.
✓ Branch 2 taken 21672 times.
31632 if (!ff_fmt_is_regular_yuv(swfmt)) {
881 /* These fields are explicitly documented as affecting YUV only,
882 * so set them to sane values for other formats. */
883
2/2
✓ Branch 0 taken 606 times.
✓ Branch 1 taken 9354 times.
9960 if (desc->flags & AV_PIX_FMT_FLAG_FLOAT)
884 606 link->color_range = AVCOL_RANGE_UNSPECIFIED;
885 else
886 9354 link->color_range = AVCOL_RANGE_JPEG;
887
2/2
✓ Branch 0 taken 8324 times.
✓ Branch 1 taken 1636 times.
9960 if (desc->flags & (AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_XYZ)) {
888 8324 link->colorspace = AVCOL_SPC_RGB;
889 } else {
890 1636 link->colorspace = AVCOL_SPC_UNSPECIFIED;
891 }
892 } else {
893
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21672 times.
21672 if (!link->incfg.color_spaces->nb_formats) {
894 ✗ av_log(link->src, AV_LOG_ERROR, "Cannot select color space for"
895 ✗ " the link between filters %s and %s.\n", link->src->name,
896 ✗ link->dst->name);
897 ✗ return AVERROR(EINVAL);
898 }
899 21672 link->incfg.color_spaces->nb_formats = 1;
900 21672 link->colorspace = link->incfg.color_spaces->formats[0];
901
902
2/2
✓ Branch 1 taken 703 times.
✓ Branch 2 taken 20969 times.
21672 if (ff_fmt_is_forced_full_range(swfmt)) {
903 703 link->color_range = AVCOL_RANGE_JPEG;
904 } else {
905
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20969 times.
20969 if (!link->incfg.color_ranges->nb_formats) {
906 ✗ av_log(link->src, AV_LOG_ERROR, "Cannot select color range for"
907 ✗ " the link between filters %s and %s.\n", link->src->name,
908 ✗ link->dst->name);
909 ✗ return AVERROR(EINVAL);
910 }
911 20969 link->incfg.color_ranges->nb_formats = 1;
912 20969 link->color_range = link->incfg.color_ranges->formats[0];
913 }
914 }
915
916
2/2
✓ Branch 0 taken 3796 times.
✓ Branch 1 taken 27836 times.
31632 if (desc->flags & AV_PIX_FMT_FLAG_ALPHA) {
917
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3796 times.
3796 if (!link->incfg.alpha_modes->nb_formats) {
918 ✗ av_log(link->src, AV_LOG_ERROR, "Cannot select alpha mode for"
919 ✗ " the link between filters %s and %s.\n", link->src->name,
920 ✗ link->dst->name);
921 ✗ return AVERROR(EINVAL);
922 }
923 3796 link->incfg.alpha_modes->nb_formats = 1;
924 3796 link->alpha_mode = link->incfg.alpha_modes->formats[0];
925 } else {
926 27836 link->alpha_mode = AVALPHA_MODE_UNSPECIFIED;
927 }
928
929
4/4
✓ Branch 0 taken 17279 times.
✓ Branch 1 taken 14353 times.
✓ Branch 2 taken 512 times.
✓ Branch 3 taken 16767 times.
31632 if (desc->log2_chroma_w || desc->log2_chroma_h) {
930
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14865 times.
14865 if (!link->incfg.chroma_locations->nb_formats) {
931 ✗ av_log(link->src, AV_LOG_ERROR, "Cannot select chroma location"
932 ✗ " for the link between filters %s and %s.\n", link->src->name,
933 ✗ link->dst->name);
934 ✗ return AVERROR(EINVAL);
935 }
936 14865 link->incfg.chroma_locations->nb_formats = 1;
937 14865 link->chroma_location = link->incfg.chroma_locations->formats[0];
938 } else {
939 /* Chroma location is meaningless without subsampled chroma. */
940 16767 link->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
941 }
942
1/2
✓ Branch 0 taken 7007 times.
✗ Branch 1 not taken.
7007 } else if (link->type == AVMEDIA_TYPE_AUDIO) {
943 int ret;
944
945
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7007 times.
7007 if (!link->incfg.samplerates->nb_formats) {
946 ✗ av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
947 ✗ " the link between filters %s and %s.\n", link->src->name,
948 ✗ link->dst->name);
949 ✗ return AVERROR(EINVAL);
950 }
951 7007 link->incfg.samplerates->nb_formats = 1;
952 7007 link->sample_rate = link->incfg.samplerates->formats[0];
953
954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7007 times.
7007 if (link->incfg.channel_layouts->all_layouts) {
955 ✗ av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
956 ✗ " the link between filters %s and %s.\n", link->src->name,
957 ✗ link->dst->name);
958 ✗ if (!link->incfg.channel_layouts->all_counts)
959 ✗ av_log(link->src, AV_LOG_ERROR, "Unknown channel layouts not "
960 "supported, try specifying a channel layout using "
961 "'aformat=channel_layouts=something'.\n");
962 ✗ return AVERROR(EINVAL);
963 }
964 7007 link->incfg.channel_layouts->nb_channel_layouts = 1;
965 7007 ret = av_channel_layout_copy(&link->ch_layout, &link->incfg.channel_layouts->channel_layouts[0]);
966
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7007 times.
7007 if (ret < 0)
967 ✗ return ret;
968 }
969
970 38639 ff_formats_unref(&link->incfg.formats);
971 38639 ff_formats_unref(&link->outcfg.formats);
972 38639 ff_formats_unref(&link->incfg.samplerates);
973 38639 ff_formats_unref(&link->outcfg.samplerates);
974 38639 ff_channel_layouts_unref(&link->incfg.channel_layouts);
975 38639 ff_channel_layouts_unref(&link->outcfg.channel_layouts);
976 38639 ff_formats_unref(&link->incfg.color_spaces);
977 38639 ff_formats_unref(&link->outcfg.color_spaces);
978 38639 ff_formats_unref(&link->incfg.color_ranges);
979 38639 ff_formats_unref(&link->outcfg.color_ranges);
980 38639 ff_formats_unref(&link->incfg.alpha_modes);
981 38639 ff_formats_unref(&link->outcfg.alpha_modes);
982 38639 ff_formats_unref(&link->incfg.chroma_locations);
983 38639 ff_formats_unref(&link->outcfg.chroma_locations);
984
985 38639 return 0;
986 }
987
988 #define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format) \
989 do { \
990 for (i = 0; i < filter->nb_inputs; i++) { \
991 AVFilterLink *link = filter->inputs[i]; \
992 fmt_type fmt; \
993 \
994 if (!link->outcfg.list || link->outcfg.list->nb != 1) \
995 continue; \
996 fmt = link->outcfg.list->var[0]; \
997 \
998 for (j = 0; j < filter->nb_outputs; j++) { \
999 AVFilterLink *out_link = filter->outputs[j]; \
1000 list_type *fmts; \
1001 \
1002 if (link->type != out_link->type || \
1003 out_link->incfg.list->nb == 1) \
1004 continue; \
1005 fmts = out_link->incfg.list; \
1006 \
1007 if (!out_link->incfg.list->nb) { \
1008 if ((ret = add_format(&out_link->incfg.list, fmt)) < 0)\
1009 return ret; \
1010 ret = 1; \
1011 break; \
1012 } \
1013 \
1014 for (k = 0; k < out_link->incfg.list->nb; k++) \
1015 if (fmts->var[k] == fmt) { \
1016 fmts->var[0] = fmt; \
1017 fmts->nb = 1; \
1018 ret = 1; \
1019 break; \
1020 } \
1021 } \
1022 } \
1023 } while (0)
1024
1025 75980 static int reduce_formats_on_filter(AVFilterContext *filter)
1026 {
1027 75980 int i, j, k, ret = 0;
1028
1029
16/20
✓ Branch 0 taken 62501 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1591 times.
✓ Branch 3 taken 60910 times.
✓ Branch 4 taken 47762 times.
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 47118 times.
✓ Branch 7 taken 644 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 644 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 87 times.
✓ Branch 14 taken 4978 times.
✓ Branch 15 taken 5065 times.
✓ Branch 16 taken 557 times.
✓ Branch 17 taken 47774 times.
✓ Branch 18 taken 60910 times.
✓ Branch 19 taken 62501 times.
✓ Branch 20 taken 75980 times.
191233 REDUCE_FORMATS(int, AVFilterFormats, formats, formats,
1030 nb_formats, ff_add_format);
1031
18/20
✓ Branch 0 taken 12689 times.
✓ Branch 1 taken 49812 times.
✓ Branch 2 taken 1536 times.
✓ Branch 3 taken 11153 times.
✓ Branch 4 taken 9183 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 8174 times.
✓ Branch 7 taken 1009 times.
✓ Branch 8 taken 850 times.
✓ Branch 9 taken 159 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 850 times.
✓ Branch 13 taken 159 times.
✓ Branch 14 taken 630 times.
✓ Branch 15 taken 789 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 9189 times.
✓ Branch 18 taken 10303 times.
✓ Branch 19 taken 62501 times.
✓ Branch 20 taken 75980 times.
147450 REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats,
1032 nb_formats, ff_add_format);
1033
15/20
✓ Branch 0 taken 49812 times.
✓ Branch 1 taken 12689 times.
✓ Branch 2 taken 11992 times.
✓ Branch 3 taken 37820 times.
✓ Branch 4 taken 29730 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 25642 times.
✓ Branch 7 taken 4088 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 4088 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 4088 times.
✓ Branch 14 taken 522 times.
✓ Branch 15 taken 4610 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 29730 times.
✓ Branch 18 taken 37820 times.
✓ Branch 19 taken 62501 times.
✓ Branch 20 taken 75980 times.
168733 REDUCE_FORMATS(int, AVFilterFormats, color_spaces, formats,
1034 nb_formats, ff_add_format);
1035
15/20
✓ Branch 0 taken 49812 times.
✓ Branch 1 taken 12689 times.
✓ Branch 2 taken 9291 times.
✓ Branch 3 taken 40521 times.
✓ Branch 4 taken 31001 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 27675 times.
✓ Branch 7 taken 3326 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3326 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 3326 times.
✓ Branch 14 taken 3308 times.
✓ Branch 15 taken 6634 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 31001 times.
✓ Branch 18 taken 40521 times.
✓ Branch 19 taken 62501 times.
✓ Branch 20 taken 75980 times.
172790 REDUCE_FORMATS(int, AVFilterFormats, color_ranges, formats,
1036 nb_formats, ff_add_format);
1037
15/20
✓ Branch 0 taken 49812 times.
✓ Branch 1 taken 12689 times.
✓ Branch 2 taken 49161 times.
✓ Branch 3 taken 651 times.
✓ Branch 4 taken 505 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 503 times.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
✓ Branch 14 taken 4 times.
✓ Branch 15 taken 6 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 505 times.
✓ Branch 18 taken 651 times.
✓ Branch 19 taken 62501 times.
✓ Branch 20 taken 75980 times.
138990 REDUCE_FORMATS(int, AVFilterFormats, alpha_modes, formats,
1038 nb_formats, ff_add_format);
1039
16/20
✓ Branch 0 taken 49812 times.
✓ Branch 1 taken 12689 times.
✓ Branch 2 taken 42719 times.
✓ Branch 3 taken 7093 times.
✓ Branch 4 taken 5071 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4671 times.
✓ Branch 7 taken 400 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 400 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 398 times.
✓ Branch 14 taken 762 times.
✓ Branch 15 taken 1160 times.
✓ Branch 16 taken 2 times.
✓ Branch 17 taken 5071 times.
✓ Branch 18 taken 7093 times.
✓ Branch 19 taken 62501 times.
✓ Branch 20 taken 75980 times.
144314 REDUCE_FORMATS(int, AVFilterFormats, chroma_locations, formats,
1040 nb_formats, ff_add_format);
1041
1042 /* reduce channel layouts */
1043
2/2
✓ Branch 0 taken 62501 times.
✓ Branch 1 taken 75980 times.
138481 for (i = 0; i < filter->nb_inputs; i++) {
1044 62501 AVFilterLink *inlink = filter->inputs[i];
1045 const AVChannelLayout *fmt;
1046
1047
2/2
✓ Branch 0 taken 12689 times.
✓ Branch 1 taken 49812 times.
62501 if (!inlink->outcfg.channel_layouts ||
1048
2/2
✓ Branch 0 taken 306 times.
✓ Branch 1 taken 12383 times.
12689 inlink->outcfg.channel_layouts->nb_channel_layouts != 1)
1049 50118 continue;
1050 12383 fmt = &inlink->outcfg.channel_layouts->channel_layouts[0];
1051
1052
2/2
✓ Branch 0 taken 9972 times.
✓ Branch 1 taken 11488 times.
21460 for (j = 0; j < filter->nb_outputs; j++) {
1053 9972 AVFilterLink *outlink = filter->outputs[j];
1054 AVFilterChannelLayouts *fmts;
1055
1056 9972 fmts = outlink->incfg.channel_layouts;
1057
4/4
✓ Branch 0 taken 9966 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 8915 times.
✓ Branch 3 taken 1051 times.
9972 if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1)
1058 8921 continue;
1059
1060
2/2
✓ Branch 0 taken 895 times.
✓ Branch 1 taken 156 times.
1051 if (fmts->all_layouts &&
1061
4/6
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 888 times.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
895 (KNOWN(fmt) || fmts->all_counts)) {
1062 /* Turn the infinite list into a singleton */
1063 895 fmts->all_layouts = fmts->all_counts = 0;
1064 895 ret = ff_add_channel_layout(&outlink->incfg.channel_layouts, fmt);
1065
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 895 times.
895 if (ret < 0)
1066 ✗ return ret;
1067 895 ret = 1;
1068 895 break;
1069 }
1070
1071
2/2
✓ Branch 0 taken 266 times.
✓ Branch 1 taken 8 times.
274 for (k = 0; k < outlink->incfg.channel_layouts->nb_channel_layouts; k++) {
1072
2/2
✓ Branch 1 taken 148 times.
✓ Branch 2 taken 118 times.
266 if (!av_channel_layout_compare(&fmts->channel_layouts[k], fmt)) {
1073 148 ret = av_channel_layout_copy(&fmts->channel_layouts[0], fmt);
1074
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 148 times.
148 if (ret < 0)
1075 ✗ return ret;
1076 148 fmts->nb_channel_layouts = 1;
1077 148 ret = 1;
1078 148 break;
1079 }
1080 }
1081 }
1082 }
1083
1084 75980 return ret;
1085 }
1086
1087 8516 static int reduce_formats(AVFilterGraph *graph)
1088 {
1089 int i, reduced, ret;
1090
1091 do {
1092 13414 reduced = 0;
1093
1094
2/2
✓ Branch 0 taken 75980 times.
✓ Branch 1 taken 13414 times.
89394 for (i = 0; i < graph->nb_filters; i++) {
1095
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 75980 times.
75980 if ((ret = reduce_formats_on_filter(graph->filters[i])) < 0)
1096 ✗ return ret;
1097 75980 reduced |= ret;
1098 }
1099
2/2
✓ Branch 0 taken 4898 times.
✓ Branch 1 taken 8516 times.
13414 } while (reduced);
1100
1101 8516 return 0;
1102 }
1103
1104 47185 static void swap_samplerates_on_filter(AVFilterContext *filter)
1105 {
1106 47185 AVFilterLink *link = NULL;
1107 int sample_rate;
1108 int i, j;
1109
1110
2/2
✓ Branch 0 taken 38548 times.
✓ Branch 1 taken 40265 times.
78813 for (i = 0; i < filter->nb_inputs; i++) {
1111 38548 link = filter->inputs[i];
1112
1113
2/2
✓ Branch 0 taken 6920 times.
✓ Branch 1 taken 31628 times.
38548 if (link->type == AVMEDIA_TYPE_AUDIO &&
1114
1/2
✓ Branch 0 taken 6920 times.
✗ Branch 1 not taken.
6920 link->outcfg.samplerates->nb_formats== 1)
1115 6920 break;
1116 }
1117
2/2
✓ Branch 0 taken 40265 times.
✓ Branch 1 taken 6920 times.
47185 if (i == filter->nb_inputs)
1118 40265 return;
1119
1120 6920 sample_rate = link->outcfg.samplerates->formats[0];
1121
1122
2/2
✓ Branch 0 taken 5434 times.
✓ Branch 1 taken 6920 times.
12354 for (i = 0; i < filter->nb_outputs; i++) {
1123 5434 AVFilterLink *outlink = filter->outputs[i];
1124 5434 int best_idx, best_diff = INT_MAX;
1125
1126
2/2
✓ Branch 0 taken 5432 times.
✓ Branch 1 taken 2 times.
5434 if (outlink->type != AVMEDIA_TYPE_AUDIO ||
1127
1/2
✓ Branch 0 taken 5432 times.
✗ Branch 1 not taken.
5432 outlink->incfg.samplerates->nb_formats < 2)
1128 5434 continue;
1129
1130 ✗ for (j = 0; j < outlink->incfg.samplerates->nb_formats; j++) {
1131 ✗ int diff = abs(sample_rate - outlink->incfg.samplerates->formats[j]);
1132
1133 ✗ av_assert0(diff < INT_MAX); // This would lead to the use of uninitialized best_diff but is only possible with invalid sample rates
1134
1135 ✗ if (diff < best_diff) {
1136 ✗ best_diff = diff;
1137 ✗ best_idx = j;
1138 }
1139 }
1140 ✗ FFSWAP(int, outlink->incfg.samplerates->formats[0],
1141 outlink->incfg.samplerates->formats[best_idx]);
1142 }
1143 }
1144
1145 8516 static void swap_samplerates(AVFilterGraph *graph)
1146 {
1147 int i;
1148
1149
2/2
✓ Branch 0 taken 47185 times.
✓ Branch 1 taken 8516 times.
55701 for (i = 0; i < graph->nb_filters; i++)
1150 47185 swap_samplerates_on_filter(graph->filters[i]);
1151 8516 }
1152
1153 #define CH_CENTER_PAIR (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)
1154 #define CH_FRONT_PAIR (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT)
1155 #define CH_STEREO_PAIR (AV_CH_STEREO_LEFT | AV_CH_STEREO_RIGHT)
1156 #define CH_WIDE_PAIR (AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT)
1157 #define CH_SIDE_PAIR (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT)
1158 #define CH_DIRECT_PAIR (AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT)
1159 #define CH_BACK_PAIR (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT)
1160
1161 /* allowable substitutions for channel pairs when comparing layouts,
1162 * ordered by priority for both values */
1163 static const uint64_t ch_subst[][2] = {
1164 { CH_FRONT_PAIR, CH_CENTER_PAIR },
1165 { CH_FRONT_PAIR, CH_WIDE_PAIR },
1166 { CH_FRONT_PAIR, AV_CH_FRONT_CENTER },
1167 { CH_CENTER_PAIR, CH_FRONT_PAIR },
1168 { CH_CENTER_PAIR, CH_WIDE_PAIR },
1169 { CH_CENTER_PAIR, AV_CH_FRONT_CENTER },
1170 { CH_WIDE_PAIR, CH_FRONT_PAIR },
1171 { CH_WIDE_PAIR, CH_CENTER_PAIR },
1172 { CH_WIDE_PAIR, AV_CH_FRONT_CENTER },
1173 { AV_CH_FRONT_CENTER, CH_FRONT_PAIR },
1174 { AV_CH_FRONT_CENTER, CH_CENTER_PAIR },
1175 { AV_CH_FRONT_CENTER, CH_WIDE_PAIR },
1176 { CH_SIDE_PAIR, CH_DIRECT_PAIR },
1177 { CH_SIDE_PAIR, CH_BACK_PAIR },
1178 { CH_SIDE_PAIR, AV_CH_BACK_CENTER },
1179 { CH_BACK_PAIR, CH_DIRECT_PAIR },
1180 { CH_BACK_PAIR, CH_SIDE_PAIR },
1181 { CH_BACK_PAIR, AV_CH_BACK_CENTER },
1182 { AV_CH_BACK_CENTER, CH_BACK_PAIR },
1183 { AV_CH_BACK_CENTER, CH_DIRECT_PAIR },
1184 { AV_CH_BACK_CENTER, CH_SIDE_PAIR },
1185 };
1186
1187 47185 static void swap_channel_layouts_on_filter(AVFilterContext *filter)
1188 {
1189 47185 AVFilterLink *link = NULL;
1190 int i, j, k;
1191
1192
2/2
✓ Branch 0 taken 38548 times.
✓ Branch 1 taken 40273 times.
78821 for (i = 0; i < filter->nb_inputs; i++) {
1193 38548 link = filter->inputs[i];
1194
1195
2/2
✓ Branch 0 taken 6920 times.
✓ Branch 1 taken 31628 times.
38548 if (link->type == AVMEDIA_TYPE_AUDIO &&
1196
2/2
✓ Branch 0 taken 6912 times.
✓ Branch 1 taken 8 times.
6920 link->outcfg.channel_layouts->nb_channel_layouts == 1)
1197 6912 break;
1198 }
1199
2/2
✓ Branch 0 taken 40273 times.
✓ Branch 1 taken 6912 times.
47185 if (i == filter->nb_inputs)
1200 40273 return;
1201
1202
2/2
✓ Branch 0 taken 5430 times.
✓ Branch 1 taken 6912 times.
12342 for (i = 0; i < filter->nb_outputs; i++) {
1203 5430 AVFilterLink *outlink = filter->outputs[i];
1204 5430 int best_idx = -1, best_score = INT_MIN, best_count_diff = INT_MAX;
1205
1206
2/2
✓ Branch 0 taken 5428 times.
✓ Branch 1 taken 2 times.
5430 if (outlink->type != AVMEDIA_TYPE_AUDIO ||
1207
2/2
✓ Branch 0 taken 5424 times.
✓ Branch 1 taken 4 times.
5428 outlink->incfg.channel_layouts->nb_channel_layouts < 2)
1208 5426 continue;
1209
1210
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 4 times.
43 for (j = 0; j < outlink->incfg.channel_layouts->nb_channel_layouts; j++) {
1211 39 AVChannelLayout in_chlayout = link->outcfg.channel_layouts->channel_layouts[0];
1212 39 AVChannelLayout out_chlayout = outlink->incfg.channel_layouts->channel_layouts[j];
1213 int in_channels;
1214 int out_channels;
1215 int count_diff;
1216 int matched_channels, extra_channels;
1217 39 int score = 100000;
1218
1219 39 in_channels = in_chlayout.nb_channels;
1220 39 out_channels = out_chlayout.nb_channels;
1221 39 count_diff = out_channels - in_channels;
1222
4/8
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 23 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
39 if (!KNOWN(&in_chlayout) || !KNOWN(&out_chlayout)) {
1223 /* Compute score in case the input or output layout encodes
1224 a channel count; in this case the score is not altered by
1225 the computation afterwards, as in_chlayout and
1226 out_chlayout have both been set to 0 */
1227
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))
1228
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 in_channels = FF_LAYOUT2COUNT(&in_chlayout);
1229
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 if (!KNOWN(&out_chlayout))
1230 ✗ out_channels = FF_LAYOUT2COUNT(&out_chlayout);
1231 32 score -= 10000 + FFABS(out_channels - in_channels) +
1232
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 (in_channels > out_channels ? 10000 : 0);
1233 16 in_chlayout = (AVChannelLayout){ 0 };
1234 16 out_chlayout = (AVChannelLayout){ 0 };
1235 /* Let the remaining computation run, even if the score
1236 value is not altered */
1237 }
1238
1239 /* channel substitution */
1240
2/2
✓ Branch 0 taken 819 times.
✓ Branch 1 taken 39 times.
858 for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) {
1241 819 uint64_t cmp0 = ch_subst[k][0];
1242 819 uint64_t cmp1 = ch_subst[k][1];
1243
4/4
✓ Branch 1 taken 258 times.
✓ Branch 2 taken 561 times.
✓ Branch 3 taken 141 times.
✓ Branch 4 taken 117 times.
1077 if ( av_channel_layout_subset(& in_chlayout, cmp0) &&
1244
2/2
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 115 times.
399 !av_channel_layout_subset(&out_chlayout, cmp0) &&
1245
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 19 times.
167 av_channel_layout_subset(&out_chlayout, cmp1) &&
1246 26 !av_channel_layout_subset(& in_chlayout, cmp1)) {
1247 7 av_channel_layout_from_mask(&in_chlayout, av_channel_layout_subset(& in_chlayout, ~cmp0));
1248 7 av_channel_layout_from_mask(&out_chlayout, av_channel_layout_subset(&out_chlayout, ~cmp1));
1249 /* add score for channel match, minus a deduction for
1250 having to do the substitution */
1251 7 score += 10 * av_popcount64(cmp1) - 2;
1252 }
1253 }
1254
1255 /* no penalty for LFE channel mismatch */
1256
4/4
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 15 times.
62 if (av_channel_layout_index_from_channel(&in_chlayout, AV_CHAN_LOW_FREQUENCY) >= 0 &&
1257 23 av_channel_layout_index_from_channel(&out_chlayout, AV_CHAN_LOW_FREQUENCY) >= 0)
1258 8 score += 10;
1259 39 av_channel_layout_from_mask(&in_chlayout, av_channel_layout_subset(&in_chlayout, ~AV_CH_LOW_FREQUENCY));
1260 39 av_channel_layout_from_mask(&out_chlayout, av_channel_layout_subset(&out_chlayout, ~AV_CH_LOW_FREQUENCY));
1261
1262 39 matched_channels = av_popcount64(in_chlayout.u.mask & out_chlayout.u.mask);
1263 39 extra_channels = av_popcount64(out_chlayout.u.mask & (~in_chlayout.u.mask));
1264 39 score += 10 * matched_channels - 5 * extra_channels;
1265
1266
4/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 20 times.
39 if (score > best_score ||
1267
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 (count_diff < best_count_diff && score == best_score)) {
1268 15 best_score = score;
1269 15 best_idx = j;
1270 15 best_count_diff = count_diff;
1271 }
1272 }
1273
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 av_assert0(best_idx >= 0);
1274 4 FFSWAP(AVChannelLayout, outlink->incfg.channel_layouts->channel_layouts[0],
1275 outlink->incfg.channel_layouts->channel_layouts[best_idx]);
1276 }
1277
1278 }
1279
1280 8516 static void swap_channel_layouts(AVFilterGraph *graph)
1281 {
1282 int i;
1283
1284
2/2
✓ Branch 0 taken 47185 times.
✓ Branch 1 taken 8516 times.
55701 for (i = 0; i < graph->nb_filters; i++)
1285 47185 swap_channel_layouts_on_filter(graph->filters[i]);
1286 8516 }
1287
1288 47185 static void swap_sample_fmts_on_filter(AVFilterContext *filter)
1289 {
1290 47185 AVFilterLink *link = NULL;
1291 int format, bps;
1292 int i, j;
1293
1294
2/2
✓ Branch 0 taken 38618 times.
✓ Branch 1 taken 40691 times.
79309 for (i = 0; i < filter->nb_inputs; i++) {
1295 38618 link = filter->inputs[i];
1296
1297
2/2
✓ Branch 0 taken 6990 times.
✓ Branch 1 taken 31628 times.
38618 if (link->type == AVMEDIA_TYPE_AUDIO &&
1298
2/2
✓ Branch 0 taken 6494 times.
✓ Branch 1 taken 496 times.
6990 link->outcfg.formats->nb_formats == 1)
1299 6494 break;
1300 }
1301
2/2
✓ Branch 0 taken 40691 times.
✓ Branch 1 taken 6494 times.
47185 if (i == filter->nb_inputs)
1302 40691 return;
1303
1304 6494 format = link->outcfg.formats->formats[0];
1305 6494 bps = av_get_bytes_per_sample(format);
1306
1307
2/2
✓ Branch 0 taken 5033 times.
✓ Branch 1 taken 6494 times.
11527 for (i = 0; i < filter->nb_outputs; i++) {
1308 5033 AVFilterLink *outlink = filter->outputs[i];
1309 5033 int best_idx = -1, best_score = INT_MIN;
1310
1311
2/2
✓ Branch 0 taken 5031 times.
✓ Branch 1 taken 2 times.
5033 if (outlink->type != AVMEDIA_TYPE_AUDIO ||
1312
2/2
✓ Branch 0 taken 4860 times.
✓ Branch 1 taken 171 times.
5031 outlink->incfg.formats->nb_formats < 2)
1313 4862 continue;
1314
1315
2/2
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 10 times.
347 for (j = 0; j < outlink->incfg.formats->nb_formats; j++) {
1316 337 int out_format = outlink->incfg.formats->formats[j];
1317 337 int out_bps = av_get_bytes_per_sample(out_format);
1318 int score;
1319
1320
4/4
✓ Branch 1 taken 196 times.
✓ Branch 2 taken 141 times.
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 176 times.
533 if (av_get_packed_sample_fmt(out_format) == format ||
1321 196 av_get_planar_sample_fmt(out_format) == format) {
1322 161 best_idx = j;
1323 161 break;
1324 }
1325
1326 /* for s32 and float prefer double to prevent loss of information */
1327
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 170 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
176 if (bps == 4 && out_bps == 8) {
1328 ✗ best_idx = j;
1329 ✗ break;
1330 }
1331
1332 /* prefer closest higher or equal bps */
1333 176 score = -abs(out_bps - bps);
1334
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 143 times.
176 if (out_bps >= bps)
1335 33 score += INT_MAX/2;
1336
1337
2/2
✓ Branch 0 taken 135 times.
✓ Branch 1 taken 41 times.
176 if (score > best_score) {
1338 135 best_score = score;
1339 135 best_idx = j;
1340 }
1341 }
1342
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 171 times.
171 av_assert0(best_idx >= 0);
1343 171 FFSWAP(int, outlink->incfg.formats->formats[0],
1344 outlink->incfg.formats->formats[best_idx]);
1345 }
1346 }
1347
1348 8516 static void swap_sample_fmts(AVFilterGraph *graph)
1349 {
1350 int i;
1351
1352
2/2
✓ Branch 0 taken 47185 times.
✓ Branch 1 taken 8516 times.
55701 for (i = 0; i < graph->nb_filters; i++)
1353 47185 swap_sample_fmts_on_filter(graph->filters[i]);
1354
1355 8516 }
1356
1357 8516 static int pick_formats(AVFilterGraph *graph)
1358 {
1359 int i, j, ret;
1360 int change;
1361
1362 do{
1363 17054 change = 0;
1364
2/2
✓ Branch 0 taken 95302 times.
✓ Branch 1 taken 17054 times.
112356 for (i = 0; i < graph->nb_filters; i++) {
1365 95302 AVFilterContext *filter = graph->filters[i];
1366
2/2
✓ Branch 0 taken 77714 times.
✓ Branch 1 taken 17588 times.
95302 if (filter->nb_inputs){
1367
2/2
✓ Branch 0 taken 78148 times.
✓ Branch 1 taken 77714 times.
155862 for (j = 0; j < filter->nb_inputs; j++){
1368
4/4
✓ Branch 0 taken 16687 times.
✓ Branch 1 taken 61461 times.
✓ Branch 2 taken 16102 times.
✓ Branch 3 taken 585 times.
78148 if (filter->inputs[j]->incfg.formats && filter->inputs[j]->incfg.formats->nb_formats == 1) {
1369
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 16102 times.
16102 if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
1370 ✗ return ret;
1371 16102 change = 1;
1372 }
1373 }
1374 }
1375
2/2
✓ Branch 0 taken 77660 times.
✓ Branch 1 taken 17642 times.
95302 if (filter->nb_outputs){
1376
2/2
✓ Branch 0 taken 78148 times.
✓ Branch 1 taken 77660 times.
155808 for (j = 0; j < filter->nb_outputs; j++){
1377
4/4
✓ Branch 0 taken 22875 times.
✓ Branch 1 taken 55273 times.
✓ Branch 2 taken 22166 times.
✓ Branch 3 taken 709 times.
78148 if (filter->outputs[j]->incfg.formats && filter->outputs[j]->incfg.formats->nb_formats == 1) {
1378
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 22166 times.
22166 if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
1379 ✗ return ret;
1380 22166 change = 1;
1381 }
1382 }
1383 }
1384
6/6
✓ Branch 0 taken 77714 times.
✓ Branch 1 taken 17588 times.
✓ Branch 2 taken 60072 times.
✓ Branch 3 taken 17642 times.
✓ Branch 4 taken 59750 times.
✓ Branch 5 taken 322 times.
95302 if (filter->nb_inputs && filter->nb_outputs && filter->inputs[0]->format>=0) {
1385
2/2
✓ Branch 0 taken 60170 times.
✓ Branch 1 taken 59750 times.
119920 for (j = 0; j < filter->nb_outputs; j++) {
1386
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 59898 times.
60170 if (filter->outputs[j]->format<0) {
1387
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 272 times.
272 if ((ret = pick_format(filter->outputs[j], filter->inputs[0])) < 0)
1388 ✗ return ret;
1389 272 change = 1;
1390 }
1391 }
1392 }
1393 }
1394
2/2
✓ Branch 0 taken 8538 times.
✓ Branch 1 taken 8516 times.
17054 }while(change);
1395
1396
2/2
✓ Branch 0 taken 47185 times.
✓ Branch 1 taken 8516 times.
55701 for (i = 0; i < graph->nb_filters; i++) {
1397 47185 AVFilterContext *filter = graph->filters[i];
1398
1399
2/2
✓ Branch 0 taken 38639 times.
✓ Branch 1 taken 47185 times.
85824 for (j = 0; j < filter->nb_inputs; j++)
1400
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 38639 times.
38639 if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
1401 ✗ return ret;
1402
2/2
✓ Branch 0 taken 38639 times.
✓ Branch 1 taken 47185 times.
85824 for (j = 0; j < filter->nb_outputs; j++)
1403
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 38639 times.
38639 if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
1404 ✗ return ret;
1405 }
1406 8516 return 0;
1407 }
1408
1409 /**
1410 * Configure the formats of all the links in the graph.
1411 */
1412 8516 static int graph_config_formats(AVFilterGraph *graph, void *log_ctx)
1413 {
1414 int ret;
1415
1416 /* find supported formats from sub-filters, and merge along links */
1417
2/2
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 8516 times.
8531 while ((ret = query_formats(graph, log_ctx)) == AVERROR(EAGAIN))
1418 15 av_log(graph, AV_LOG_DEBUG, "query_formats not finished\n");
1419
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8516 times.
8516 if (ret < 0)
1420 ✗ return ret;
1421
1422 /* Once everything is merged, it's possible that we'll still have
1423 * multiple valid media format choices. We try to minimize the amount
1424 * of format conversion inside filters */
1425
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8516 times.
8516 if ((ret = reduce_formats(graph)) < 0)
1426 ✗ return ret;
1427
1428 /* for audio filters, ensure the best format, sample rate and channel layout
1429 * is selected */
1430 8516 swap_sample_fmts(graph);
1431 8516 swap_samplerates(graph);
1432 8516 swap_channel_layouts(graph);
1433
1434
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8516 times.
8516 if ((ret = pick_formats(graph)) < 0)
1435 ✗ return ret;
1436
1437 8516 return 0;
1438 }
1439
1440 8514 static int graph_config_pointers(AVFilterGraph *graph, void *log_ctx)
1441 {
1442 unsigned i, j;
1443 8514 int sink_links_count = 0, n = 0;
1444 AVFilterContext *f;
1445 FilterLinkInternal **sinks;
1446
1447
2/2
✓ Branch 0 taken 47173 times.
✓ Branch 1 taken 8514 times.
55687 for (i = 0; i < graph->nb_filters; i++) {
1448 47173 f = graph->filters[i];
1449
2/2
✓ Branch 0 taken 38629 times.
✓ Branch 1 taken 47173 times.
85802 for (j = 0; j < f->nb_inputs; j++) {
1450 38629 ff_link_internal(f->inputs[j])->age_index = -1;
1451 }
1452
2/2
✓ Branch 0 taken 38629 times.
✓ Branch 1 taken 47173 times.
85802 for (j = 0; j < f->nb_outputs; j++) {
1453 38629 ff_link_internal(f->outputs[j])->age_index = -1;
1454 }
1455
2/2
✓ Branch 0 taken 8753 times.
✓ Branch 1 taken 38420 times.
47173 if (!f->nb_outputs) {
1456
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8753 times.
8753 if (f->nb_inputs > INT_MAX - sink_links_count)
1457 ✗ return AVERROR(EINVAL);
1458 8753 sink_links_count += f->nb_inputs;
1459 }
1460 }
1461 8514 sinks = av_calloc(sink_links_count, sizeof(*sinks));
1462
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8514 times.
8514 if (!sinks)
1463 ✗ return AVERROR(ENOMEM);
1464
2/2
✓ Branch 0 taken 47173 times.
✓ Branch 1 taken 8514 times.
55687 for (i = 0; i < graph->nb_filters; i++) {
1465 47173 f = graph->filters[i];
1466
2/2
✓ Branch 0 taken 8753 times.
✓ Branch 1 taken 38420 times.
47173 if (!f->nb_outputs) {
1467
2/2
✓ Branch 0 taken 8753 times.
✓ Branch 1 taken 8753 times.
17506 for (j = 0; j < f->nb_inputs; j++) {
1468 8753 sinks[n] = ff_link_internal(f->inputs[j]);
1469 8753 sinks[n]->age_index = n;
1470 8753 n++;
1471 }
1472 }
1473 }
1474
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8514 times.
8514 av_assert0(n == sink_links_count);
1475 8514 fffiltergraph(graph)->sink_links = sinks;
1476 8514 fffiltergraph(graph)->sink_links_count = sink_links_count;
1477 8514 return 0;
1478 }
1479
1480 8516 int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
1481 {
1482 8516 FFFilterGraph *graphi = fffiltergraph(graphctx);
1483 int ret;
1484
1485 8516 size_t max_queued = SIZE_MAX;
1486 #if FF_API_MAX_BUFFERED_FRAMES
1487 FF_DISABLE_DEPRECATION_WARNINGS
1488
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8516 times.
8516 if (graphctx->max_buffered_frames)
1489 ✗ max_queued = graphctx->max_buffered_frames;
1490 FF_ENABLE_DEPRECATION_WARNINGS
1491 #endif
1492
1493
2/2
✓ Branch 0 taken 42580 times.
✓ Branch 1 taken 8516 times.
51096 for (int i = 0; i < FF_ARRAY_ELEMS(graphi->frame_queues); i++) {
1494 /* only infer the value from graphctx->max_buffered_frames if it was
1495 * not already set by avfilter_graph_set_max_buffered_frames() */
1496
2/2
✓ Branch 0 taken 42575 times.
✓ Branch 1 taken 5 times.
42580 if (!graphi->max_queued_set[i])
1497 42575 graphi->frame_queues[i].max_queued = max_queued;
1498 }
1499
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8516 times.
8516 if ((ret = graph_check_validity(graphctx, log_ctx)))
1500 ✗ return ret;
1501
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8516 times.
8516 if ((ret = graph_config_formats(graphctx, log_ctx)))
1502 ✗ return ret;
1503
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 8514 times.
8516 if ((ret = graph_config_links(graphctx, log_ctx)))
1504 2 return ret;
1505
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8514 times.
8514 if ((ret = graph_check_links(graphctx, log_ctx)))
1506 ✗ return ret;
1507
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8514 times.
8514 if ((ret = graph_config_pointers(graphctx, log_ctx)))
1508 ✗ return ret;
1509
1510 8514 return 0;
1511 }
1512
1513 ✗ int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags)
1514 {
1515 ✗ int i, r = AVERROR(ENOSYS);
1516
1517 ✗ if (!graph)
1518 ✗ return r;
1519
1520 ✗ if ((flags & AVFILTER_CMD_FLAG_ONE) && !(flags & AVFILTER_CMD_FLAG_FAST)) {
1521 ✗ r = avfilter_graph_send_command(graph, target, cmd, arg, res, res_len, flags | AVFILTER_CMD_FLAG_FAST);
1522 ✗ if (r != AVERROR(ENOSYS))
1523 ✗ return r;
1524 }
1525
1526 ✗ if (res_len && res)
1527 ✗ res[0] = 0;
1528
1529 ✗ for (i = 0; i < graph->nb_filters; i++) {
1530 ✗ AVFilterContext *filter = graph->filters[i];
1531 ✗ if (!strcmp(target, "all") || (filter->name && !strcmp(target, filter->name)) || !strcmp(target, filter->filter->name)) {
1532 ✗ r = avfilter_process_command(filter, cmd, arg, res, res_len, flags);
1533 ✗ if (r != AVERROR(ENOSYS)) {
1534 ✗ if ((flags & AVFILTER_CMD_FLAG_ONE) || r < 0)
1535 ✗ return r;
1536 }
1537 }
1538 }
1539
1540 ✗ return r;
1541 }
1542
1543 ✗ int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *command, const char *arg, int flags, double ts)
1544 {
1545 int i;
1546
1547 ✗ if(!graph)
1548 ✗ return 0;
1549
1550 ✗ for (i = 0; i < graph->nb_filters; i++) {
1551 ✗ AVFilterContext *filter = graph->filters[i];
1552 ✗ FFFilterContext *ctxi = fffilterctx(filter);
1553 ✗ if(filter && (!strcmp(target, "all") || !strcmp(target, filter->name) || !strcmp(target, filter->filter->name))){
1554 ✗ AVFilterCommand **queue = &ctxi->command_queue, *next;
1555 ✗ while (*queue && (*queue)->time <= ts)
1556 ✗ queue = &(*queue)->next;
1557 ✗ next = *queue;
1558 ✗ *queue = av_mallocz(sizeof(AVFilterCommand));
1559 ✗ if (!*queue)
1560 ✗ return AVERROR(ENOMEM);
1561
1562 ✗ (*queue)->command = av_strdup(command);
1563 ✗ (*queue)->arg = av_strdup(arg);
1564 ✗ (*queue)->time = ts;
1565 ✗ (*queue)->flags = flags;
1566 ✗ (*queue)->next = next;
1567 ✗ if(flags & AVFILTER_CMD_FLAG_ONE)
1568 ✗ return 0;
1569 }
1570 }
1571
1572 ✗ return 0;
1573 }
1574
1575 477694 static void heap_bubble_up(FFFilterGraph *graph,
1576 FilterLinkInternal *li, int index)
1577 {
1578 477694 FilterLinkInternal **links = graph->sink_links;
1579
1580
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 477694 times.
477694 av_assert0(index >= 0);
1581
1582
2/2
✓ Branch 0 taken 14026 times.
✓ Branch 1 taken 477694 times.
491720 while (index) {
1583 14026 int parent = (index - 1) >> 1;
1584
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14026 times.
14026 if (links[parent]->l.current_pts_us >= li->l.current_pts_us)
1585 ✗ break;
1586 14026 links[index] = links[parent];
1587 14026 links[index]->age_index = index;
1588 14026 index = parent;
1589 }
1590 477694 links[index] = li;
1591 477694 li->age_index = index;
1592 477694 }
1593
1594 477915 static void heap_bubble_down(FFFilterGraph *graph,
1595 FilterLinkInternal *li, int index)
1596 {
1597 477915 FilterLinkInternal **links = graph->sink_links;
1598
1599
1/2
✓ Branch 0 taken 477915 times.
✗ Branch 1 not taken.
477915 av_assert0(index >= 0);
1600
1601 24206 while (1) {
1602 502121 int child = 2 * index + 1;
1603
2/2
✓ Branch 0 taken 477552 times.
✓ Branch 1 taken 24569 times.
502121 if (child >= graph->sink_links_count)
1604 477552 break;
1605
2/2
✓ Branch 0 taken 23031 times.
✓ Branch 1 taken 1538 times.
24569 if (child + 1 < graph->sink_links_count &&
1606
2/2
✓ Branch 0 taken 8295 times.
✓ Branch 1 taken 14736 times.
23031 links[child + 1]->l.current_pts_us < links[child]->l.current_pts_us)
1607 8295 child++;
1608
2/2
✓ Branch 0 taken 363 times.
✓ Branch 1 taken 24206 times.
24569 if (li->l.current_pts_us < links[child]->l.current_pts_us)
1609 363 break;
1610 24206 links[index] = links[child];
1611 24206 links[index]->age_index = index;
1612 24206 index = child;
1613 }
1614 477915 links[index] = li;
1615 477915 li->age_index = index;
1616 477915 }
1617
1618 477694 void ff_avfilter_graph_update_heap(AVFilterGraph *graph, FilterLinkInternal *li)
1619 {
1620 477694 FFFilterGraph *graphi = fffiltergraph(graph);
1621
1622 477694 heap_bubble_up (graphi, li, li->age_index);
1623 477694 heap_bubble_down(graphi, li, li->age_index);
1624 477694 }
1625
1626 463037 int avfilter_graph_request_oldest(AVFilterGraph *graph)
1627 {
1628 463037 FFFilterGraph *graphi = fffiltergraph(graph);
1629 463037 FilterLinkInternal *oldesti = graphi->sink_links[0];
1630 463037 AVFilterLink *oldest = &oldesti->l.pub;
1631 int64_t frame_count;
1632 int r;
1633
1634
2/2
✓ Branch 0 taken 463270 times.
✓ Branch 1 taken 5272 times.
468542 while (graphi->sink_links_count) {
1635 463270 oldesti = graphi->sink_links[0];
1636 463270 oldest = &oldesti->l.pub;
1637
2/2
✓ Branch 1 taken 463252 times.
✓ Branch 2 taken 18 times.
463270 if (fffilter(oldest->dst->filter)->activate) {
1638 463252 r = av_buffersink_get_frame_flags(oldest->dst, NULL,
1639 AV_BUFFERSINK_FLAG_PEEK);
1640
2/2
✓ Branch 0 taken 457748 times.
✓ Branch 1 taken 5504 times.
463252 if (r != AVERROR_EOF)
1641 457748 return r;
1642 } else {
1643 18 r = ff_request_frame(oldest);
1644 }
1645
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 5505 times.
5522 if (r != AVERROR_EOF)
1646 17 break;
1647 5505 av_log(oldest->dst, AV_LOG_DEBUG, "EOF on sink link %s:%s.\n",
1648 5505 oldest->dst->name,
1649 5505 oldest->dstpad->name);
1650 /* EOF: remove the link from the heap */
1651
2/2
✓ Branch 0 taken 221 times.
✓ Branch 1 taken 5284 times.
5505 if (oldesti->age_index < --graphi->sink_links_count)
1652 221 heap_bubble_down(graphi, graphi->sink_links[graphi->sink_links_count],
1653 oldesti->age_index);
1654 5505 oldesti->age_index = -1;
1655 }
1656
2/2
✓ Branch 0 taken 5272 times.
✓ Branch 1 taken 17 times.
5289 if (!graphi->sink_links_count)
1657 5272 return AVERROR_EOF;
1658 av_assert1(!fffilter(oldest->dst->filter)->activate);
1659 av_assert1(oldesti->age_index >= 0);
1660 17 frame_count = oldesti->l.frame_count_out;
1661
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 while (frame_count == oldesti->l.frame_count_out) {
1662 68 r = ff_filter_graph_run_once(graph);
1663
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 51 times.
68 if (r == FFERROR_BUFFERSRC_EMPTY)
1664 17 r = 0;
1665
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 51 times.
68 if (r == AVERROR(EAGAIN) &&
1666
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17 !oldesti->frame_wanted_out && !oldesti->frame_blocked_in &&
1667 ✗ !oldesti->status_in)
1668 ✗ (void)ff_request_frame(oldest);
1669
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 51 times.
68 else if (r < 0)
1670 17 return r;
1671 }
1672 ✗ return 0;
1673 }
1674
1675 5243447 int ff_filter_graph_run_once(AVFilterGraph *graph)
1676 {
1677 FFFilterContext *ctxi;
1678 unsigned i;
1679
1680
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5243447 times.
5243447 av_assert0(graph->nb_filters);
1681 5243447 ctxi = fffilterctx(graph->filters[0]);
1682
2/2
✓ Branch 0 taken 26134924 times.
✓ Branch 1 taken 5243447 times.
31378371 for (i = 1; i < graph->nb_filters; i++) {
1683 26134924 FFFilterContext *ctxi_other = fffilterctx(graph->filters[i]);
1684
1685
2/2
✓ Branch 0 taken 3150173 times.
✓ Branch 1 taken 22984751 times.
26134924 if (ctxi_other->ready > ctxi->ready)
1686 3150173 ctxi = ctxi_other;
1687 }
1688
1689
2/2
✓ Branch 0 taken 863325 times.
✓ Branch 1 taken 4380122 times.
5243447 if (!ctxi->ready)
1690 863325 return AVERROR(EAGAIN);
1691 4380122 return ff_filter_activate(&ctxi->p);
1692 }
1693