FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/avfilter.c
Date: 2026-04-05 07:23:09
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 1684401 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 1684401 }
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 47354 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 47354 times.
47354 av_assert0(src->graph);
156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47354 times.
47354 av_assert0(dst->graph);
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47354 times.
47354 av_assert0(src->graph == dst->graph);
158
159
2/4
✓ Branch 0 taken 47354 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47354 times.
✗ Branch 3 not taken.
47354 if (src->nb_outputs <= srcpad || dst->nb_inputs <= dstpad ||
160
2/4
✓ Branch 0 taken 47354 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 47354 times.
47354 src->outputs[srcpad] || dst->inputs[dstpad])
161 return AVERROR(EINVAL);
162
163
1/2
✓ Branch 1 taken 47354 times.
✗ Branch 2 not taken.
47354 if (!(fffilterctx(src)->state_flags & AV_CLASS_STATE_INITIALIZED) ||
164
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 47354 times.
47354 !(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 47354 times.
47354 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 47354 li = av_mallocz(sizeof(*li));
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47354 times.
47354 if (!li)
179 return AVERROR(ENOMEM);
180 47354 link = &li->l.pub;
181
182 47354 src->outputs[srcpad] = dst->inputs[dstpad] = link;
183
184 47354 link->src = src;
185 47354 link->dst = dst;
186 47354 link->srcpad = &src->output_pads[srcpad];
187 47354 link->dstpad = &dst->input_pads[dstpad];
188 47354 link->type = src->output_pads[srcpad].type;
189 47354 li->l.graph = src->graph;
190 av_assert0(AV_PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1);
191 47354 link->format = -1;
192 47354 link->colorspace = AVCOL_SPC_UNSPECIFIED;
193 47354 ff_framequeue_init(&li->fifo, &fffiltergraph(src->graph)->frame_queues);
194
195 47354 return 0;
196 }
197
198 47486 static void link_free(AVFilterLink **link)
199 {
200 FilterLinkInternal *li;
201
202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47486 times.
47486 if (!*link)
203 return;
204 47486 li = ff_link_internal(*link);
205
206 47486 ff_framequeue_free(&li->fifo);
207 47486 ff_frame_pool_uninit(&li->frame_pool);
208 47486 av_channel_layout_uninit(&(*link)->ch_layout);
209 47486 av_frame_side_data_free(&(*link)->side_data, &(*link)->nb_side_data);
210
211 47486 av_buffer_unref(&li->l.hw_frames_ctx);
212
213 47486 av_freep(link);
214 }
215
216 1695895 static void update_link_current_pts(FilterLinkInternal *li, int64_t pts)
217 {
218 1695895 AVFilterLink *const link = &li->l.pub;
219
220
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1695890 times.
1695895 if (pts == AV_NOPTS_VALUE)
221 5 return;
222 1695890 li->l.current_pts = pts;
223 1695890 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 1695890 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 457038 times.
✓ Branch 3 taken 1238852 times.
1695890 if (li->l.graph && li->age_index >= 0)
226 457038 ff_avfilter_graph_update_heap(li->l.graph, li);
227 }
228
229 4205603 void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
230 {
231 4205603 FFFilterContext *ctxi = fffilterctx(filter);
232 4205603 ctxi->ready = FFMAX(ctxi->ready, priority);
233 4205603 }
234
235 /**
236 * Clear frame_blocked_in on all outputs.
237 * This is necessary whenever something changes on input.
238 */
239 2510303 static void filter_unblock(AVFilterContext *filter)
240 {
241 unsigned i;
242
243
2/2
✓ Branch 0 taken 2053376 times.
✓ Branch 1 taken 2510303 times.
4563679 for (i = 0; i < filter->nb_outputs; i++) {
244 2053376 FilterLinkInternal * const li = ff_link_internal(filter->outputs[i]);
245 2053376 li->frame_blocked_in = 0;
246 }
247 2510303 }
248
249
250 19648 void ff_avfilter_link_set_in_status(AVFilterLink *link, int status, int64_t pts)
251 {
252 19648 FilterLinkInternal * const li = ff_link_internal(link);
253
254
2/2
✓ Branch 0 taken 5611 times.
✓ Branch 1 taken 14037 times.
19648 if (li->status_in == status)
255 5611 return;
256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14037 times.
14037 av_assert0(!li->status_in);
257 14037 li->status_in = status;
258 14037 li->status_in_pts = pts;
259 14037 li->frame_wanted_out = 0;
260 14037 li->frame_blocked_in = 0;
261 14037 filter_unblock(link->dst);
262 14037 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 8562 static void link_set_out_status(AVFilterLink *link, int status, int64_t pts)
270 {
271 8562 FilterLinkInternal * const li = ff_link_internal(link);
272
273
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8562 times.
8562 av_assert0(!li->frame_wanted_out);
274
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8562 times.
8562 av_assert0(!li->status_out);
275 8562 li->status_out = status;
276
2/2
✓ Branch 0 taken 6052 times.
✓ Branch 1 taken 2510 times.
8562 if (pts != AV_NOPTS_VALUE)
277 6052 update_link_current_pts(li, pts);
278 8562 filter_unblock(link->dst);
279 8562 ff_filter_set_ready(link->src, 200);
280 8562 }
281
282 1276 int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
283 unsigned filt_srcpad_idx, unsigned filt_dstpad_idx)
284 {
285 int ret;
286 1276 unsigned dstpad_idx = link->dstpad - link->dst->input_pads;
287
288 1276 av_log(link->dst, AV_LOG_VERBOSE, "auto-inserting filter '%s' "
289 "between the filter '%s' and the filter '%s'\n",
290 1276 filt->name, link->src->name, link->dst->name);
291
292 1276 link->dst->inputs[dstpad_idx] = NULL;
293
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1276 times.
1276 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 1276 link->dst = filt;
301 1276 link->dstpad = &filt->input_pads[filt_srcpad_idx];
302 1276 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 1276 times.
✗ Branch 1 not taken.
1276 if (link->outcfg.formats)
307 1276 ff_formats_changeref(&link->outcfg.formats,
308 1276 &filt->outputs[filt_dstpad_idx]->outcfg.formats);
309
2/2
✓ Branch 0 taken 630 times.
✓ Branch 1 taken 646 times.
1276 if (link->outcfg.color_spaces)
310 630 ff_formats_changeref(&link->outcfg.color_spaces,
311 630 &filt->outputs[filt_dstpad_idx]->outcfg.color_spaces);
312
2/2
✓ Branch 0 taken 630 times.
✓ Branch 1 taken 646 times.
1276 if (link->outcfg.color_ranges)
313 630 ff_formats_changeref(&link->outcfg.color_ranges,
314 630 &filt->outputs[filt_dstpad_idx]->outcfg.color_ranges);
315
2/2
✓ Branch 0 taken 630 times.
✓ Branch 1 taken 646 times.
1276 if (link->outcfg.alpha_modes)
316 630 ff_formats_changeref(&link->outcfg.alpha_modes,
317 630 &filt->outputs[filt_dstpad_idx]->outcfg.alpha_modes);
318
2/2
✓ Branch 0 taken 646 times.
✓ Branch 1 taken 630 times.
1276 if (link->outcfg.samplerates)
319 646 ff_formats_changeref(&link->outcfg.samplerates,
320 646 &filt->outputs[filt_dstpad_idx]->outcfg.samplerates);
321
2/2
✓ Branch 0 taken 646 times.
✓ Branch 1 taken 630 times.
1276 if (link->outcfg.channel_layouts)
322 646 ff_channel_layouts_changeref(&link->outcfg.channel_layouts,
323 646 &filt->outputs[filt_dstpad_idx]->outcfg.channel_layouts);
324
325 1276 return 0;
326 }
327
328 45344 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 37119 times.
✓ Branch 1 taken 45342 times.
82461 for (i = 0; i < filter->nb_inputs; i ++) {
335 37119 AVFilterLink *link = filter->inputs[i];
336 AVFilterLink *inlink;
337 37119 FilterLinkInternal *li = ff_link_internal(link);
338 FilterLinkInternal *li_in;
339
340
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37119 times.
37119 if (!link) continue;
341
2/4
✓ Branch 0 taken 37119 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 37119 times.
37119 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 28694 times.
✓ Branch 1 taken 8425 times.
37119 inlink = link->src->nb_inputs ? link->src->inputs[0] : NULL;
348
2/2
✓ Branch 0 taken 28694 times.
✓ Branch 1 taken 8425 times.
37119 li_in = inlink ? ff_link_internal(inlink) : NULL;
349 37119 li->l.current_pts =
350 37119 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 37006 times.
✗ Branch 3 not taken.
37119 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 37006 case AVLINK_UNINIT:
359 37006 li->init_state = AVLINK_STARTINIT;
360
361
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 37006 times.
37006 if ((ret = ff_filter_config_links(link->src)) < 0)
362 return ret;
363
364
2/2
✓ Branch 0 taken 19393 times.
✓ Branch 1 taken 17613 times.
37006 if (!(config_link = link->srcpad->config_props)) {
365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19393 times.
19393 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 28615 times.
✓ Branch 1 taken 8391 times.
✓ Branch 2 taken 261 times.
✓ Branch 3 taken 28354 times.
✓ Branch 4 taken 261 times.
✗ Branch 5 not taken.
37006 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 17613 times.
✓ Branch 1 taken 19393 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17613 times.
37006 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 30948 times.
✓ Branch 1 taken 6058 times.
✗ Branch 2 not taken.
37006 switch (link->type) {
395 30948 case AVMEDIA_TYPE_VIDEO:
396
3/4
✓ Branch 0 taken 23702 times.
✓ Branch 1 taken 7246 times.
✓ Branch 2 taken 23702 times.
✗ Branch 3 not taken.
30948 if (!link->time_base.num && !link->time_base.den)
397
1/2
✓ Branch 0 taken 23702 times.
✗ Branch 1 not taken.
23702 link->time_base = inlink ? inlink->time_base : AV_TIME_BASE_Q;
398
399
4/4
✓ Branch 0 taken 26497 times.
✓ Branch 1 taken 4451 times.
✓ Branch 2 taken 16855 times.
✓ Branch 3 taken 9642 times.
30948 if (!link->sample_aspect_ratio.num && !link->sample_aspect_ratio.den)
400 16855 link->sample_aspect_ratio = inlink ?
401
2/2
✓ Branch 0 taken 16840 times.
✓ Branch 1 taken 15 times.
16855 inlink->sample_aspect_ratio : (AVRational){1,1};
402
403
2/2
✓ Branch 0 taken 23964 times.
✓ Branch 1 taken 6984 times.
30948 if (inlink) {
404
3/4
✓ Branch 0 taken 23745 times.
✓ Branch 1 taken 219 times.
✓ Branch 2 taken 23745 times.
✗ Branch 3 not taken.
23964 if (!li->l.frame_rate.num && !li->l.frame_rate.den)
405 23745 li->l.frame_rate = li_in->l.frame_rate;
406
2/2
✓ Branch 0 taken 16352 times.
✓ Branch 1 taken 7612 times.
23964 if (!link->w)
407 16352 link->w = inlink->w;
408
2/2
✓ Branch 0 taken 16352 times.
✓ Branch 1 taken 7612 times.
23964 if (!link->h)
409 16352 link->h = inlink->h;
410
2/4
✓ Branch 0 taken 6984 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6984 times.
6984 } 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 30948 break;
417
418 6058 case AVMEDIA_TYPE_AUDIO:
419
2/2
✓ Branch 0 taken 4651 times.
✓ Branch 1 taken 1407 times.
6058 if (inlink) {
420
3/4
✓ Branch 0 taken 3132 times.
✓ Branch 1 taken 1519 times.
✓ Branch 2 taken 3132 times.
✗ Branch 3 not taken.
4651 if (!link->time_base.num && !link->time_base.den)
421 3132 link->time_base = inlink->time_base;
422 }
423
424
3/4
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 5975 times.
✓ Branch 2 taken 83 times.
✗ Branch 3 not taken.
6058 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 28615 times.
✓ Branch 1 taken 8391 times.
37006 if (link->src->nb_inputs &&
429
1/2
✓ Branch 1 taken 28615 times.
✗ Branch 2 not taken.
28615 !(fffilter(link->src->filter)->flags_internal & FF_FILTER_FLAG_HWFRAME_AWARE)) {
430 28615 FilterLink *l0 = ff_filter_link(link->src->inputs[0]);
431
432
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28615 times.
28615 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 28615 times.
28615 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 4945 times.
✓ Branch 1 taken 32061 times.
37006 if ((config_link = link->dstpad->config_props))
443
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4945 times.
4945 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 37006 li->init_state = AVLINK_INIT;
451 }
452 }
453
454 45342 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 803861 int ff_request_frame(AVFilterLink *link)
484 {
485 803861 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 803852 times.
803861 if (li->status_out)
491 9 return li->status_out;
492
2/2
✓ Branch 0 taken 6053 times.
✓ Branch 1 taken 797799 times.
803852 if (li->status_in) {
493
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6053 times.
6053 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 6053 link_set_out_status(link, li->status_in, li->status_in_pts);
502 6053 return li->status_out;
503 }
504 }
505 797799 li->frame_wanted_out = 1;
506 797799 ff_filter_set_ready(link->src, 100);
507 797799 return 0;
508 }
509
510 6047 static int64_t guess_status_pts(AVFilterContext *ctx, int status, AVRational link_time_base)
511 {
512 unsigned i;
513 6047 int64_t r = INT64_MAX;
514
515
2/2
✓ Branch 0 taken 6046 times.
✓ Branch 1 taken 6047 times.
12093 for (i = 0; i < ctx->nb_inputs; i++) {
516 6046 FilterLinkInternal * const li = ff_link_internal(ctx->inputs[i]);
517
1/2
✓ Branch 0 taken 6046 times.
✗ Branch 1 not taken.
6046 if (li->status_out == status)
518 6046 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 6046 times.
✓ Branch 1 taken 1 times.
6047 if (r < INT64_MAX)
521 6046 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 804176 static int request_frame_to_filter(AVFilterLink *link)
533 {
534 804176 FilterLinkInternal * const li = ff_link_internal(link);
535 804176 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 804176 li->frame_blocked_in = 1;
540
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 802129 times.
804176 if (link->srcpad->request_frame)
541 2047 ret = link->srcpad->request_frame(link);
542
1/2
✓ Branch 0 taken 802129 times.
✗ Branch 1 not taken.
802129 else if (link->src->inputs[0])
543 802129 ret = ff_request_frame(link->src->inputs[0]);
544
2/2
✓ Branch 0 taken 6047 times.
✓ Branch 1 taken 798129 times.
804176 if (ret < 0) {
545
2/4
✓ Branch 0 taken 6047 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6047 times.
✗ Branch 3 not taken.
6047 if (ret != AVERROR(EAGAIN) && ret != li->status_in)
546 6047 ff_avfilter_link_set_in_status(link, ret, guess_status_pts(link->src, ret, link->time_base));
547
1/2
✓ Branch 0 taken 6047 times.
✗ Branch 1 not taken.
6047 if (ret == AVERROR_EOF)
548 6047 ret = 0;
549 }
550 804176 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 14958 unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output)
632 {
633
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14958 times.
14958 return is_output ? fffilter(filter)->nb_outputs : fffilter(filter)->nb_inputs;
634 }
635
636 542 static const char *default_filter_name(void *filter_ctx)
637 {
638 542 AVFilterContext *ctx = filter_ctx;
639
1/2
✓ Branch 0 taken 542 times.
✗ Branch 1 not taken.
542 return ctx->name ? ctx->name : ctx->filter->name;
640 }
641
642 57030 static void *filter_child_next(void *obj, void *prev)
643 {
644 57030 AVFilterContext *ctx = obj;
645
5/8
✓ Branch 0 taken 57024 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 57024 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 57024 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 57024 times.
✗ Branch 7 not taken.
57030 if (!prev && ctx->filter && ctx->filter->priv_class && ctx->priv)
646 57024 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 63797 AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name)
702 {
703 FFFilterContext *ctx;
704 AVFilterContext *ret;
705 63797 const FFFilter *const fi = fffilter(filter);
706 63797 int preinited = 0;
707
708
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63797 times.
63797 if (!filter)
709 return NULL;
710
711 63797 ctx = av_mallocz(sizeof(*ctx));
712
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63797 times.
63797 if (!ctx)
713 return NULL;
714 63797 ret = &ctx->p;
715
716 63797 ret->av_class = &avfilter_class;
717 63797 ret->filter = filter;
718
1/2
✓ Branch 0 taken 63797 times.
✗ Branch 1 not taken.
63797 ret->name = inst_name ? av_strdup(inst_name) : NULL;
719
2/2
✓ Branch 0 taken 56964 times.
✓ Branch 1 taken 6833 times.
63797 if (fi->priv_size) {
720 56964 ret->priv = av_mallocz(fi->priv_size);
721
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56964 times.
56964 if (!ret->priv)
722 goto err;
723 }
724
2/2
✓ Branch 0 taken 13666 times.
✓ Branch 1 taken 50131 times.
63797 if (fi->preinit) {
725
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13666 times.
13666 if (fi->preinit(ret) < 0)
726 goto err;
727 13666 preinited = 1;
728 }
729
730 63797 av_opt_set_defaults(ret);
731
2/2
✓ Branch 0 taken 55705 times.
✓ Branch 1 taken 8092 times.
63797 if (filter->priv_class) {
732 55705 *(const AVClass**)ret->priv = filter->priv_class;
733 55705 av_opt_set_defaults(ret->priv);
734 }
735
736 63797 ctx->execute = default_execute;
737
738 63797 ret->nb_inputs = fi->nb_inputs;
739
2/2
✓ Branch 0 taken 54065 times.
✓ Branch 1 taken 9732 times.
63797 if (ret->nb_inputs ) {
740 54065 ret->input_pads = av_memdup(filter->inputs, ret->nb_inputs * sizeof(*filter->inputs));
741
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54065 times.
54065 if (!ret->input_pads)
742 goto err;
743 54065 ret->inputs = av_calloc(ret->nb_inputs, sizeof(*ret->inputs));
744
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54065 times.
54065 if (!ret->inputs)
745 goto err;
746 }
747
748 63797 ret->nb_outputs = fi->nb_outputs;
749
2/2
✓ Branch 0 taken 55368 times.
✓ Branch 1 taken 8429 times.
63797 if (ret->nb_outputs) {
750 55368 ret->output_pads = av_memdup(filter->outputs, ret->nb_outputs * sizeof(*filter->outputs));
751
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55368 times.
55368 if (!ret->output_pads)
752 goto err;
753 55368 ret->outputs = av_calloc(ret->nb_outputs, sizeof(*ret->outputs));
754
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55368 times.
55368 if (!ret->outputs)
755 goto err;
756 }
757
758 63797 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 110103 static void free_link(AVFilterLink *link)
775 {
776
2/2
✓ Branch 0 taken 62617 times.
✓ Branch 1 taken 47486 times.
110103 if (!link)
777 62617 return;
778
779
2/2
✓ Branch 0 taken 47354 times.
✓ Branch 1 taken 132 times.
47486 if (link->src)
780 47354 link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
781
2/2
✓ Branch 0 taken 47354 times.
✓ Branch 1 taken 132 times.
47486 if (link->dst)
782 47354 link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
783
784 47486 ff_formats_unref(&link->incfg.formats);
785 47486 ff_formats_unref(&link->outcfg.formats);
786 47486 ff_formats_unref(&link->incfg.color_spaces);
787 47486 ff_formats_unref(&link->outcfg.color_spaces);
788 47486 ff_formats_unref(&link->incfg.color_ranges);
789 47486 ff_formats_unref(&link->outcfg.color_ranges);
790 47486 ff_formats_unref(&link->incfg.alpha_modes);
791 47486 ff_formats_unref(&link->outcfg.alpha_modes);
792 47486 ff_formats_unref(&link->incfg.samplerates);
793 47486 ff_formats_unref(&link->outcfg.samplerates);
794 47486 ff_channel_layouts_unref(&link->incfg.channel_layouts);
795 47486 ff_channel_layouts_unref(&link->outcfg.channel_layouts);
796 47486 link_free(&link);
797 }
798
799 63797 void avfilter_free(AVFilterContext *filter)
800 {
801 FFFilterContext *ctxi;
802 int i;
803
804
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63797 times.
63797 if (!filter)
805 return;
806 63797 ctxi = fffilterctx(filter);
807
808
1/2
✓ Branch 0 taken 63797 times.
✗ Branch 1 not taken.
63797 if (filter->graph)
809 63797 ff_filter_graph_remove_filter(filter->graph, filter);
810
811
2/2
✓ Branch 1 taken 49626 times.
✓ Branch 2 taken 14171 times.
63797 if (fffilter(filter->filter)->uninit)
812 49626 fffilter(filter->filter)->uninit(filter);
813
814
2/2
✓ Branch 0 taken 54444 times.
✓ Branch 1 taken 63797 times.
118241 for (i = 0; i < filter->nb_inputs; i++) {
815 54444 free_link(filter->inputs[i]);
816
2/2
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 54180 times.
54444 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 55659 times.
✓ Branch 1 taken 63797 times.
119456 for (i = 0; i < filter->nb_outputs; i++) {
820 55659 free_link(filter->outputs[i]);
821
2/2
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 55377 times.
55659 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 55705 times.
✓ Branch 1 taken 8092 times.
63797 if (filter->filter->priv_class)
826 55705 av_opt_free(filter->priv);
827
828 63797 av_buffer_unref(&filter->hw_device_ctx);
829
830 63797 av_freep(&filter->name);
831 63797 av_freep(&filter->input_pads);
832 63797 av_freep(&filter->output_pads);
833 63797 av_freep(&filter->inputs);
834 63797 av_freep(&filter->outputs);
835 63797 av_freep(&filter->priv);
836
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63797 times.
63797 while (ctxi->command_queue)
837 command_queue_pop(filter);
838 63797 av_opt_free(filter);
839 63797 av_expr_free(ctxi->enable);
840 63797 ctxi->enable = NULL;
841 63797 av_freep(&ctxi->var_values);
842 63797 av_free(filter);
843 }
844
845 19273 int ff_filter_get_nb_threads(AVFilterContext *ctx)
846 {
847
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19273 times.
19273 if (ctx->nb_threads > 0)
848 return FFMIN(ctx->nb_threads, ctx->graph->nb_threads);
849 19273 return ctx->graph->nb_threads;
850 }
851
852 34171 int ff_filter_opt_parse(void *logctx, const AVClass *priv_class,
853 AVDictionary **options, const char *args)
854 {
855 34171 const AVOption *o = NULL;
856 int ret;
857 34171 int offset= -1;
858
859
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34171 times.
34171 if (!args)
860 return 0;
861
862
2/2
✓ Branch 0 taken 58814 times.
✓ Branch 1 taken 34171 times.
92985 while (*args) {
863 char *parsed_key, *value;
864 const char *key;
865 58814 const char *shorthand = NULL;
866 58814 int additional_flags = 0;
867
868
4/4
✓ Branch 0 taken 45716 times.
✓ Branch 1 taken 13098 times.
✓ Branch 3 taken 44434 times.
✓ Branch 4 taken 1282 times.
58814 if (priv_class && (o = av_opt_next(&priv_class, o))) {
869
4/4
✓ Branch 0 taken 42664 times.
✓ Branch 1 taken 1770 times.
✓ Branch 2 taken 4558 times.
✓ Branch 3 taken 38106 times.
44434 if (o->type == AV_OPT_TYPE_CONST || o->offset == offset)
870 6328 continue;
871 38106 offset = o->offset;
872 38106 shorthand = o->name;
873 }
874
875 52486 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 52486 times.
52486 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 27266 times.
✓ Branch 1 taken 25220 times.
52486 if (*args)
887 27266 args++;
888
2/2
✓ Branch 0 taken 31494 times.
✓ Branch 1 taken 20992 times.
52486 if (parsed_key) {
889 31494 key = parsed_key;
890 31494 additional_flags = AV_DICT_DONT_STRDUP_KEY;
891 31494 priv_class = NULL; /* reject all remaining shorthand */
892 } else {
893 20992 key = shorthand;
894 }
895
896 52486 av_log(logctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
897
898 52486 av_dict_set(options, key, value,
899 additional_flags | AV_DICT_DONT_STRDUP_VAL | AV_DICT_MULTIKEY);
900 }
901
902 34171 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 63797 int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options)
919 {
920 63797 FFFilterContext *ctxi = fffilterctx(ctx);
921 63797 int ret = 0;
922
923
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63797 times.
63797 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 63797 ret = av_opt_set_dict2(ctx, options, AV_OPT_SEARCH_CHILDREN);
929
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63797 times.
63797 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 62553 times.
63797 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 63644 ctx->thread_type = 0;
941 }
942
943
2/2
✓ Branch 1 taken 50444 times.
✓ Branch 2 taken 13353 times.
63797 if (fffilter(ctx->filter)->init)
944 50444 ret = fffilter(ctx->filter)->init(ctx);
945
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63797 times.
63797 if (ret < 0)
946 return ret;
947
948
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 63791 times.
63797 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 63797 ctxi->state_flags |= AV_CLASS_STATE_INITIALIZED;
955
956 63797 return 0;
957 }
958
959 20875 int avfilter_init_str(AVFilterContext *filter, const char *args)
960 {
961 20875 AVDictionary *options = NULL;
962 const AVDictionaryEntry *e;
963 20875 int ret = 0;
964
965
3/4
✓ Branch 0 taken 10428 times.
✓ Branch 1 taken 10447 times.
✓ Branch 2 taken 10428 times.
✗ Branch 3 not taken.
20875 if (args && *args) {
966 10428 ret = ff_filter_opt_parse(filter, filter->filter->priv_class, &options, args);
967
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10428 times.
10428 if (ret < 0)
968 goto fail;
969 }
970
971 20875 ret = avfilter_init_dict(filter, &options);
972
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20875 times.
20875 if (ret < 0)
973 goto fail;
974
975
1/2
✓ Branch 1 taken 20875 times.
✗ Branch 2 not taken.
20875 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 20875 fail:
982 20875 av_dict_free(&options);
983
984 20875 return ret;
985 }
986
987 15227 const char *avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx)
988 {
989 15227 return pads[pad_idx].name;
990 }
991
992 30794 enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx)
993 {
994 30794 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 782962 static int default_filter_frame(AVFilterLink *link, AVFrame *frame)
1007 {
1008 782962 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 2482445 static int evaluate_timeline_at_frame(AVFilterLink *link, const AVFrame *frame)
1018 {
1019 2482445 FilterLink *l = ff_filter_link(link);
1020 2482445 AVFilterContext *dstctx = link->dst;
1021 2482445 FFFilterContext *dsti = fffilterctx(dstctx);
1022 2482445 int64_t pts = frame->pts;
1023
1024
2/2
✓ Branch 0 taken 2482247 times.
✓ Branch 1 taken 198 times.
2482445 if (!dstctx->enable_str)
1025 2482247 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 803303 static int filter_frame_framed(AVFilterLink *link, AVFrame *frame)
1036 {
1037 803303 FilterLink *l = ff_filter_link(link);
1038 int (*filter_frame)(AVFilterLink *, AVFrame *);
1039 803303 AVFilterContext *dstctx = link->dst;
1040 803303 AVFilterPad *dst = link->dstpad;
1041 int ret;
1042
1043
2/2
✓ Branch 0 taken 782953 times.
✓ Branch 1 taken 20350 times.
803303 if (!(filter_frame = dst->filter_frame))
1044 782953 filter_frame = default_filter_frame;
1045
1046
2/2
✓ Branch 0 taken 2993 times.
✓ Branch 1 taken 800310 times.
803303 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 803303 ff_inlink_process_commands(link, frame);
1053 803303 dstctx->is_disabled = !evaluate_timeline_at_frame(link, frame);
1054
1055
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 803284 times.
803303 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 803303 ret = filter_frame(link, frame);
1059 803303 l->frame_count_out++;
1060 803303 return ret;
1061
1062 fail:
1063 av_frame_free(&frame);
1064 return ret;
1065 }
1066
1067 1684401 int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
1068 {
1069 1684401 FilterLinkInternal * const li = ff_link_internal(link);
1070 int ret;
1071 1684401 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 584821 times.
✓ Branch 1 taken 1099580 times.
1684401 if (link->type == AVMEDIA_TYPE_VIDEO) {
1075
2/2
✓ Branch 0 taken 435158 times.
✓ Branch 1 taken 149663 times.
584821 if (strcmp(link->dst->filter->name, "buffersink") &&
1076
2/2
✓ Branch 0 taken 259178 times.
✓ Branch 1 taken 175980 times.
435158 strcmp(link->dst->filter->name, "format") &&
1077
2/2
✓ Branch 0 taken 259151 times.
✓ Branch 1 taken 27 times.
259178 strcmp(link->dst->filter->name, "idet") &&
1078
2/2
✓ Branch 0 taken 167877 times.
✓ Branch 1 taken 91274 times.
259151 strcmp(link->dst->filter->name, "null") &&
1079
2/2
✓ Branch 0 taken 57451 times.
✓ Branch 1 taken 110426 times.
167877 strcmp(link->dst->filter->name, "scale") &&
1080
1/2
✓ Branch 0 taken 57451 times.
✗ Branch 1 not taken.
57451 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 57451 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 1099580 times.
1099580 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 1099580 times.
1099580 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 1099580 times.
1099580 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 1099580 frame->duration = av_rescale_q(frame->nb_samples, (AVRational){ 1, frame->sample_rate },
1102 link->time_base);
1103 }
1104
1105 1684401 li->frame_blocked_in = li->frame_wanted_out = 0;
1106 1684401 li->l.frame_count_in++;
1107 1684401 li->l.sample_count_in += frame->nb_samples;
1108 1684401 filter_unblock(link->dst);
1109 1684401 ret = ff_framequeue_add(&li->fifo, frame);
1110
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1684401 times.
1684401 if (ret < 0) {
1111 av_frame_free(&frame);
1112 return ret;
1113 }
1114 1684401 ff_filter_set_ready(link->dst, 300);
1115 1684401 return 0;
1116
1117 error:
1118 av_frame_free(&frame);
1119 return AVERROR_PATCHWELCOME;
1120 }
1121
1122 2405433 static int samples_ready(FilterLinkInternal *link, unsigned min)
1123 {
1124
2/2
✓ Branch 1 taken 803437 times.
✓ Branch 2 taken 1601996 times.
3208870 return ff_framequeue_queued_frames(&link->fifo) &&
1125
2/2
✓ Branch 1 taken 135 times.
✓ Branch 2 taken 803302 times.
803437 (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 1027 times.
✓ Branch 5 taken 277 times.
2933 if (!li->fifo.samples_skipped && frame->nb_samples >= min && frame->nb_samples <= max) {
1143 1027 *rframe = ff_framequeue_take(&li->fifo);
1144 1027 return 0;
1145 }
1146 1906 nb_frames = 0;
1147 1906 nb_samples = 0;
1148 while (1) {
1149
2/2
✓ Branch 0 taken 1520 times.
✓ Branch 1 taken 1461 times.
2981 if (nb_samples + frame->nb_samples > max) {
1150
2/2
✓ Branch 0 taken 1519 times.
✓ Branch 1 taken 1 times.
1520 if (nb_samples < min)
1151 1519 nb_samples = max;
1152 1520 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 1906 buf = ff_get_audio_buffer(link, nb_samples);
1162
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1906 times.
1906 if (!buf)
1163 return AVERROR(ENOMEM);
1164 1906 ret = av_frame_copy_props(buf, frame0);
1165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1906 times.
1906 if (ret < 0) {
1166 av_frame_free(&buf);
1167 return ret;
1168 }
1169
1170 1906 p = 0;
1171
2/2
✓ Branch 0 taken 1461 times.
✓ Branch 1 taken 1906 times.
3367 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 1519 times.
✓ Branch 1 taken 387 times.
1906 if (p < nb_samples) {
1179 1519 unsigned n = nb_samples - p;
1180 1519 frame = ff_framequeue_peek(&li->fifo, 0);
1181 1519 av_samples_copy(buf->extended_data, frame->extended_data, p, 0, n,
1182 1519 link->ch_layout.nb_channels, link->format);
1183 1519 ff_framequeue_skip_samples(&li->fifo, n, link->time_base);
1184 }
1185
1186 1906 *rframe = buf;
1187 1906 return 0;
1188 }
1189
1190 803303 static int filter_frame_to_filter(AVFilterLink *link)
1191 {
1192 803303 FilterLinkInternal * const li = ff_link_internal(link);
1193 803303 AVFrame *frame = NULL;
1194 803303 AVFilterContext *dst = link->dst;
1195 int ret;
1196
1197 av_assert1(ff_framequeue_queued_frames(&li->fifo));
1198 1606606 ret = li->l.min_samples ?
1199
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 803267 times.
803303 ff_inlink_consume_samples(link, li->l.min_samples, li->l.max_samples, &frame) :
1200 803267 ff_inlink_consume_frame(link, &frame);
1201 av_assert1(ret);
1202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 803303 times.
803303 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 803303 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 803303 li->l.frame_count_out--;
1212 803303 ret = filter_frame_framed(link, frame);
1213
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 803303 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
803303 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 803303 ff_filter_set_ready(dst, 300);
1219 }
1220 803303 return ret;
1221 }
1222
1223 6053 static int forward_status_change(AVFilterContext *filter, FilterLinkInternal *li_in)
1224 {
1225 6053 AVFilterLink *in = &li_in->l.pub;
1226 6053 unsigned out = 0, progress = 0;
1227 int ret;
1228
1229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6053 times.
6053 av_assert0(!li_in->status_out);
1230
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6052 times.
6053 if (!filter->nb_outputs) {
1231 /* not necessary with the current API and sinks */
1232 1 return 0;
1233 }
1234
2/2
✓ Branch 0 taken 6052 times.
✓ Branch 1 taken 6052 times.
12104 while (!li_in->status_out) {
1235 6052 FilterLinkInternal *li_out = ff_link_internal(filter->outputs[out]);
1236
1237
1/2
✓ Branch 0 taken 6052 times.
✗ Branch 1 not taken.
6052 if (!li_out->status_in) {
1238 6052 progress++;
1239 6052 ret = request_frame_to_filter(filter->outputs[out]);
1240
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6052 times.
6052 if (ret < 0)
1241 return ret;
1242 }
1243
1/2
✓ Branch 0 taken 6052 times.
✗ Branch 1 not taken.
6052 if (++out == filter->nb_outputs) {
1244
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6052 times.
6052 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 6052 progress = 0;
1251 6052 out = 0;
1252 }
1253 }
1254 6052 ff_filter_set_ready(filter, 200);
1255 6052 return 0;
1256 }
1257
1258 2412618 static int filter_activate_default(AVFilterContext *filter)
1259 {
1260 unsigned i;
1261 2412618 int nb_eofs = 0;
1262
1263
2/2
✓ Branch 0 taken 2412581 times.
✓ Branch 1 taken 2412618 times.
4825199 for (i = 0; i < filter->nb_outputs; i++)
1264 2412581 nb_eofs += ff_outlink_get_status(filter->outputs[i]) == AVERROR_EOF;
1265
4/4
✓ Branch 0 taken 2412581 times.
✓ Branch 1 taken 37 times.
✓ Branch 2 taken 6916 times.
✓ Branch 3 taken 2405665 times.
2412618 if (filter->nb_outputs && nb_eofs == filter->nb_outputs) {
1266
2/2
✓ Branch 0 taken 6916 times.
✓ Branch 1 taken 6916 times.
13832 for (int j = 0; j < filter->nb_inputs; j++)
1267 6916 ff_inlink_set_status(filter->inputs[j], AVERROR_EOF);
1268 6916 return 0;
1269 }
1270
1271
2/2
✓ Branch 0 taken 2405433 times.
✓ Branch 1 taken 1602399 times.
4007832 for (i = 0; i < filter->nb_inputs; i++) {
1272 2405433 FilterLinkInternal *li = ff_link_internal(filter->inputs[i]);
1273
2/2
✓ Branch 1 taken 803303 times.
✓ Branch 2 taken 1602130 times.
2405433 if (samples_ready(li, li->l.min_samples)) {
1274 803303 return filter_frame_to_filter(filter->inputs[i]);
1275 }
1276 }
1277
2/2
✓ Branch 0 taken 1602130 times.
✓ Branch 1 taken 1596346 times.
3198476 for (i = 0; i < filter->nb_inputs; i++) {
1278 1602130 FilterLinkInternal * const li = ff_link_internal(filter->inputs[i]);
1279
4/4
✓ Branch 0 taken 6082 times.
✓ Branch 1 taken 1596048 times.
✓ Branch 2 taken 6053 times.
✓ Branch 3 taken 29 times.
1602130 if (li->status_in && !li->status_out) {
1280 av_assert1(!ff_framequeue_queued_frames(&li->fifo));
1281 6053 return forward_status_change(filter, li);
1282 }
1283 }
1284
2/2
✓ Branch 0 taken 1596328 times.
✓ Branch 1 taken 803081 times.
2399409 for (i = 0; i < filter->nb_outputs; i++) {
1285 1596328 FilterLinkInternal * const li = ff_link_internal(filter->outputs[i]);
1286
2/2
✓ Branch 0 taken 798124 times.
✓ Branch 1 taken 798204 times.
1596328 if (li->frame_wanted_out &&
1287
2/2
✓ Branch 0 taken 793265 times.
✓ Branch 1 taken 4859 times.
798124 !li->frame_blocked_in) {
1288 793265 return request_frame_to_filter(filter->outputs[i]);
1289 }
1290 }
1291
2/2
✓ Branch 0 taken 803063 times.
✓ Branch 1 taken 798222 times.
1601285 for (i = 0; i < filter->nb_outputs; i++) {
1292 803063 FilterLinkInternal * const li = ff_link_internal(filter->outputs[i]);
1293
2/2
✓ Branch 0 taken 4859 times.
✓ Branch 1 taken 798204 times.
803063 if (li->frame_wanted_out)
1294 4859 return request_frame_to_filter(filter->outputs[i]);
1295 }
1296
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 798204 times.
798222 if (!filter->nb_outputs) {
1297 18 ff_inlink_request_frame(filter->inputs[0]);
1298 18 return 0;
1299 }
1300 798204 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 4191378 int ff_filter_activate(AVFilterContext *filter)
1447 {
1448 4191378 FFFilterContext *ctxi = fffilterctx(filter);
1449 4191378 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 4191378 ctxi->ready = 0;
1456
2/2
✓ Branch 0 taken 1778760 times.
✓ Branch 1 taken 2412618 times.
4191378 ret = fi->activate ? fi->activate(filter) : filter_activate_default(filter);
1457
2/2
✓ Branch 0 taken 799080 times.
✓ Branch 1 taken 3392298 times.
4191378 if (ret == FFERROR_NOT_READY)
1458 799080 ret = 0;
1459 4191378 return ret;
1460 }
1461
1462 3810737 int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
1463 {
1464 3810737 FilterLinkInternal * const li = ff_link_internal(link);
1465 3810737 *rpts = li->l.current_pts;
1466
2/2
✓ Branch 1 taken 2165 times.
✓ Branch 2 taken 3808572 times.
3810737 if (ff_framequeue_queued_frames(&li->fifo))
1467 2165 return *rstatus = 0;
1468
2/2
✓ Branch 0 taken 8000 times.
✓ Branch 1 taken 3800572 times.
3808572 if (li->status_out)
1469 8000 return *rstatus = li->status_out;
1470
2/2
✓ Branch 0 taken 3792599 times.
✓ Branch 1 taken 7973 times.
3800572 if (!li->status_in)
1471 3792599 return *rstatus = 0;
1472 7973 *rstatus = li->status_out = li->status_in;
1473 7973 update_link_current_pts(li, li->status_in_pts);
1474 7973 *rpts = li->l.current_pts;
1475 7973 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 5482066 int ff_inlink_check_available_frame(AVFilterLink *link)
1485 {
1486 5482066 FilterLinkInternal * const li = ff_link_internal(link);
1487 5482066 return ff_framequeue_queued_frames(&li->fifo) > 0;
1488 }
1489
1490 8616 int ff_inlink_queued_samples(AVFilterLink *link)
1491 {
1492 8616 FilterLinkInternal * const li = ff_link_internal(link);
1493 8616 return ff_framequeue_queued_samples(&li->fifo);
1494 }
1495
1496 5019 int ff_inlink_check_available_samples(AVFilterLink *link, unsigned min)
1497 {
1498 5019 FilterLinkInternal * const li = ff_link_internal(link);
1499 5019 uint64_t samples = ff_framequeue_queued_samples(&li->fifo);
1500 av_assert1(min);
1501
6/6
✓ Branch 0 taken 2092 times.
✓ Branch 1 taken 2927 times.
✓ Branch 2 taken 65 times.
✓ Branch 3 taken 2027 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 59 times.
5019 return samples >= min || (li->status_in && samples);
1502 }
1503
1504 1681870 static void consume_update(FilterLinkInternal *li, const AVFrame *frame)
1505 {
1506 1681870 AVFilterLink *const link = &li->l.pub;
1507 1681870 update_link_current_pts(li, frame->pts);
1508 1681870 ff_inlink_process_commands(link, frame);
1509
2/2
✓ Branch 0 taken 1679142 times.
✓ Branch 1 taken 2728 times.
1681870 if (link == link->dst->inputs[0])
1510 1679142 link->dst->is_disabled = !evaluate_timeline_at_frame(link, frame);
1511 1681870 li->l.frame_count_out++;
1512 1681870 li->l.sample_count_out += frame->nb_samples;
1513 1681870 }
1514
1515 5479951 int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
1516 {
1517 5479951 FilterLinkInternal * const li = ff_link_internal(link);
1518 AVFrame *frame;
1519
1520 5479951 *rframe = NULL;
1521
2/2
✓ Branch 1 taken 3801010 times.
✓ Branch 2 taken 1678941 times.
5479951 if (!ff_inlink_check_available_frame(link))
1522 3801010 return 0;
1523
1524
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1678937 times.
1678941 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 1678937 frame = ff_framequeue_take(&li->fifo);
1530 1678937 consume_update(li, frame);
1531 1678937 *rframe = frame;
1532 1678937 return 1;
1533 }
1534
1535 5019 int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max,
1536 AVFrame **rframe)
1537 {
1538 5019 FilterLinkInternal * const li = ff_link_internal(link);
1539 AVFrame *frame;
1540 int ret;
1541
1542 av_assert1(min);
1543 5019 *rframe = NULL;
1544
2/2
✓ Branch 1 taken 2086 times.
✓ Branch 2 taken 2933 times.
5019 if (!ff_inlink_check_available_samples(link, min))
1545 2086 return 0;
1546
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2920 times.
2933 if (li->status_in)
1547
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 7 times.
13 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 5175 int ff_inlink_make_frame_writable(AVFilterLink *link, AVFrame **rframe)
1563 {
1564 5175 AVFrame *frame = *rframe;
1565 AVFrame *out;
1566 int ret;
1567
1568
2/2
✓ Branch 1 taken 2287 times.
✓ Branch 2 taken 2888 times.
5175 if (av_frame_is_writable(frame))
1569 2287 return 0;
1570 2888 av_log(link->dst, AV_LOG_DEBUG, "Copying data in avfilter.\n");
1571
1572
1/3
✓ Branch 0 taken 2888 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
2888 switch (link->type) {
1573 2888 case AVMEDIA_TYPE_VIDEO:
1574 2888 out = ff_get_video_buffer(link, link->w, link->h);
1575 2888 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 2888 times.
2888 if (!out)
1583 return AVERROR(ENOMEM);
1584
1585 2888 ret = av_frame_copy_props(out, frame);
1586
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2888 times.
2888 if (ret < 0) {
1587 av_frame_free(&out);
1588 return ret;
1589 }
1590
1591 2888 ret = av_frame_copy(out, frame);
1592
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2888 times.
2888 if (ret < 0) {
1593 av_frame_free(&out);
1594 return ret;
1595 }
1596
1597 2888 av_frame_free(&frame);
1598 2888 *rframe = out;
1599 2888 return 0;
1600 }
1601
1602 2485173 int ff_inlink_process_commands(AVFilterLink *link, const AVFrame *frame)
1603 {
1604 2485173 FFFilterContext *ctxi = fffilterctx(link->dst);
1605 2485173 AVFilterCommand *cmd = ctxi->command_queue;
1606
1607
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2485173 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2485173 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 2485173 return 0;
1616 }
1617
1618 885413 void ff_inlink_request_frame(AVFilterLink *link)
1619 {
1620 885413 av_unused FilterLinkInternal *li = ff_link_internal(link);
1621 av_assert1(!li->status_in);
1622 av_assert1(!li->status_out);
1623 885413 li->frame_wanted_out = 1;
1624 885413 ff_filter_set_ready(link->src, 100);
1625 885413 }
1626
1627 11039 void ff_inlink_set_status(AVFilterLink *link, int status)
1628 {
1629 11039 FilterLinkInternal * const li = ff_link_internal(link);
1630
2/2
✓ Branch 0 taken 8530 times.
✓ Branch 1 taken 2509 times.
11039 if (li->status_out)
1631 8530 return;
1632 2509 li->frame_wanted_out = 0;
1633 2509 li->frame_blocked_in = 0;
1634 2509 link_set_out_status(link, status, AV_NOPTS_VALUE);
1635
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 2509 times.
2521 while (ff_framequeue_queued_frames(&li->fifo)) {
1636 12 AVFrame *frame = ff_framequeue_take(&li->fifo);
1637 12 av_frame_free(&frame);
1638 }
1639
2/2
✓ Branch 0 taken 2505 times.
✓ Branch 1 taken 4 times.
2509 if (!li->status_in)
1640 2505 li->status_in = status;
1641 }
1642
1643 4116238 int ff_outlink_get_status(AVFilterLink *link)
1644 {
1645 4116238 FilterLinkInternal * const li = ff_link_internal(link);
1646 4116238 return li->status_in;
1647 }
1648
1649 1668 int ff_inoutlink_check_flow(AVFilterLink *inlink, AVFilterLink *outlink)
1650 {
1651 1668 FilterLinkInternal * const li_in = ff_link_internal(inlink);
1652
1/2
✓ Branch 1 taken 1049 times.
✗ Branch 2 not taken.
2717 return ff_outlink_frame_wanted(outlink) ||
1653
2/2
✓ Branch 0 taken 1049 times.
✓ Branch 1 taken 619 times.
2717 ff_inlink_check_available_frame(inlink) ||
1654
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 994 times.
1049 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 481135 int ff_outlink_frame_wanted(AVFilterLink *link)
1686 {
1687 481135 FilterLinkInternal * const li = ff_link_internal(link);
1688 481135 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