FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/avfilter.c
Date: 2026-03-12 03:22:39
Exec Total Coverage
Lines: 673 848 79.4%
Functions: 59 66 89.4%
Branches: 362 510 71.0%

Line Branch Exec Source
1 /*
2 * filter layer
3 * Copyright (c) 2007 Bobby Bingham
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "libavutil/avassert.h"
23 #include "libavutil/avstring.h"
24 #include "libavutil/bprint.h"
25 #include "libavutil/buffer.h"
26 #include "libavutil/channel_layout.h"
27 #include "libavutil/common.h"
28 #include "libavutil/eval.h"
29 #include "libavutil/frame.h"
30 #include "libavutil/hwcontext.h"
31 #include "libavutil/internal.h"
32 #include "libavutil/mem.h"
33 #include "libavutil/opt.h"
34 #include "libavutil/pixdesc.h"
35 #include "libavutil/rational.h"
36 #include "libavutil/samplefmt.h"
37
38 #include "audio.h"
39 #include "avfilter.h"
40 #include "avfilter_internal.h"
41 #include "filters.h"
42 #include "formats.h"
43 #include "framequeue.h"
44 #include "framepool.h"
45 #include "video.h"
46
47 1546380 static void tlog_ref(void *ctx, AVFrame *ref, int end)
48 {
49 #ifdef TRACE
50 ff_tlog(ctx,
51 "ref[%p buf:%p data:%p linesize[%d, %d, %d, %d] pts:%"PRId64,
52 ref, ref->buf, ref->data[0],
53 ref->linesize[0], ref->linesize[1], ref->linesize[2], ref->linesize[3],
54 ref->pts);
55
56 if (ref->width) {
57 ff_tlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c",
58 ref->sample_aspect_ratio.num, ref->sample_aspect_ratio.den,
59 ref->width, ref->height,
60 !(ref->flags & AV_FRAME_FLAG_INTERLACED) ? 'P' : /* Progressive */
61 (ref->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 'T' : 'B', /* Top / Bottom */
62 !!(ref->flags & AV_FRAME_FLAG_KEY),
63 av_get_picture_type_char(ref->pict_type));
64 }
65 if (ref->nb_samples) {
66 AVBPrint bprint;
67
68 av_bprint_init(&bprint, 1, AV_BPRINT_SIZE_UNLIMITED);
69 av_channel_layout_describe_bprint(&ref->ch_layout, &bprint);
70 ff_tlog(ctx, " cl:%s n:%d r:%d",
71 bprint.str,
72 ref->nb_samples,
73 ref->sample_rate);
74 av_bprint_finalize(&bprint, NULL);
75 }
76
77 ff_tlog(ctx, "]%s", end ? "\n" : "");
78 #endif
79 1546380 }
80
81 static void command_queue_pop(AVFilterContext *filter)
82 {
83 FFFilterContext *ctxi = fffilterctx(filter);
84 AVFilterCommand *c = ctxi->command_queue;
85 av_freep(&c->arg);
86 av_freep(&c->command);
87 ctxi->command_queue = c->next;
88 av_free(c);
89 }
90
91 /**
92 * Append a new pad.
93 *
94 * @param count Pointer to the number of pads in the list
95 * @param pads Pointer to the pointer to the beginning of the list of pads
96 * @param links Pointer to the pointer to the beginning of the list of links
97 * @param newpad The new pad to add. A copy is made when adding.
98 * @return >= 0 in case of success, a negative AVERROR code on error
99 */
100 570 static int append_pad(unsigned *count, AVFilterPad **pads,
101 AVFilterLink ***links, AVFilterPad *newpad)
102 {
103 AVFilterLink **newlinks;
104 AVFilterPad *newpads;
105 570 unsigned idx = *count;
106
107 570 newpads = av_realloc_array(*pads, idx + 1, sizeof(*newpads));
108 570 newlinks = av_realloc_array(*links, idx + 1, sizeof(*newlinks));
109
1/2
✓ Branch 0 taken 570 times.
✗ Branch 1 not taken.
570 if (newpads)
110 570 *pads = newpads;
111
1/2
✓ Branch 0 taken 570 times.
✗ Branch 1 not taken.
570 if (newlinks)
112 570 *links = newlinks;
113
2/4
✓ Branch 0 taken 570 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 570 times.
570 if (!newpads || !newlinks) {
114 if (newpad->flags & AVFILTERPAD_FLAG_FREE_NAME)
115 av_freep(&newpad->name);
116 return AVERROR(ENOMEM);
117 }
118
119 570 memcpy(*pads + idx, newpad, sizeof(AVFilterPad));
120 570 (*links)[idx] = NULL;
121
122 570 (*count)++;
123
124 570 return 0;
125 }
126
127 283 int ff_append_inpad(AVFilterContext *f, AVFilterPad *p)
128 {
129 283 return append_pad(&f->nb_inputs, &f->input_pads, &f->inputs, p);
130 }
131
132 264 int ff_append_inpad_free_name(AVFilterContext *f, AVFilterPad *p)
133 {
134 264 p->flags |= AVFILTERPAD_FLAG_FREE_NAME;
135 264 return ff_append_inpad(f, p);
136 }
137
138 287 int ff_append_outpad(AVFilterContext *f, AVFilterPad *p)
139 {
140 287 return append_pad(&f->nb_outputs, &f->output_pads, &f->outputs, p);
141 }
142
143 146 int ff_append_outpad_free_name(AVFilterContext *f, AVFilterPad *p)
144 {
145 146 p->flags |= AVFILTERPAD_FLAG_FREE_NAME;
146 146 return ff_append_outpad(f, p);
147 }
148
149 47207 int avfilter_link(AVFilterContext *src, unsigned srcpad,
150 AVFilterContext *dst, unsigned dstpad)
151 {
152 FilterLinkInternal *li;
153 AVFilterLink *link;
154
155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47207 times.
47207 av_assert0(src->graph);
156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47207 times.
47207 av_assert0(dst->graph);
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47207 times.
47207 av_assert0(src->graph == dst->graph);
158
159
2/4
✓ Branch 0 taken 47207 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47207 times.
✗ Branch 3 not taken.
47207 if (src->nb_outputs <= srcpad || dst->nb_inputs <= dstpad ||
160
2/4
✓ Branch 0 taken 47207 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 47207 times.
47207 src->outputs[srcpad] || dst->inputs[dstpad])
161 return AVERROR(EINVAL);
162
163
1/2
✓ Branch 1 taken 47207 times.
✗ Branch 2 not taken.
47207 if (!(fffilterctx(src)->state_flags & AV_CLASS_STATE_INITIALIZED) ||
164
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 47207 times.
47207 !(fffilterctx(dst)->state_flags & AV_CLASS_STATE_INITIALIZED)) {
165 av_log(src, AV_LOG_ERROR, "Filters must be initialized before linking.\n");
166 return AVERROR(EINVAL);
167 }
168
169
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47207 times.
47207 if (src->output_pads[srcpad].type != dst->input_pads[dstpad].type) {
170 av_log(src, AV_LOG_ERROR,
171 "Media type mismatch between the '%s' filter output pad %d (%s) and the '%s' filter input pad %d (%s)\n",
172 src->name, srcpad, (char *)av_x_if_null(av_get_media_type_string(src->output_pads[srcpad].type), "?"),
173 dst->name, dstpad, (char *)av_x_if_null(av_get_media_type_string(dst-> input_pads[dstpad].type), "?"));
174 return AVERROR(EINVAL);
175 }
176
177 47207 li = av_mallocz(sizeof(*li));
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47207 times.
47207 if (!li)
179 return AVERROR(ENOMEM);
180 47207 link = &li->l.pub;
181
182 47207 src->outputs[srcpad] = dst->inputs[dstpad] = link;
183
184 47207 link->src = src;
185 47207 link->dst = dst;
186 47207 link->srcpad = &src->output_pads[srcpad];
187 47207 link->dstpad = &dst->input_pads[dstpad];
188 47207 link->type = src->output_pads[srcpad].type;
189 47207 li->l.graph = src->graph;
190 av_assert0(AV_PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1);
191 47207 link->format = -1;
192 47207 link->colorspace = AVCOL_SPC_UNSPECIFIED;
193 47207 ff_framequeue_init(&li->fifo, &fffiltergraph(src->graph)->frame_queues);
194
195 47207 return 0;
196 }
197
198 47339 static void link_free(AVFilterLink **link)
199 {
200 FilterLinkInternal *li;
201
202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47339 times.
47339 if (!*link)
203 return;
204 47339 li = ff_link_internal(*link);
205
206 47339 ff_framequeue_free(&li->fifo);
207 47339 ff_frame_pool_uninit(&li->frame_pool);
208 47339 av_channel_layout_uninit(&(*link)->ch_layout);
209 47339 av_frame_side_data_free(&(*link)->side_data, &(*link)->nb_side_data);
210
211 47339 av_buffer_unref(&li->l.hw_frames_ctx);
212
213 47339 av_freep(link);
214 }
215
216 1557775 static void update_link_current_pts(FilterLinkInternal *li, int64_t pts)
217 {
218 1557775 AVFilterLink *const link = &li->l.pub;
219
220
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1557770 times.
1557775 if (pts == AV_NOPTS_VALUE)
221 5 return;
222 1557770 li->l.current_pts = pts;
223 1557770 li->l.current_pts_us = av_rescale_q(pts, link->time_base, AV_TIME_BASE_Q);
224 /* TODO use duration */
225
3/4
✓ Branch 0 taken 1557770 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 422197 times.
✓ Branch 3 taken 1135573 times.
1557770 if (li->l.graph && li->age_index >= 0)
226 422197 ff_avfilter_graph_update_heap(li->l.graph, li);
227 }
228
229 3859698 void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
230 {
231 3859698 FFFilterContext *ctxi = fffilterctx(filter);
232 3859698 ctxi->ready = FFMAX(ctxi->ready, priority);
233 3859698 }
234
235 /**
236 * Clear frame_blocked_in on all outputs.
237 * This is necessary whenever something changes on input.
238 */
239 2302397 static void filter_unblock(AVFilterContext *filter)
240 {
241 unsigned i;
242
243
2/2
✓ Branch 0 taken 1880312 times.
✓ Branch 1 taken 2302397 times.
4182709 for (i = 0; i < filter->nb_outputs; i++) {
244 1880312 FilterLinkInternal * const li = ff_link_internal(filter->outputs[i]);
245 1880312 li->frame_blocked_in = 0;
246 }
247 2302397 }
248
249
250 19511 void ff_avfilter_link_set_in_status(AVFilterLink *link, int status, int64_t pts)
251 {
252 19511 FilterLinkInternal * const li = ff_link_internal(link);
253
254
2/2
✓ Branch 0 taken 5578 times.
✓ Branch 1 taken 13933 times.
19511 if (li->status_in == status)
255 5578 return;
256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13933 times.
13933 av_assert0(!li->status_in);
257 13933 li->status_in = status;
258 13933 li->status_in_pts = pts;
259 13933 li->frame_wanted_out = 0;
260 13933 li->frame_blocked_in = 0;
261 13933 filter_unblock(link->dst);
262 13933 ff_filter_set_ready(link->dst, 200);
263 }
264
265 /**
266 * Set the status field of a link from the destination filter.
267 * The pts should probably be left unset (AV_NOPTS_VALUE).
268 */
269 8475 static void link_set_out_status(AVFilterLink *link, int status, int64_t pts)
270 {
271 8475 FilterLinkInternal * const li = ff_link_internal(link);
272
273
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8475 times.
8475 av_assert0(!li->frame_wanted_out);
274
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8475 times.
8475 av_assert0(!li->status_out);
275 8475 li->status_out = status;
276
2/2
✓ Branch 0 taken 5998 times.
✓ Branch 1 taken 2477 times.
8475 if (pts != AV_NOPTS_VALUE)
277 5998 update_link_current_pts(li, pts);
278 8475 filter_unblock(link->dst);
279 8475 ff_filter_set_ready(link->src, 200);
280 8475 }
281
282 1265 int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
283 unsigned filt_srcpad_idx, unsigned filt_dstpad_idx)
284 {
285 int ret;
286 1265 unsigned dstpad_idx = link->dstpad - link->dst->input_pads;
287
288 1265 av_log(link->dst, AV_LOG_VERBOSE, "auto-inserting filter '%s' "
289 "between the filter '%s' and the filter '%s'\n",
290 1265 filt->name, link->src->name, link->dst->name);
291
292 1265 link->dst->inputs[dstpad_idx] = NULL;
293
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1265 times.
1265 if ((ret = avfilter_link(filt, filt_dstpad_idx, link->dst, dstpad_idx)) < 0) {
294 /* failed to link output filter to new filter */
295 link->dst->inputs[dstpad_idx] = link;
296 return ret;
297 }
298
299 /* re-hookup the link to the new destination filter we inserted */
300 1265 link->dst = filt;
301 1265 link->dstpad = &filt->input_pads[filt_srcpad_idx];
302 1265 filt->inputs[filt_srcpad_idx] = link;
303
304 /* if any information on supported media formats already exists on the
305 * link, we need to preserve that */
306
1/2
✓ Branch 0 taken 1265 times.
✗ Branch 1 not taken.
1265 if (link->outcfg.formats)
307 1265 ff_formats_changeref(&link->outcfg.formats,
308 1265 &filt->outputs[filt_dstpad_idx]->outcfg.formats);
309
2/2
✓ Branch 0 taken 626 times.
✓ Branch 1 taken 639 times.
1265 if (link->outcfg.color_spaces)
310 626 ff_formats_changeref(&link->outcfg.color_spaces,
311 626 &filt->outputs[filt_dstpad_idx]->outcfg.color_spaces);
312
2/2
✓ Branch 0 taken 626 times.
✓ Branch 1 taken 639 times.
1265 if (link->outcfg.color_ranges)
313 626 ff_formats_changeref(&link->outcfg.color_ranges,
314 626 &filt->outputs[filt_dstpad_idx]->outcfg.color_ranges);
315
2/2
✓ Branch 0 taken 626 times.
✓ Branch 1 taken 639 times.
1265 if (link->outcfg.alpha_modes)
316 626 ff_formats_changeref(&link->outcfg.alpha_modes,
317 626 &filt->outputs[filt_dstpad_idx]->outcfg.alpha_modes);
318
2/2
✓ Branch 0 taken 639 times.
✓ Branch 1 taken 626 times.
1265 if (link->outcfg.samplerates)
319 639 ff_formats_changeref(&link->outcfg.samplerates,
320 639 &filt->outputs[filt_dstpad_idx]->outcfg.samplerates);
321
2/2
✓ Branch 0 taken 639 times.
✓ Branch 1 taken 626 times.
1265 if (link->outcfg.channel_layouts)
322 639 ff_channel_layouts_changeref(&link->outcfg.channel_layouts,
323 639 &filt->outputs[filt_dstpad_idx]->outcfg.channel_layouts);
324
325 1265 return 0;
326 }
327
328 45167 int ff_filter_config_links(AVFilterContext *filter)
329 {
330 int (*config_link)(AVFilterLink *);
331 unsigned i;
332 int ret;
333
334
2/2
✓ Branch 0 taken 36980 times.
✓ Branch 1 taken 45165 times.
82145 for (i = 0; i < filter->nb_inputs; i ++) {
335 36980 AVFilterLink *link = filter->inputs[i];
336 AVFilterLink *inlink;
337 36980 FilterLinkInternal *li = ff_link_internal(link);
338 FilterLinkInternal *li_in;
339
340
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36980 times.
36980 if (!link) continue;
341
2/4
✓ Branch 0 taken 36980 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36980 times.
36980 if (!link->src || !link->dst) {
342 av_log(filter, AV_LOG_ERROR,
343 "Not all input and output are properly linked (%d).\n", i);
344 return AVERROR(EINVAL);
345 }
346
347
2/2
✓ Branch 0 taken 28593 times.
✓ Branch 1 taken 8387 times.
36980 inlink = link->src->nb_inputs ? link->src->inputs[0] : NULL;
348
2/2
✓ Branch 0 taken 28593 times.
✓ Branch 1 taken 8387 times.
36980 li_in = inlink ? ff_link_internal(inlink) : NULL;
349 36980 li->l.current_pts =
350 36980 li->l.current_pts_us = AV_NOPTS_VALUE;
351
352
3/4
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 36867 times.
✗ Branch 3 not taken.
36980 switch (li->init_state) {
353 111 case AVLINK_INIT:
354 111 continue;
355 2 case AVLINK_STARTINIT:
356 2 av_log(filter, AV_LOG_INFO, "circular filter chain detected\n");
357 2 return 0;
358 36867 case AVLINK_UNINIT:
359 36867 li->init_state = AVLINK_STARTINIT;
360
361
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 36867 times.
36867 if ((ret = ff_filter_config_links(link->src)) < 0)
362 return ret;
363
364
2/2
✓ Branch 0 taken 19307 times.
✓ Branch 1 taken 17560 times.
36867 if (!(config_link = link->srcpad->config_props)) {
365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19307 times.
19307 if (link->src->nb_inputs != 1) {
366 av_log(link->src, AV_LOG_ERROR, "Source filters and filters "
367 "with more than one input "
368 "must set config_props() "
369 "callbacks on all outputs\n");
370 return AVERROR(EINVAL);
371 }
372 }
373
374 /* Copy side data before link->srcpad->config_props() is called, so the filter
375 * may remove it for the next filter in the chain */
376
5/6
✓ Branch 0 taken 28514 times.
✓ Branch 1 taken 8353 times.
✓ Branch 2 taken 261 times.
✓ Branch 3 taken 28253 times.
✓ Branch 4 taken 261 times.
✗ Branch 5 not taken.
36867 if (inlink && inlink->nb_side_data && !link->nb_side_data) {
377
2/2
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 261 times.
531 for (int j = 0; j < inlink->nb_side_data; j++) {
378 270 ret = av_frame_side_data_clone(&link->side_data, &link->nb_side_data,
379 270 inlink->side_data[j], 0);
380
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 270 times.
270 if (ret < 0) {
381 av_frame_side_data_free(&link->side_data, &link->nb_side_data);
382 return ret;
383 }
384 }
385 }
386
387
3/4
✓ Branch 0 taken 17560 times.
✓ Branch 1 taken 19307 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17560 times.
36867 if (config_link && (ret = config_link(link)) < 0) {
388 av_log(link->src, AV_LOG_ERROR,
389 "Failed to configure output pad on %s\n",
390 link->src->name);
391 return ret;
392 }
393
394
2/3
✓ Branch 0 taken 30900 times.
✓ Branch 1 taken 5967 times.
✗ Branch 2 not taken.
36867 switch (link->type) {
395 30900 case AVMEDIA_TYPE_VIDEO:
396
3/4
✓ Branch 0 taken 23670 times.
✓ Branch 1 taken 7230 times.
✓ Branch 2 taken 23670 times.
✗ Branch 3 not taken.
30900 if (!link->time_base.num && !link->time_base.den)
397
1/2
✓ Branch 0 taken 23670 times.
✗ Branch 1 not taken.
23670 link->time_base = inlink ? inlink->time_base : AV_TIME_BASE_Q;
398
399
4/4
✓ Branch 0 taken 26453 times.
✓ Branch 1 taken 4447 times.
✓ Branch 2 taken 16823 times.
✓ Branch 3 taken 9630 times.
30900 if (!link->sample_aspect_ratio.num && !link->sample_aspect_ratio.den)
400 16823 link->sample_aspect_ratio = inlink ?
401
2/2
✓ Branch 0 taken 16808 times.
✓ Branch 1 taken 15 times.
16823 inlink->sample_aspect_ratio : (AVRational){1,1};
402
403
2/2
✓ Branch 0 taken 23928 times.
✓ Branch 1 taken 6972 times.
30900 if (inlink) {
404
3/4
✓ Branch 0 taken 23713 times.
✓ Branch 1 taken 215 times.
✓ Branch 2 taken 23713 times.
✗ Branch 3 not taken.
23928 if (!li->l.frame_rate.num && !li->l.frame_rate.den)
405 23713 li->l.frame_rate = li_in->l.frame_rate;
406
2/2
✓ Branch 0 taken 16320 times.
✓ Branch 1 taken 7608 times.
23928 if (!link->w)
407 16320 link->w = inlink->w;
408
2/2
✓ Branch 0 taken 16320 times.
✓ Branch 1 taken 7608 times.
23928 if (!link->h)
409 16320 link->h = inlink->h;
410
2/4
✓ Branch 0 taken 6972 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6972 times.
6972 } else if (!link->w || !link->h) {
411 av_log(link->src, AV_LOG_ERROR,
412 "Video source filters must set their output link's "
413 "width and height\n");
414 return AVERROR(EINVAL);
415 }
416 30900 break;
417
418 5967 case AVMEDIA_TYPE_AUDIO:
419
2/2
✓ Branch 0 taken 4586 times.
✓ Branch 1 taken 1381 times.
5967 if (inlink) {
420
3/4
✓ Branch 0 taken 3074 times.
✓ Branch 1 taken 1512 times.
✓ Branch 2 taken 3074 times.
✗ Branch 3 not taken.
4586 if (!link->time_base.num && !link->time_base.den)
421 3074 link->time_base = inlink->time_base;
422 }
423
424
3/4
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 5884 times.
✓ Branch 2 taken 83 times.
✗ Branch 3 not taken.
5967 if (!link->time_base.num && !link->time_base.den)
425 83 link->time_base = (AVRational) {1, link->sample_rate};
426 }
427
428
2/2
✓ Branch 0 taken 28514 times.
✓ Branch 1 taken 8353 times.
36867 if (link->src->nb_inputs &&
429
1/2
✓ Branch 1 taken 28514 times.
✗ Branch 2 not taken.
28514 !(fffilter(link->src->filter)->flags_internal & FF_FILTER_FLAG_HWFRAME_AWARE)) {
430 28514 FilterLink *l0 = ff_filter_link(link->src->inputs[0]);
431
432
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28514 times.
28514 av_assert0(!li->l.hw_frames_ctx &&
433 "should not be set by non-hwframe-aware filter");
434
435
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28514 times.
28514 if (l0->hw_frames_ctx) {
436 li->l.hw_frames_ctx = av_buffer_ref(l0->hw_frames_ctx);
437 if (!li->l.hw_frames_ctx)
438 return AVERROR(ENOMEM);
439 }
440 }
441
442
2/2
✓ Branch 0 taken 4903 times.
✓ Branch 1 taken 31964 times.
36867 if ((config_link = link->dstpad->config_props))
443
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4903 times.
4903 if ((ret = config_link(link)) < 0) {
444 av_log(link->dst, AV_LOG_ERROR,
445 "Failed to configure input pad on %s\n",
446 link->dst->name);
447 return ret;
448 }
449
450 36867 li->init_state = AVLINK_INIT;
451 }
452 }
453
454 45165 return 0;
455 }
456
457 #ifdef TRACE
458 void ff_tlog_link(void *ctx, AVFilterLink *link, int end)
459 {
460 if (link->type == AVMEDIA_TYPE_VIDEO) {
461 ff_tlog(ctx,
462 "link[%p s:%dx%d fmt:%s %s->%s]%s",
463 link, link->w, link->h,
464 av_get_pix_fmt_name(link->format),
465 link->src ? link->src->filter->name : "",
466 link->dst ? link->dst->filter->name : "",
467 end ? "\n" : "");
468 } else {
469 char buf[128];
470 av_channel_layout_describe(&link->ch_layout, buf, sizeof(buf));
471
472 ff_tlog(ctx,
473 "link[%p r:%d cl:%s fmt:%s %s->%s]%s",
474 link, (int)link->sample_rate, buf,
475 av_get_sample_fmt_name(link->format),
476 link->src ? link->src->filter->name : "",
477 link->dst ? link->dst->filter->name : "",
478 end ? "\n" : "");
479 }
480 }
481 #endif
482
483 734139 int ff_request_frame(AVFilterLink *link)
484 {
485 734139 FilterLinkInternal * const li = ff_link_internal(link);
486
487 FF_TPRINTF_START(NULL, request_frame); ff_tlog_link(NULL, link, 1);
488
489 av_assert1(!fffilter(link->dst->filter)->activate);
490
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 734130 times.
734139 if (li->status_out)
491 9 return li->status_out;
492
2/2
✓ Branch 0 taken 5999 times.
✓ Branch 1 taken 728131 times.
734130 if (li->status_in) {
493
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5999 times.
5999 if (ff_framequeue_queued_frames(&li->fifo)) {
494 av_assert1(!li->frame_wanted_out);
495 av_assert1(fffilterctx(link->dst)->ready >= 300);
496 return 0;
497 } else {
498 /* Acknowledge status change. Filters using ff_request_frame() will
499 handle the change automatically. Filters can also check the
500 status directly but none do yet. */
501 5999 link_set_out_status(link, li->status_in, li->status_in_pts);
502 5999 return li->status_out;
503 }
504 }
505 728131 li->frame_wanted_out = 1;
506 728131 ff_filter_set_ready(link->src, 100);
507 728131 return 0;
508 }
509
510 5993 static int64_t guess_status_pts(AVFilterContext *ctx, int status, AVRational link_time_base)
511 {
512 unsigned i;
513 5993 int64_t r = INT64_MAX;
514
515
2/2
✓ Branch 0 taken 5992 times.
✓ Branch 1 taken 5993 times.
11985 for (i = 0; i < ctx->nb_inputs; i++) {
516 5992 FilterLinkInternal * const li = ff_link_internal(ctx->inputs[i]);
517
1/2
✓ Branch 0 taken 5992 times.
✗ Branch 1 not taken.
5992 if (li->status_out == status)
518 5992 r = FFMIN(r, av_rescale_q(li->l.current_pts, ctx->inputs[i]->time_base, link_time_base));
519 }
520
2/2
✓ Branch 0 taken 5992 times.
✓ Branch 1 taken 1 times.
5993 if (r < INT64_MAX)
521 5992 return r;
522 1 av_log(ctx, AV_LOG_WARNING, "EOF timestamp not reliable\n");
523
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 for (i = 0; i < ctx->nb_inputs; i++) {
524 FilterLinkInternal * const li = ff_link_internal(ctx->inputs[i]);
525 r = FFMIN(r, av_rescale_q(li->status_in_pts, ctx->inputs[i]->time_base, link_time_base));
526 }
527
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (r < INT64_MAX)
528 return r;
529 1 return AV_NOPTS_VALUE;
530 }
531
532 734451 static int request_frame_to_filter(AVFilterLink *link)
533 {
534 734451 FilterLinkInternal * const li = ff_link_internal(link);
535 734451 int ret = -1;
536
537 FF_TPRINTF_START(NULL, request_frame_to_filter); ff_tlog_link(NULL, link, 1);
538 /* Assume the filter is blocked, let the method clear it if not */
539 734451 li->frame_blocked_in = 1;
540
2/2
✓ Branch 0 taken 2049 times.
✓ Branch 1 taken 732402 times.
734451 if (link->srcpad->request_frame)
541 2049 ret = link->srcpad->request_frame(link);
542
1/2
✓ Branch 0 taken 732402 times.
✗ Branch 1 not taken.
732402 else if (link->src->inputs[0])
543 732402 ret = ff_request_frame(link->src->inputs[0]);
544
2/2
✓ Branch 0 taken 5993 times.
✓ Branch 1 taken 728458 times.
734451 if (ret < 0) {
545
2/4
✓ Branch 0 taken 5993 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5993 times.
✗ Branch 3 not taken.
5993 if (ret != AVERROR(EAGAIN) && ret != li->status_in)
546 5993 ff_avfilter_link_set_in_status(link, ret, guess_status_pts(link->src, ret, link->time_base));
547
1/2
✓ Branch 0 taken 5993 times.
✗ Branch 1 not taken.
5993 if (ret == AVERROR_EOF)
548 5993 ret = 0;
549 }
550 734451 return ret;
551 }
552
553 static const char *const var_names[] = {
554 "t",
555 "n",
556 "w",
557 "h",
558 NULL
559 };
560
561 enum {
562 VAR_T,
563 VAR_N,
564 VAR_W,
565 VAR_H,
566 VAR_VARS_NB
567 };
568
569 6 static int set_enable_expr(FFFilterContext *ctxi, const char *expr)
570 {
571 6 AVFilterContext *ctx = &ctxi->p;
572 int ret;
573 char *expr_dup;
574 6 AVExpr *old = ctxi->enable;
575
576
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!(ctx->filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE)) {
577 av_log(ctx, AV_LOG_ERROR, "Timeline ('enable' option) not supported "
578 "with filter '%s'\n", ctx->filter->name);
579 return AVERROR_PATCHWELCOME;
580 }
581
582 6 expr_dup = av_strdup(expr);
583
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!expr_dup)
584 return AVERROR(ENOMEM);
585
586
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (!ctxi->var_values) {
587 6 ctxi->var_values = av_calloc(VAR_VARS_NB, sizeof(*ctxi->var_values));
588
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!ctxi->var_values) {
589 av_free(expr_dup);
590 return AVERROR(ENOMEM);
591 }
592 }
593
594 6 ret = av_expr_parse(&ctxi->enable, expr_dup, var_names,
595 NULL, NULL, NULL, NULL, 0, ctx->priv);
596
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ret < 0) {
597 av_log(ctx->priv, AV_LOG_ERROR,
598 "Error when evaluating the expression '%s' for enable\n",
599 expr_dup);
600 av_free(expr_dup);
601 return ret;
602 }
603
604 6 av_expr_free(old);
605 6 av_free(ctx->enable_str);
606 6 ctx->enable_str = expr_dup;
607 6 return 0;
608 }
609
610 int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags)
611 {
612 if(!strcmp(cmd, "ping")){
613 char local_res[256] = {0};
614
615 if (!res) {
616 res = local_res;
617 res_len = sizeof(local_res);
618 }
619 av_strlcatf(res, res_len, "pong from:%s %s\n", filter->filter->name, filter->name);
620 if (res == local_res)
621 av_log(filter, AV_LOG_INFO, "%s", res);
622 return 0;
623 }else if(!strcmp(cmd, "enable")) {
624 return set_enable_expr(fffilterctx(filter), arg);
625 }else if (fffilter(filter->filter)->process_command) {
626 return fffilter(filter->filter)->process_command(filter, cmd, arg, res, res_len, flags);
627 }
628 return AVERROR(ENOSYS);
629 }
630
631 14920 unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output)
632 {
633
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14920 times.
14920 return is_output ? fffilter(filter)->nb_outputs : fffilter(filter)->nb_inputs;
634 }
635
636 540 static const char *default_filter_name(void *filter_ctx)
637 {
638 540 AVFilterContext *ctx = filter_ctx;
639
1/2
✓ Branch 0 taken 540 times.
✗ Branch 1 not taken.
540 return ctx->name ? ctx->name : ctx->filter->name;
640 }
641
642 56812 static void *filter_child_next(void *obj, void *prev)
643 {
644 56812 AVFilterContext *ctx = obj;
645
5/8
✓ Branch 0 taken 56806 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 56806 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 56806 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 56806 times.
✗ Branch 7 not taken.
56812 if (!prev && ctx->filter && ctx->filter->priv_class && ctx->priv)
646 56806 return ctx->priv;
647 6 return NULL;
648 }
649
650 static const AVClass *filter_child_class_iterate(void **iter)
651 {
652 const AVFilter *f;
653
654 while ((f = av_filter_iterate(iter)))
655 if (f->priv_class)
656 return f->priv_class;
657
658 return NULL;
659 }
660
661 #define OFFSET(x) offsetof(AVFilterContext, x)
662 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM
663 #define TFLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
664 static const AVOption avfilter_options[] = {
665 { "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,
666 { .i64 = AVFILTER_THREAD_SLICE }, 0, INT_MAX, FLAGS, .unit = "thread_type" },
667 { "slice", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVFILTER_THREAD_SLICE }, .flags = FLAGS, .unit = "thread_type" },
668 { "enable", "set enable expression", OFFSET(enable_str), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = TFLAGS },
669 { "threads", "Allowed number of threads", OFFSET(nb_threads), AV_OPT_TYPE_INT,
670 { .i64 = 0 }, 0, INT_MAX, FLAGS, .unit = "threads" },
671 {"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, .flags = FLAGS, .unit = "threads"},
672 { "extra_hw_frames", "Number of extra hardware frames to allocate for the user",
673 OFFSET(extra_hw_frames), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS },
674 { NULL },
675 };
676
677 static const AVClass avfilter_class = {
678 .class_name = "AVFilter",
679 .item_name = default_filter_name,
680 .version = LIBAVUTIL_VERSION_INT,
681 .category = AV_CLASS_CATEGORY_FILTER,
682 .child_next = filter_child_next,
683 .child_class_iterate = filter_child_class_iterate,
684 .option = avfilter_options,
685 .state_flags_offset = offsetof(FFFilterContext, state_flags),
686 };
687
688 1277 static int default_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg,
689 int *ret, int nb_jobs)
690 {
691 int i;
692
693
2/2
✓ Branch 0 taken 1277 times.
✓ Branch 1 taken 1277 times.
2554 for (i = 0; i < nb_jobs; i++) {
694 1277 int r = func(ctx, arg, i, nb_jobs);
695
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1277 times.
1277 if (ret)
696 ret[i] = r;
697 }
698 1277 return 0;
699 }
700
701 63574 AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name)
702 {
703 FFFilterContext *ctx;
704 AVFilterContext *ret;
705 63574 const FFFilter *const fi = fffilter(filter);
706 63574 int preinited = 0;
707
708
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63574 times.
63574 if (!filter)
709 return NULL;
710
711 63574 ctx = av_mallocz(sizeof(*ctx));
712
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63574 times.
63574 if (!ctx)
713 return NULL;
714 63574 ret = &ctx->p;
715
716 63574 ret->av_class = &avfilter_class;
717 63574 ret->filter = filter;
718
1/2
✓ Branch 0 taken 63574 times.
✗ Branch 1 not taken.
63574 ret->name = inst_name ? av_strdup(inst_name) : NULL;
719
2/2
✓ Branch 0 taken 56805 times.
✓ Branch 1 taken 6769 times.
63574 if (fi->priv_size) {
720 56805 ret->priv = av_mallocz(fi->priv_size);
721
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56805 times.
56805 if (!ret->priv)
722 goto err;
723 }
724
2/2
✓ Branch 0 taken 13655 times.
✓ Branch 1 taken 49919 times.
63574 if (fi->preinit) {
725
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13655 times.
13655 if (fi->preinit(ret) < 0)
726 goto err;
727 13655 preinited = 1;
728 }
729
730 63574 av_opt_set_defaults(ret);
731
2/2
✓ Branch 0 taken 55546 times.
✓ Branch 1 taken 8028 times.
63574 if (filter->priv_class) {
732 55546 *(const AVClass**)ret->priv = filter->priv_class;
733 55546 av_opt_set_defaults(ret->priv);
734 }
735
736 63574 ctx->execute = default_execute;
737
738 63574 ret->nb_inputs = fi->nb_inputs;
739
2/2
✓ Branch 0 taken 53884 times.
✓ Branch 1 taken 9690 times.
63574 if (ret->nb_inputs ) {
740 53884 ret->input_pads = av_memdup(filter->inputs, ret->nb_inputs * sizeof(*filter->inputs));
741
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53884 times.
53884 if (!ret->input_pads)
742 goto err;
743 53884 ret->inputs = av_calloc(ret->nb_inputs, sizeof(*ret->inputs));
744
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53884 times.
53884 if (!ret->inputs)
745 goto err;
746 }
747
748 63574 ret->nb_outputs = fi->nb_outputs;
749
2/2
✓ Branch 0 taken 55183 times.
✓ Branch 1 taken 8391 times.
63574 if (ret->nb_outputs) {
750 55183 ret->output_pads = av_memdup(filter->outputs, ret->nb_outputs * sizeof(*filter->outputs));
751
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55183 times.
55183 if (!ret->output_pads)
752 goto err;
753 55183 ret->outputs = av_calloc(ret->nb_outputs, sizeof(*ret->outputs));
754
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55183 times.
55183 if (!ret->outputs)
755 goto err;
756 }
757
758 63574 return ret;
759
760 err:
761 if (preinited)
762 fi->uninit(ret);
763 av_freep(&ret->inputs);
764 av_freep(&ret->input_pads);
765 ret->nb_inputs = 0;
766 av_freep(&ret->outputs);
767 av_freep(&ret->output_pads);
768 ret->nb_outputs = 0;
769 av_freep(&ret->priv);
770 av_free(ret);
771 return NULL;
772 }
773
774 109737 static void free_link(AVFilterLink *link)
775 {
776
2/2
✓ Branch 0 taken 62398 times.
✓ Branch 1 taken 47339 times.
109737 if (!link)
777 62398 return;
778
779
2/2
✓ Branch 0 taken 47207 times.
✓ Branch 1 taken 132 times.
47339 if (link->src)
780 47207 link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
781
2/2
✓ Branch 0 taken 47207 times.
✓ Branch 1 taken 132 times.
47339 if (link->dst)
782 47207 link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
783
784 47339 ff_formats_unref(&link->incfg.formats);
785 47339 ff_formats_unref(&link->outcfg.formats);
786 47339 ff_formats_unref(&link->incfg.color_spaces);
787 47339 ff_formats_unref(&link->outcfg.color_spaces);
788 47339 ff_formats_unref(&link->incfg.color_ranges);
789 47339 ff_formats_unref(&link->outcfg.color_ranges);
790 47339 ff_formats_unref(&link->incfg.alpha_modes);
791 47339 ff_formats_unref(&link->outcfg.alpha_modes);
792 47339 ff_formats_unref(&link->incfg.samplerates);
793 47339 ff_formats_unref(&link->outcfg.samplerates);
794 47339 ff_channel_layouts_unref(&link->incfg.channel_layouts);
795 47339 ff_channel_layouts_unref(&link->outcfg.channel_layouts);
796 47339 link_free(&link);
797 }
798
799 63574 void avfilter_free(AVFilterContext *filter)
800 {
801 FFFilterContext *ctxi;
802 int i;
803
804
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63574 times.
63574 if (!filter)
805 return;
806 63574 ctxi = fffilterctx(filter);
807
808
1/2
✓ Branch 0 taken 63574 times.
✗ Branch 1 not taken.
63574 if (filter->graph)
809 63574 ff_filter_graph_remove_filter(filter->graph, filter);
810
811
2/2
✓ Branch 1 taken 49503 times.
✓ Branch 2 taken 14071 times.
63574 if (fffilter(filter->filter)->uninit)
812 49503 fffilter(filter->filter)->uninit(filter);
813
814
2/2
✓ Branch 0 taken 54263 times.
✓ Branch 1 taken 63574 times.
117837 for (i = 0; i < filter->nb_inputs; i++) {
815 54263 free_link(filter->inputs[i]);
816
2/2
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 53999 times.
54263 if (filter->input_pads[i].flags & AVFILTERPAD_FLAG_FREE_NAME)
817 264 av_freep(&filter->input_pads[i].name);
818 }
819
2/2
✓ Branch 0 taken 55474 times.
✓ Branch 1 taken 63574 times.
119048 for (i = 0; i < filter->nb_outputs; i++) {
820 55474 free_link(filter->outputs[i]);
821
2/2
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 55192 times.
55474 if (filter->output_pads[i].flags & AVFILTERPAD_FLAG_FREE_NAME)
822 282 av_freep(&filter->output_pads[i].name);
823 }
824
825
2/2
✓ Branch 0 taken 55546 times.
✓ Branch 1 taken 8028 times.
63574 if (filter->filter->priv_class)
826 55546 av_opt_free(filter->priv);
827
828 63574 av_buffer_unref(&filter->hw_device_ctx);
829
830 63574 av_freep(&filter->name);
831 63574 av_freep(&filter->input_pads);
832 63574 av_freep(&filter->output_pads);
833 63574 av_freep(&filter->inputs);
834 63574 av_freep(&filter->outputs);
835 63574 av_freep(&filter->priv);
836
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63574 times.
63574 while (ctxi->command_queue)
837 command_queue_pop(filter);
838 63574 av_opt_free(filter);
839 63574 av_expr_free(ctxi->enable);
840 63574 ctxi->enable = NULL;
841 63574 av_freep(&ctxi->var_values);
842 63574 av_free(filter);
843 }
844
845 19269 int ff_filter_get_nb_threads(AVFilterContext *ctx)
846 {
847
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19269 times.
19269 if (ctx->nb_threads > 0)
848 return FFMIN(ctx->nb_threads, ctx->graph->nb_threads);
849 19269 return ctx->graph->nb_threads;
850 }
851
852 34075 int ff_filter_opt_parse(void *logctx, const AVClass *priv_class,
853 AVDictionary **options, const char *args)
854 {
855 34075 const AVOption *o = NULL;
856 int ret;
857 34075 int offset= -1;
858
859
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34075 times.
34075 if (!args)
860 return 0;
861
862
2/2
✓ Branch 0 taken 58606 times.
✓ Branch 1 taken 34075 times.
92681 while (*args) {
863 char *parsed_key, *value;
864 const char *key;
865 58606 const char *shorthand = NULL;
866 58606 int additional_flags = 0;
867
868
4/4
✓ Branch 0 taken 45620 times.
✓ Branch 1 taken 12986 times.
✓ Branch 3 taken 44338 times.
✓ Branch 4 taken 1282 times.
58606 if (priv_class && (o = av_opt_next(&priv_class, o))) {
869
4/4
✓ Branch 0 taken 42568 times.
✓ Branch 1 taken 1770 times.
✓ Branch 2 taken 4558 times.
✓ Branch 3 taken 38010 times.
44338 if (o->type == AV_OPT_TYPE_CONST || o->offset == offset)
870 6328 continue;
871 38010 offset = o->offset;
872 38010 shorthand = o->name;
873 }
874
875 52278 ret = av_opt_get_key_value(&args, "=", ":",
876 shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0,
877 &parsed_key, &value);
878
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52278 times.
52278 if (ret < 0) {
879 if (ret == AVERROR(EINVAL))
880 av_log(logctx, AV_LOG_ERROR, "No option name near '%s'\n", args);
881 else
882 av_log(logctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", args,
883 av_err2str(ret));
884 return ret;
885 }
886
2/2
✓ Branch 0 taken 27116 times.
✓ Branch 1 taken 25162 times.
52278 if (*args)
887 27116 args++;
888
2/2
✓ Branch 0 taken 31298 times.
✓ Branch 1 taken 20980 times.
52278 if (parsed_key) {
889 31298 key = parsed_key;
890 31298 additional_flags = AV_DICT_DONT_STRDUP_KEY;
891 31298 priv_class = NULL; /* reject all remaining shorthand */
892 } else {
893 20980 key = shorthand;
894 }
895
896 52278 av_log(logctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
897
898 52278 av_dict_set(options, key, value,
899 additional_flags | AV_DICT_DONT_STRDUP_VAL | AV_DICT_MULTIKEY);
900 }
901
902 34075 return 0;
903 }
904
905 int ff_filter_process_command(AVFilterContext *ctx, const char *cmd,
906 const char *arg, char *res, int res_len, int flags)
907 {
908 const AVOption *o;
909
910 if (!ctx->filter->priv_class)
911 return 0;
912 o = av_opt_find2(ctx->priv, cmd, NULL, AV_OPT_FLAG_RUNTIME_PARAM | AV_OPT_FLAG_FILTERING_PARAM, AV_OPT_SEARCH_CHILDREN, NULL);
913 if (!o)
914 return AVERROR(ENOSYS);
915 return av_opt_set(ctx->priv, cmd, arg, 0);
916 }
917
918 63574 int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options)
919 {
920 63574 FFFilterContext *ctxi = fffilterctx(ctx);
921 63574 int ret = 0;
922
923
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63574 times.
63574 if (ctxi->state_flags & AV_CLASS_STATE_INITIALIZED) {
924 av_log(ctx, AV_LOG_ERROR, "Filter already initialized\n");
925 return AVERROR(EINVAL);
926 }
927
928 63574 ret = av_opt_set_dict2(ctx, options, AV_OPT_SEARCH_CHILDREN);
929
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63574 times.
63574 if (ret < 0) {
930 av_log(ctx, AV_LOG_ERROR, "Error applying generic filter options.\n");
931 return ret;
932 }
933
934
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 62330 times.
63574 if (ctx->filter->flags & AVFILTER_FLAG_SLICE_THREADS &&
935
2/2
✓ Branch 0 taken 153 times.
✓ Branch 1 taken 1091 times.
1244 ctx->thread_type & ctx->graph->thread_type & AVFILTER_THREAD_SLICE &&
936
1/2
✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
153 fffiltergraph(ctx->graph)->thread_execute) {
937 153 ctx->thread_type = AVFILTER_THREAD_SLICE;
938 153 ctxi->execute = fffiltergraph(ctx->graph)->thread_execute;
939 } else {
940 63421 ctx->thread_type = 0;
941 }
942
943
2/2
✓ Branch 1 taken 50284 times.
✓ Branch 2 taken 13290 times.
63574 if (fffilter(ctx->filter)->init)
944 50284 ret = fffilter(ctx->filter)->init(ctx);
945
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63574 times.
63574 if (ret < 0)
946 return ret;
947
948
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 63568 times.
63574 if (ctx->enable_str) {
949 6 ret = set_enable_expr(ctxi, ctx->enable_str);
950
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ret < 0)
951 return ret;
952 }
953
954 63574 ctxi->state_flags |= AV_CLASS_STATE_INITIALIZED;
955
956 63574 return 0;
957 }
958
959 20752 int avfilter_init_str(AVFilterContext *filter, const char *args)
960 {
961 20752 AVDictionary *options = NULL;
962 const AVDictionaryEntry *e;
963 20752 int ret = 0;
964
965
3/4
✓ Branch 0 taken 10360 times.
✓ Branch 1 taken 10392 times.
✓ Branch 2 taken 10360 times.
✗ Branch 3 not taken.
20752 if (args && *args) {
966 10360 ret = ff_filter_opt_parse(filter, filter->filter->priv_class, &options, args);
967
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10360 times.
10360 if (ret < 0)
968 goto fail;
969 }
970
971 20752 ret = avfilter_init_dict(filter, &options);
972
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20752 times.
20752 if (ret < 0)
973 goto fail;
974
975
1/2
✓ Branch 1 taken 20752 times.
✗ Branch 2 not taken.
20752 if ((e = av_dict_iterate(options, NULL))) {
976 av_log(filter, AV_LOG_ERROR, "No such option: %s.\n", e->key);
977 ret = AVERROR_OPTION_NOT_FOUND;
978 goto fail;
979 }
980
981 20752 fail:
982 20752 av_dict_free(&options);
983
984 20752 return ret;
985 }
986
987 15155 const char *avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx)
988 {
989 15155 return pads[pad_idx].name;
990 }
991
992 30650 enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx)
993 {
994 30650 return pads[pad_idx].type;
995 }
996
997 AVBufferRef *avfilter_link_get_hw_frames_ctx(AVFilterLink *link)
998 {
999 FilterLink *plink = ff_filter_link(link);
1000 if (plink->hw_frames_ctx)
1001 return av_buffer_ref(plink->hw_frames_ctx);
1002
1003 return NULL;
1004 }
1005
1006 713437 static int default_filter_frame(AVFilterLink *link, AVFrame *frame)
1007 {
1008 713437 return ff_filter_frame(link->dst->outputs[0], frame);
1009 }
1010
1011 /**
1012 * Evaluate the timeline expression of the link for the time and properties
1013 * of the frame.
1014 * @return >0 if enabled, 0 if disabled
1015 * @note It does not update link->dst->is_disabled.
1016 */
1017 2274732 static int evaluate_timeline_at_frame(AVFilterLink *link, const AVFrame *frame)
1018 {
1019 2274732 FilterLink *l = ff_filter_link(link);
1020 2274732 AVFilterContext *dstctx = link->dst;
1021 2274732 FFFilterContext *dsti = fffilterctx(dstctx);
1022 2274732 int64_t pts = frame->pts;
1023
1024
2/2
✓ Branch 0 taken 2274534 times.
✓ Branch 1 taken 198 times.
2274732 if (!dstctx->enable_str)
1025 2274534 return 1;
1026
1027 198 dsti->var_values[VAR_N] = l->frame_count_out;
1028
1/2
✓ Branch 0 taken 198 times.
✗ Branch 1 not taken.
198 dsti->var_values[VAR_T] = pts == AV_NOPTS_VALUE ? NAN : pts * av_q2d(link->time_base);
1029 198 dsti->var_values[VAR_W] = link->w;
1030 198 dsti->var_values[VAR_H] = link->h;
1031
1032 198 return fabs(av_expr_eval(dsti->enable, dsti->var_values, NULL)) >= 0.5;
1033 }
1034
1035 733609 static int filter_frame_framed(AVFilterLink *link, AVFrame *frame)
1036 {
1037 733609 FilterLink *l = ff_filter_link(link);
1038 int (*filter_frame)(AVFilterLink *, AVFrame *);
1039 733609 AVFilterContext *dstctx = link->dst;
1040 733609 AVFilterPad *dst = link->dstpad;
1041 int ret;
1042
1043
2/2
✓ Branch 0 taken 713428 times.
✓ Branch 1 taken 20181 times.
733609 if (!(filter_frame = dst->filter_frame))
1044 713428 filter_frame = default_filter_frame;
1045
1046
2/2
✓ Branch 0 taken 2993 times.
✓ Branch 1 taken 730616 times.
733609 if (dst->flags & AVFILTERPAD_FLAG_NEEDS_WRITABLE) {
1047 2993 ret = ff_inlink_make_frame_writable(link, &frame);
1048
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2993 times.
2993 if (ret < 0)
1049 goto fail;
1050 }
1051
1052 733609 ff_inlink_process_commands(link, frame);
1053 733609 dstctx->is_disabled = !evaluate_timeline_at_frame(link, frame);
1054
1055
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 733590 times.
733609 if (dstctx->is_disabled &&
1056
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 10 times.
19 (dstctx->filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC))
1057 9 filter_frame = default_filter_frame;
1058 733609 ret = filter_frame(link, frame);
1059 733609 l->frame_count_out++;
1060 733609 return ret;
1061
1062 fail:
1063 av_frame_free(&frame);
1064 return ret;
1065 }
1066
1067 1546380 int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
1068 {
1069 1546380 FilterLinkInternal * const li = ff_link_internal(link);
1070 int ret;
1071 1546380 FF_TPRINTF_START(NULL, filter_frame); ff_tlog_link(NULL, link, 1); ff_tlog(NULL, " "); tlog_ref(NULL, frame, 1);
1072
1073 /* Consistency checks */
1074
2/2
✓ Branch 0 taken 583643 times.
✓ Branch 1 taken 962737 times.
1546380 if (link->type == AVMEDIA_TYPE_VIDEO) {
1075
2/2
✓ Branch 0 taken 434266 times.
✓ Branch 1 taken 149377 times.
583643 if (strcmp(link->dst->filter->name, "buffersink") &&
1076
2/2
✓ Branch 0 taken 258580 times.
✓ Branch 1 taken 175686 times.
434266 strcmp(link->dst->filter->name, "format") &&
1077
2/2
✓ Branch 0 taken 258553 times.
✓ Branch 1 taken 27 times.
258580 strcmp(link->dst->filter->name, "idet") &&
1078
2/2
✓ Branch 0 taken 167481 times.
✓ Branch 1 taken 91072 times.
258553 strcmp(link->dst->filter->name, "null") &&
1079
2/2
✓ Branch 0 taken 57159 times.
✓ Branch 1 taken 110322 times.
167481 strcmp(link->dst->filter->name, "scale") &&
1080
1/2
✓ Branch 0 taken 57159 times.
✗ Branch 1 not taken.
57159 strcmp(link->dst->filter->name, "libplacebo")) {
1081 av_assert1(frame->format == link->format);
1082 av_assert1(frame->width == link->w);
1083 av_assert1(frame->height == link->h);
1084 57159 if (av_pix_fmt_desc_get(link->format)->flags & AV_PIX_FMT_FLAG_ALPHA)
1085 av_assert1(frame->alpha_mode == link->alpha_mode);
1086 }
1087 } else {
1088
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 962737 times.
962737 if (frame->format != link->format) {
1089 av_log(link->dst, AV_LOG_ERROR, "Format change is not supported\n");
1090 goto error;
1091 }
1092
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 962737 times.
962737 if (av_channel_layout_compare(&frame->ch_layout, &link->ch_layout)) {
1093 av_log(link->dst, AV_LOG_ERROR, "Channel layout change is not supported\n");
1094 goto error;
1095 }
1096
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 962737 times.
962737 if (frame->sample_rate != link->sample_rate) {
1097 av_log(link->dst, AV_LOG_ERROR, "Sample rate change is not supported\n");
1098 goto error;
1099 }
1100
1101 962737 frame->duration = av_rescale_q(frame->nb_samples, (AVRational){ 1, frame->sample_rate },
1102 link->time_base);
1103 }
1104
1105 1546380 li->frame_blocked_in = li->frame_wanted_out = 0;
1106 1546380 li->l.frame_count_in++;
1107 1546380 li->l.sample_count_in += frame->nb_samples;
1108 1546380 filter_unblock(link->dst);
1109 1546380 ret = ff_framequeue_add(&li->fifo, frame);
1110
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1546380 times.
1546380 if (ret < 0) {
1111 av_frame_free(&frame);
1112 return ret;
1113 }
1114 1546380 ff_filter_set_ready(link->dst, 300);
1115 1546380 return 0;
1116
1117 error:
1118 av_frame_free(&frame);
1119 return AVERROR_PATCHWELCOME;
1120 }
1121
1122 2196477 static int samples_ready(FilterLinkInternal *link, unsigned min)
1123 {
1124
2/2
✓ Branch 1 taken 733743 times.
✓ Branch 2 taken 1462734 times.
2930220 return ff_framequeue_queued_frames(&link->fifo) &&
1125
2/2
✓ Branch 1 taken 135 times.
✓ Branch 2 taken 733608 times.
733743 (ff_framequeue_queued_samples(&link->fifo) >= min ||
1126
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 134 times.
135 link->status_in);
1127 }
1128
1129 2933 static int take_samples(FilterLinkInternal *li, unsigned min, unsigned max,
1130 AVFrame **rframe)
1131 {
1132 2933 FilterLink *l = &li->l;
1133 2933 AVFilterLink *link = &l->pub;
1134 AVFrame *frame0, *frame, *buf;
1135 unsigned nb_samples, nb_frames, i, p;
1136 int ret;
1137
1138 /* Note: this function relies on no format changes and must only be
1139 called with enough samples. */
1140 av_assert1(samples_ready(li, l->min_samples));
1141 2933 frame0 = frame = ff_framequeue_peek(&li->fifo, 0);
1142
6/6
✓ Branch 0 taken 1418 times.
✓ Branch 1 taken 1515 times.
✓ Branch 2 taken 1304 times.
✓ Branch 3 taken 114 times.
✓ Branch 4 taken 1028 times.
✓ Branch 5 taken 276 times.
2933 if (!li->fifo.samples_skipped && frame->nb_samples >= min && frame->nb_samples <= max) {
1143 1028 *rframe = ff_framequeue_take(&li->fifo);
1144 1028 return 0;
1145 }
1146 1905 nb_frames = 0;
1147 1905 nb_samples = 0;
1148 while (1) {
1149
2/2
✓ Branch 0 taken 1519 times.
✓ Branch 1 taken 1461 times.
2980 if (nb_samples + frame->nb_samples > max) {
1150
2/2
✓ Branch 0 taken 1518 times.
✓ Branch 1 taken 1 times.
1519 if (nb_samples < min)
1151 1518 nb_samples = max;
1152 1519 break;
1153 }
1154 1461 nb_samples += frame->nb_samples;
1155 1461 nb_frames++;
1156
2/2
✓ Branch 1 taken 386 times.
✓ Branch 2 taken 1075 times.
1461 if (nb_frames == ff_framequeue_queued_frames(&li->fifo))
1157 386 break;
1158 1075 frame = ff_framequeue_peek(&li->fifo, nb_frames);
1159 }
1160
1161 1905 buf = ff_get_audio_buffer(link, nb_samples);
1162
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1905 times.
1905 if (!buf)
1163 return AVERROR(ENOMEM);
1164 1905 ret = av_frame_copy_props(buf, frame0);
1165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1905 times.
1905 if (ret < 0) {
1166 av_frame_free(&buf);
1167 return ret;
1168 }
1169
1170 1905 p = 0;
1171
2/2
✓ Branch 0 taken 1461 times.
✓ Branch 1 taken 1905 times.
3366 for (i = 0; i < nb_frames; i++) {
1172 1461 frame = ff_framequeue_take(&li->fifo);
1173 1461 av_samples_copy(buf->extended_data, frame->extended_data, p, 0,
1174 1461 frame->nb_samples, link->ch_layout.nb_channels, link->format);
1175 1461 p += frame->nb_samples;
1176 1461 av_frame_free(&frame);
1177 }
1178
2/2
✓ Branch 0 taken 1518 times.
✓ Branch 1 taken 387 times.
1905 if (p < nb_samples) {
1179 1518 unsigned n = nb_samples - p;
1180 1518 frame = ff_framequeue_peek(&li->fifo, 0);
1181 1518 av_samples_copy(buf->extended_data, frame->extended_data, p, 0, n,
1182 1518 link->ch_layout.nb_channels, link->format);
1183 1518 ff_framequeue_skip_samples(&li->fifo, n, link->time_base);
1184 }
1185
1186 1905 *rframe = buf;
1187 1905 return 0;
1188 }
1189
1190 733609 static int filter_frame_to_filter(AVFilterLink *link)
1191 {
1192 733609 FilterLinkInternal * const li = ff_link_internal(link);
1193 733609 AVFrame *frame = NULL;
1194 733609 AVFilterContext *dst = link->dst;
1195 int ret;
1196
1197 av_assert1(ff_framequeue_queued_frames(&li->fifo));
1198 1467218 ret = li->l.min_samples ?
1199
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 733573 times.
733609 ff_inlink_consume_samples(link, li->l.min_samples, li->l.max_samples, &frame) :
1200 733573 ff_inlink_consume_frame(link, &frame);
1201 av_assert1(ret);
1202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 733609 times.
733609 if (ret < 0) {
1203 av_assert1(!frame);
1204 return ret;
1205 }
1206 /* The filter will soon have received a new frame, that may allow it to
1207 produce one or more: unblock its outputs. */
1208 733609 filter_unblock(dst);
1209 /* AVFilterPad.filter_frame() expect frame_count_out to have the value
1210 before the frame; filter_frame_framed() will re-increment it. */
1211 733609 li->l.frame_count_out--;
1212 733609 ret = filter_frame_framed(link, frame);
1213
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 733609 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
733609 if (ret < 0 && ret != li->status_out) {
1214 link_set_out_status(link, ret, AV_NOPTS_VALUE);
1215 } else {
1216 /* Run once again, to see if several frames were available, or if
1217 the input status has also changed, or any other reason. */
1218 733609 ff_filter_set_ready(dst, 300);
1219 }
1220 733609 return ret;
1221 }
1222
1223 5999 static int forward_status_change(AVFilterContext *filter, FilterLinkInternal *li_in)
1224 {
1225 5999 AVFilterLink *in = &li_in->l.pub;
1226 5999 unsigned out = 0, progress = 0;
1227 int ret;
1228
1229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5999 times.
5999 av_assert0(!li_in->status_out);
1230
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5998 times.
5999 if (!filter->nb_outputs) {
1231 /* not necessary with the current API and sinks */
1232 1 return 0;
1233 }
1234
2/2
✓ Branch 0 taken 5998 times.
✓ Branch 1 taken 5998 times.
11996 while (!li_in->status_out) {
1235 5998 FilterLinkInternal *li_out = ff_link_internal(filter->outputs[out]);
1236
1237
1/2
✓ Branch 0 taken 5998 times.
✗ Branch 1 not taken.
5998 if (!li_out->status_in) {
1238 5998 progress++;
1239 5998 ret = request_frame_to_filter(filter->outputs[out]);
1240
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5998 times.
5998 if (ret < 0)
1241 return ret;
1242 }
1243
1/2
✓ Branch 0 taken 5998 times.
✗ Branch 1 not taken.
5998 if (++out == filter->nb_outputs) {
1244
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5998 times.
5998 if (!progress) {
1245 /* Every output already closed: input no longer interesting
1246 (example: overlay in shortest mode, other input closed). */
1247 link_set_out_status(in, li_in->status_in, li_in->status_in_pts);
1248 return 0;
1249 }
1250 5998 progress = 0;
1251 5998 out = 0;
1252 }
1253 }
1254 5998 ff_filter_set_ready(filter, 200);
1255 5998 return 0;
1256 }
1257
1258 2203578 static int filter_activate_default(AVFilterContext *filter)
1259 {
1260 unsigned i;
1261 2203578 int nb_eofs = 0;
1262
1263
2/2
✓ Branch 0 taken 2203531 times.
✓ Branch 1 taken 2203578 times.
4407109 for (i = 0; i < filter->nb_outputs; i++)
1264 2203531 nb_eofs += ff_outlink_get_status(filter->outputs[i]) == AVERROR_EOF;
1265
4/4
✓ Branch 0 taken 2203531 times.
✓ Branch 1 taken 47 times.
✓ Branch 2 taken 6830 times.
✓ Branch 3 taken 2196701 times.
2203578 if (filter->nb_outputs && nb_eofs == filter->nb_outputs) {
1266
2/2
✓ Branch 0 taken 6830 times.
✓ Branch 1 taken 6830 times.
13660 for (int j = 0; j < filter->nb_inputs; j++)
1267 6830 ff_inlink_set_status(filter->inputs[j], AVERROR_EOF);
1268 6830 return 0;
1269 }
1270
1271
2/2
✓ Branch 0 taken 2196477 times.
✓ Branch 1 taken 1463139 times.
3659616 for (i = 0; i < filter->nb_inputs; i++) {
1272 2196477 FilterLinkInternal *li = ff_link_internal(filter->inputs[i]);
1273
2/2
✓ Branch 1 taken 733609 times.
✓ Branch 2 taken 1462868 times.
2196477 if (samples_ready(li, li->l.min_samples)) {
1274 733609 return filter_frame_to_filter(filter->inputs[i]);
1275 }
1276 }
1277
2/2
✓ Branch 0 taken 1462868 times.
✓ Branch 1 taken 1457140 times.
2920008 for (i = 0; i < filter->nb_inputs; i++) {
1278 1462868 FilterLinkInternal * const li = ff_link_internal(filter->inputs[i]);
1279
4/4
✓ Branch 0 taken 6028 times.
✓ Branch 1 taken 1456840 times.
✓ Branch 2 taken 5999 times.
✓ Branch 3 taken 29 times.
1462868 if (li->status_in && !li->status_out) {
1280 av_assert1(!ff_framequeue_queued_frames(&li->fifo));
1281 5999 return forward_status_change(filter, li);
1282 }
1283 }
1284
2/2
✓ Branch 0 taken 1457117 times.
✓ Branch 1 taken 733544 times.
2190661 for (i = 0; i < filter->nb_outputs; i++) {
1285 1457117 FilterLinkInternal * const li = ff_link_internal(filter->outputs[i]);
1286
2/2
✓ Branch 0 taken 728453 times.
✓ Branch 1 taken 728664 times.
1457117 if (li->frame_wanted_out &&
1287
2/2
✓ Branch 0 taken 723596 times.
✓ Branch 1 taken 4857 times.
728453 !li->frame_blocked_in) {
1288 723596 return request_frame_to_filter(filter->outputs[i]);
1289 }
1290 }
1291
2/2
✓ Branch 0 taken 733521 times.
✓ Branch 1 taken 728687 times.
1462208 for (i = 0; i < filter->nb_outputs; i++) {
1292 733521 FilterLinkInternal * const li = ff_link_internal(filter->outputs[i]);
1293
2/2
✓ Branch 0 taken 4857 times.
✓ Branch 1 taken 728664 times.
733521 if (li->frame_wanted_out)
1294 4857 return request_frame_to_filter(filter->outputs[i]);
1295 }
1296
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 728664 times.
728687 if (!filter->nb_outputs) {
1297 23 ff_inlink_request_frame(filter->inputs[0]);
1298 23 return 0;
1299 }
1300 728664 return FFERROR_NOT_READY;
1301 }
1302
1303 /*
1304 Filter scheduling and activation
1305
1306 When a filter is activated, it must:
1307 - if possible, output a frame;
1308 - else, if relevant, forward the input status change;
1309 - else, check outputs for wanted frames and forward the requests.
1310
1311 The following AVFilterLink fields are used for activation:
1312
1313 - frame_wanted_out:
1314
1315 This field indicates if a frame is needed on this input of the
1316 destination filter. A positive value indicates that a frame is needed
1317 to process queued frames or internal data or to satisfy the
1318 application; a zero value indicates that a frame is not especially
1319 needed but could be processed anyway; a negative value indicates that a
1320 frame would just be queued.
1321
1322 It is set by filters using ff_request_frame() or ff_request_no_frame(),
1323 when requested by the application through a specific API or when it is
1324 set on one of the outputs.
1325
1326 It is cleared when a frame is sent from the source using
1327 ff_filter_frame().
1328
1329 It is also cleared when a status change is sent from the source using
1330 ff_avfilter_link_set_in_status().
1331
1332 - frame_blocked_in:
1333
1334 This field means that the source filter can not generate a frame as is.
1335 Its goal is to avoid repeatedly calling the request_frame() method on
1336 the same link.
1337
1338 It is set by the framework on all outputs of a filter before activating it.
1339
1340 It is automatically cleared by ff_filter_frame().
1341
1342 It is also automatically cleared by ff_avfilter_link_set_in_status().
1343
1344 It is also cleared on all outputs (using filter_unblock()) when
1345 something happens on an input: processing a frame or changing the
1346 status.
1347
1348 - fifo:
1349
1350 Contains the frames queued on a filter input. If it contains frames and
1351 frame_wanted_out is not set, then the filter can be activated. If that
1352 result in the filter not able to use these frames, the filter must set
1353 frame_wanted_out to ask for more frames.
1354
1355 - status_in and status_in_pts:
1356
1357 Status (EOF or error code) of the link and timestamp of the status
1358 change (in link time base, same as frames) as seen from the input of
1359 the link. The status change is considered happening after the frames
1360 queued in fifo.
1361
1362 It is set by the source filter using ff_avfilter_link_set_in_status().
1363
1364 - status_out:
1365
1366 Status of the link as seen from the output of the link. The status
1367 change is considered having already happened.
1368
1369 It is set by the destination filter using
1370 link_set_out_status().
1371
1372 Filters are activated according to the ready field, set using the
1373 ff_filter_set_ready(). Eventually, a priority queue will be used.
1374 ff_filter_set_ready() is called whenever anything could cause progress to
1375 be possible. Marking a filter ready when it is not is not a problem,
1376 except for the small overhead it causes.
1377
1378 Conditions that cause a filter to be marked ready are:
1379
1380 - frames added on an input link;
1381
1382 - changes in the input or output status of an input link;
1383
1384 - requests for a frame on an output link;
1385
1386 - after any actual processing using the legacy methods (filter_frame(),
1387 and request_frame() to acknowledge status changes), to run once more
1388 and check if enough input was present for several frames.
1389
1390 Examples of scenarios to consider:
1391
1392 - buffersrc: activate if frame_wanted_out to notify the application;
1393 activate when the application adds a frame to push it immediately.
1394
1395 - testsrc: activate only if frame_wanted_out to produce and push a frame.
1396
1397 - concat (not at stitch points): can process a frame on any output.
1398 Activate if frame_wanted_out on output to forward on the corresponding
1399 input. Activate when a frame is present on input to process it
1400 immediately.
1401
1402 - framesync: needs at least one frame on each input; extra frames on the
1403 wrong input will accumulate. When a frame is first added on one input,
1404 set frame_wanted_out<0 on it to avoid getting more (would trigger
1405 testsrc) and frame_wanted_out>0 on the other to allow processing it.
1406
1407 Activation of old filters:
1408
1409 In order to activate a filter implementing the legacy filter_frame() and
1410 request_frame() methods, perform the first possible of the following
1411 actions:
1412
1413 - If an input has frames in fifo and frame_wanted_out == 0, dequeue a
1414 frame and call filter_frame().
1415
1416 Rationale: filter frames as soon as possible instead of leaving them
1417 queued; frame_wanted_out < 0 is not possible since the old API does not
1418 set it nor provides any similar feedback; frame_wanted_out > 0 happens
1419 when min_samples > 0 and there are not enough samples queued.
1420
1421 - If an input has status_in set but not status_out, try to call
1422 request_frame() on one of the outputs in the hope that it will trigger
1423 request_frame() on the input with status_in and acknowledge it. This is
1424 awkward and fragile, filters with several inputs or outputs should be
1425 updated to direct activation as soon as possible.
1426
1427 - If an output has frame_wanted_out > 0 and not frame_blocked_in, call
1428 request_frame().
1429
1430 Rationale: checking frame_blocked_in is necessary to avoid requesting
1431 repeatedly on a blocked input if another is not blocked (example:
1432 [buffersrc1][testsrc1][buffersrc2][testsrc2]concat=v=2).
1433
1434 - If an output has frame_wanted_out > 0 call request_frame().
1435
1436 Rationale: even if all inputs are blocked an activate callback should
1437 request a frame on some if its inputs if a frame is requested on any of
1438 its output.
1439
1440 - Request a frame on the input for sinks.
1441
1442 Rationale: sinks using the old api have no way to request a frame on their
1443 input, so we need to do it for them.
1444 */
1445
1446 3845598 int ff_filter_activate(AVFilterContext *filter)
1447 {
1448 3845598 FFFilterContext *ctxi = fffilterctx(filter);
1449 3845598 const FFFilter *const fi = fffilter(filter->filter);
1450 int ret;
1451
1452 /* Generic timeline support is not yet implemented but should be easy */
1453 av_assert1(!(fi->p.flags & AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC &&
1454 fi->activate));
1455 3845598 ctxi->ready = 0;
1456
2/2
✓ Branch 0 taken 1642020 times.
✓ Branch 1 taken 2203578 times.
3845598 ret = fi->activate ? fi->activate(filter) : filter_activate_default(filter);
1457
2/2
✓ Branch 0 taken 729537 times.
✓ Branch 1 taken 3116061 times.
3845598 if (ret == FFERROR_NOT_READY)
1458 729537 ret = 0;
1459 3845598 return ret;
1460 }
1461
1462 3534232 int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
1463 {
1464 3534232 FilterLinkInternal * const li = ff_link_internal(link);
1465 3534232 *rpts = li->l.current_pts;
1466
2/2
✓ Branch 1 taken 2172 times.
✓ Branch 2 taken 3532060 times.
3534232 if (ff_framequeue_queued_frames(&li->fifo))
1467 2172 return *rstatus = 0;
1468
2/2
✓ Branch 0 taken 7925 times.
✓ Branch 1 taken 3524135 times.
3532060 if (li->status_out)
1469 7925 return *rstatus = li->status_out;
1470
2/2
✓ Branch 0 taken 3516211 times.
✓ Branch 1 taken 7924 times.
3524135 if (!li->status_in)
1471 3516211 return *rstatus = 0;
1472 7924 *rstatus = li->status_out = li->status_in;
1473 7924 update_link_current_pts(li, li->status_in_pts);
1474 7924 *rpts = li->l.current_pts;
1475 7924 return 1;
1476 }
1477
1478 1934 size_t ff_inlink_queued_frames(AVFilterLink *link)
1479 {
1480 1934 FilterLinkInternal * const li = ff_link_internal(link);
1481 1934 return ff_framequeue_queued_frames(&li->fifo);
1482 }
1483
1484 5067385 int ff_inlink_check_available_frame(AVFilterLink *link)
1485 {
1486 5067385 FilterLinkInternal * const li = ff_link_internal(link);
1487 5067385 return ff_framequeue_queued_frames(&li->fifo) > 0;
1488 }
1489
1490 8567 int ff_inlink_queued_samples(AVFilterLink *link)
1491 {
1492 8567 FilterLinkInternal * const li = ff_link_internal(link);
1493 8567 return ff_framequeue_queued_samples(&li->fifo);
1494 }
1495
1496 5024 int ff_inlink_check_available_samples(AVFilterLink *link, unsigned min)
1497 {
1498 5024 FilterLinkInternal * const li = ff_link_internal(link);
1499 5024 uint64_t samples = ff_framequeue_queued_samples(&li->fifo);
1500 av_assert1(min);
1501
6/6
✓ Branch 0 taken 2097 times.
✓ Branch 1 taken 2927 times.
✓ Branch 2 taken 65 times.
✓ Branch 3 taken 2032 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 59 times.
5024 return samples >= min || (li->status_in && samples);
1502 }
1503
1504 1543853 static void consume_update(FilterLinkInternal *li, const AVFrame *frame)
1505 {
1506 1543853 AVFilterLink *const link = &li->l.pub;
1507 1543853 update_link_current_pts(li, frame->pts);
1508 1543853 ff_inlink_process_commands(link, frame);
1509
2/2
✓ Branch 0 taken 1541123 times.
✓ Branch 1 taken 2730 times.
1543853 if (link == link->dst->inputs[0])
1510 1541123 link->dst->is_disabled = !evaluate_timeline_at_frame(link, frame);
1511 1543853 li->l.frame_count_out++;
1512 1543853 li->l.sample_count_out += frame->nb_samples;
1513 1543853 }
1514
1515 5065500 int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
1516 {
1517 5065500 FilterLinkInternal * const li = ff_link_internal(link);
1518 AVFrame *frame;
1519
1520 5065500 *rframe = NULL;
1521
2/2
✓ Branch 1 taken 3524576 times.
✓ Branch 2 taken 1540924 times.
5065500 if (!ff_inlink_check_available_frame(link))
1522 3524576 return 0;
1523
1524
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1540920 times.
1540924 if (li->fifo.samples_skipped) {
1525 4 frame = ff_framequeue_peek(&li->fifo, 0);
1526 4 return ff_inlink_consume_samples(link, frame->nb_samples, frame->nb_samples, rframe);
1527 }
1528
1529 1540920 frame = ff_framequeue_take(&li->fifo);
1530 1540920 consume_update(li, frame);
1531 1540920 *rframe = frame;
1532 1540920 return 1;
1533 }
1534
1535 5024 int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max,
1536 AVFrame **rframe)
1537 {
1538 5024 FilterLinkInternal * const li = ff_link_internal(link);
1539 AVFrame *frame;
1540 int ret;
1541
1542 av_assert1(min);
1543 5024 *rframe = NULL;
1544
2/2
✓ Branch 1 taken 2091 times.
✓ Branch 2 taken 2933 times.
5024 if (!ff_inlink_check_available_samples(link, min))
1545 2091 return 0;
1546
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 2922 times.
2933 if (li->status_in)
1547
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 5 times.
11 min = FFMIN(min, ff_framequeue_queued_samples(&li->fifo));
1548 2933 ret = take_samples(li, min, max, &frame);
1549
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2933 times.
2933 if (ret < 0)
1550 return ret;
1551 2933 consume_update(li, frame);
1552 2933 *rframe = frame;
1553 2933 return 1;
1554 }
1555
1556 210 AVFrame *ff_inlink_peek_frame(AVFilterLink *link, size_t idx)
1557 {
1558 210 FilterLinkInternal * const li = ff_link_internal(link);
1559 210 return ff_framequeue_peek(&li->fifo, idx);
1560 }
1561
1562 5179 int ff_inlink_make_frame_writable(AVFilterLink *link, AVFrame **rframe)
1563 {
1564 5179 AVFrame *frame = *rframe;
1565 AVFrame *out;
1566 int ret;
1567
1568
2/2
✓ Branch 1 taken 2290 times.
✓ Branch 2 taken 2889 times.
5179 if (av_frame_is_writable(frame))
1569 2290 return 0;
1570 2889 av_log(link->dst, AV_LOG_DEBUG, "Copying data in avfilter.\n");
1571
1572
1/3
✓ Branch 0 taken 2889 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
2889 switch (link->type) {
1573 2889 case AVMEDIA_TYPE_VIDEO:
1574 2889 out = ff_get_video_buffer(link, link->w, link->h);
1575 2889 break;
1576 case AVMEDIA_TYPE_AUDIO:
1577 out = ff_get_audio_buffer(link, frame->nb_samples);
1578 break;
1579 default:
1580 return AVERROR(EINVAL);
1581 }
1582
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2889 times.
2889 if (!out)
1583 return AVERROR(ENOMEM);
1584
1585 2889 ret = av_frame_copy_props(out, frame);
1586
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2889 times.
2889 if (ret < 0) {
1587 av_frame_free(&out);
1588 return ret;
1589 }
1590
1591 2889 ret = av_frame_copy(out, frame);
1592
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2889 times.
2889 if (ret < 0) {
1593 av_frame_free(&out);
1594 return ret;
1595 }
1596
1597 2889 av_frame_free(&frame);
1598 2889 *rframe = out;
1599 2889 return 0;
1600 }
1601
1602 2277462 int ff_inlink_process_commands(AVFilterLink *link, const AVFrame *frame)
1603 {
1604 2277462 FFFilterContext *ctxi = fffilterctx(link->dst);
1605 2277462 AVFilterCommand *cmd = ctxi->command_queue;
1606
1607
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2277462 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2277462 while(cmd && cmd->time <= frame->pts * av_q2d(link->time_base)){
1608 av_log(link->dst, AV_LOG_DEBUG,
1609 "Processing command time:%f command:%s arg:%s\n",
1610 cmd->time, cmd->command, cmd->arg);
1611 avfilter_process_command(link->dst, cmd->command, cmd->arg, 0, 0, cmd->flags);
1612 command_queue_pop(link->dst);
1613 cmd = ctxi->command_queue;
1614 }
1615 2277462 return 0;
1616 }
1617
1618 817192 void ff_inlink_request_frame(AVFilterLink *link)
1619 {
1620 817192 av_unused FilterLinkInternal *li = ff_link_internal(link);
1621 av_assert1(!li->status_in);
1622 av_assert1(!li->status_out);
1623 817192 li->frame_wanted_out = 1;
1624 817192 ff_filter_set_ready(link->src, 100);
1625 817192 }
1626
1627 10928 void ff_inlink_set_status(AVFilterLink *link, int status)
1628 {
1629 10928 FilterLinkInternal * const li = ff_link_internal(link);
1630
2/2
✓ Branch 0 taken 8452 times.
✓ Branch 1 taken 2476 times.
10928 if (li->status_out)
1631 8452 return;
1632 2476 li->frame_wanted_out = 0;
1633 2476 li->frame_blocked_in = 0;
1634 2476 link_set_out_status(link, status, AV_NOPTS_VALUE);
1635
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 2476 times.
2483 while (ff_framequeue_queued_frames(&li->fifo)) {
1636 7 AVFrame *frame = ff_framequeue_take(&li->fifo);
1637 7 av_frame_free(&frame);
1638 }
1639
2/2
✓ Branch 0 taken 2473 times.
✓ Branch 1 taken 3 times.
2476 if (!li->status_in)
1640 2473 li->status_in = status;
1641 }
1642
1643 3770632 int ff_outlink_get_status(AVFilterLink *link)
1644 {
1645 3770632 FilterLinkInternal * const li = ff_link_internal(link);
1646 3770632 return li->status_in;
1647 }
1648
1649 1478 int ff_inoutlink_check_flow(AVFilterLink *inlink, AVFilterLink *outlink)
1650 {
1651 1478 FilterLinkInternal * const li_in = ff_link_internal(inlink);
1652
1/2
✓ Branch 1 taken 887 times.
✗ Branch 2 not taken.
2365 return ff_outlink_frame_wanted(outlink) ||
1653
2/2
✓ Branch 0 taken 887 times.
✓ Branch 1 taken 591 times.
2365 ff_inlink_check_available_frame(inlink) ||
1654
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 860 times.
887 li_in->status_out;
1655 }
1656
1657
1658 const AVClass *avfilter_get_class(void)
1659 {
1660 return &avfilter_class;
1661 }
1662
1663 int ff_filter_init_hw_frames(AVFilterContext *avctx, AVFilterLink *link,
1664 int default_pool_size)
1665 {
1666 FilterLink *l = ff_filter_link(link);
1667 AVHWFramesContext *frames;
1668
1669 // Must already be set by caller.
1670 av_assert0(l->hw_frames_ctx);
1671
1672 frames = (AVHWFramesContext*)l->hw_frames_ctx->data;
1673
1674 if (frames->initial_pool_size == 0) {
1675 // Dynamic allocation is necessarily supported.
1676 } else if (avctx->extra_hw_frames >= 0) {
1677 frames->initial_pool_size += avctx->extra_hw_frames;
1678 } else {
1679 frames->initial_pool_size = default_pool_size;
1680 }
1681
1682 return 0;
1683 }
1684
1685 447454 int ff_outlink_frame_wanted(AVFilterLink *link)
1686 {
1687 447454 FilterLinkInternal * const li = ff_link_internal(link);
1688 447454 return li->frame_wanted_out;
1689 }
1690
1691 4989 int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func,
1692 void *arg, int *ret, int nb_jobs)
1693 {
1694 4989 return fffilterctx(ctx)->execute(ctx, func, arg, ret, nb_jobs);
1695 }
1696