FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/avfilter.c
Date: 2025-08-19 23:55:23
Exec Total Coverage
Lines: 663 843 78.6%
Functions: 59 66 89.4%
Branches: 356 506 70.4%

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 1495895 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 1495895 }
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 514 static int append_pad(unsigned *count, AVFilterPad **pads,
101 AVFilterLink ***links, AVFilterPad *newpad)
102 {
103 AVFilterLink **newlinks;
104 AVFilterPad *newpads;
105 514 unsigned idx = *count;
106
107 514 newpads = av_realloc_array(*pads, idx + 1, sizeof(*newpads));
108 514 newlinks = av_realloc_array(*links, idx + 1, sizeof(*newlinks));
109
1/2
✓ Branch 0 taken 514 times.
✗ Branch 1 not taken.
514 if (newpads)
110 514 *pads = newpads;
111
1/2
✓ Branch 0 taken 514 times.
✗ Branch 1 not taken.
514 if (newlinks)
112 514 *links = newlinks;
113
2/4
✓ Branch 0 taken 514 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 514 times.
514 if (!newpads || !newlinks) {
114 if (newpad->flags & AVFILTERPAD_FLAG_FREE_NAME)
115 av_freep(&newpad->name);
116 return AVERROR(ENOMEM);
117 }
118
119 514 memcpy(*pads + idx, newpad, sizeof(AVFilterPad));
120 514 (*links)[idx] = NULL;
121
122 514 (*count)++;
123
124 514 return 0;
125 }
126
127 229 int ff_append_inpad(AVFilterContext *f, AVFilterPad *p)
128 {
129 229 return append_pad(&f->nb_inputs, &f->input_pads, &f->inputs, p);
130 }
131
132 210 int ff_append_inpad_free_name(AVFilterContext *f, AVFilterPad *p)
133 {
134 210 p->flags |= AVFILTERPAD_FLAG_FREE_NAME;
135 210 return ff_append_inpad(f, p);
136 }
137
138 285 int ff_append_outpad(AVFilterContext *f, AVFilterPad *p)
139 {
140 285 return append_pad(&f->nb_outputs, &f->output_pads, &f->outputs, p);
141 }
142
143 144 int ff_append_outpad_free_name(AVFilterContext *f, AVFilterPad *p)
144 {
145 144 p->flags |= AVFILTERPAD_FLAG_FREE_NAME;
146 144 return ff_append_outpad(f, p);
147 }
148
149 46622 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 46622 times.
46622 av_assert0(src->graph);
156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46622 times.
46622 av_assert0(dst->graph);
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46622 times.
46622 av_assert0(src->graph == dst->graph);
158
159
2/4
✓ Branch 0 taken 46622 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46622 times.
✗ Branch 3 not taken.
46622 if (src->nb_outputs <= srcpad || dst->nb_inputs <= dstpad ||
160
2/4
✓ Branch 0 taken 46622 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 46622 times.
46622 src->outputs[srcpad] || dst->inputs[dstpad])
161 return AVERROR(EINVAL);
162
163
1/2
✓ Branch 1 taken 46622 times.
✗ Branch 2 not taken.
46622 if (!(fffilterctx(src)->state_flags & AV_CLASS_STATE_INITIALIZED) ||
164
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 46622 times.
46622 !(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 46622 times.
46622 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 46622 li = av_mallocz(sizeof(*li));
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46622 times.
46622 if (!li)
179 return AVERROR(ENOMEM);
180 46622 link = &li->l.pub;
181
182 46622 src->outputs[srcpad] = dst->inputs[dstpad] = link;
183
184 46622 link->src = src;
185 46622 link->dst = dst;
186 46622 link->srcpad = &src->output_pads[srcpad];
187 46622 link->dstpad = &dst->input_pads[dstpad];
188 46622 link->type = src->output_pads[srcpad].type;
189 46622 li->l.graph = src->graph;
190 av_assert0(AV_PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1);
191 46622 link->format = -1;
192 46622 link->colorspace = AVCOL_SPC_UNSPECIFIED;
193 46622 ff_framequeue_init(&li->fifo, &fffiltergraph(src->graph)->frame_queues);
194
195 46622 return 0;
196 }
197
198 46754 static void link_free(AVFilterLink **link)
199 {
200 FilterLinkInternal *li;
201
202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46754 times.
46754 if (!*link)
203 return;
204 46754 li = ff_link_internal(*link);
205
206 46754 ff_framequeue_free(&li->fifo);
207 46754 ff_frame_pool_uninit(&li->frame_pool);
208 46754 av_channel_layout_uninit(&(*link)->ch_layout);
209 46754 av_frame_side_data_free(&(*link)->side_data, &(*link)->nb_side_data);
210
211 46754 av_buffer_unref(&li->l.hw_frames_ctx);
212
213 46754 av_freep(link);
214 }
215
216 1507204 static void update_link_current_pts(FilterLinkInternal *li, int64_t pts)
217 {
218 1507204 AVFilterLink *const link = &li->l.pub;
219
220
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1507199 times.
1507204 if (pts == AV_NOPTS_VALUE)
221 5 return;
222 1507199 li->l.current_pts = pts;
223 1507199 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 1507199 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 409735 times.
✓ Branch 3 taken 1097464 times.
1507199 if (li->l.graph && li->age_index >= 0)
226 409735 ff_avfilter_graph_update_heap(li->l.graph, li);
227 }
228
229 3731631 void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
230 {
231 3731631 FFFilterContext *ctxi = fffilterctx(filter);
232 3731631 ctxi->ready = FFMAX(ctxi->ready, priority);
233 3731631 }
234
235 /**
236 * Clear frame_blocked_in on all outputs.
237 * This is necessary whenever something changes on input.
238 */
239 2226647 static void filter_unblock(AVFilterContext *filter)
240 {
241 unsigned i;
242
243
2/2
✓ Branch 0 taken 1816908 times.
✓ Branch 1 taken 2226647 times.
4043555 for (i = 0; i < filter->nb_outputs; i++) {
244 1816908 FilterLinkInternal * const li = ff_link_internal(filter->outputs[i]);
245 1816908 li->frame_blocked_in = 0;
246 }
247 2226647 }
248
249
250 19308 void ff_avfilter_link_set_in_status(AVFilterLink *link, int status, int64_t pts)
251 {
252 19308 FilterLinkInternal * const li = ff_link_internal(link);
253
254
2/2
✓ Branch 0 taken 5508 times.
✓ Branch 1 taken 13800 times.
19308 if (li->status_in == status)
255 5508 return;
256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13800 times.
13800 av_assert0(!li->status_in);
257 13800 li->status_in = status;
258 13800 li->status_in_pts = pts;
259 13800 li->frame_wanted_out = 0;
260 13800 li->frame_blocked_in = 0;
261 13800 filter_unblock(link->dst);
262 13800 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 8365 static void link_set_out_status(AVFilterLink *link, int status, int64_t pts)
270 {
271 8365 FilterLinkInternal * const li = ff_link_internal(link);
272
273
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8365 times.
8365 av_assert0(!li->frame_wanted_out);
274
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8365 times.
8365 av_assert0(!li->status_out);
275 8365 li->status_out = status;
276
2/2
✓ Branch 0 taken 5966 times.
✓ Branch 1 taken 2399 times.
8365 if (pts != AV_NOPTS_VALUE)
277 5966 update_link_current_pts(li, pts);
278 8365 filter_unblock(link->dst);
279 8365 ff_filter_set_ready(link->src, 200);
280 8365 }
281
282 1253 int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
283 unsigned filt_srcpad_idx, unsigned filt_dstpad_idx)
284 {
285 int ret;
286 1253 unsigned dstpad_idx = link->dstpad - link->dst->input_pads;
287
288 1253 av_log(link->dst, AV_LOG_VERBOSE, "auto-inserting filter '%s' "
289 "between the filter '%s' and the filter '%s'\n",
290 1253 filt->name, link->src->name, link->dst->name);
291
292 1253 link->dst->inputs[dstpad_idx] = NULL;
293
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1253 times.
1253 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 1253 link->dst = filt;
301 1253 link->dstpad = &filt->input_pads[filt_srcpad_idx];
302 1253 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 1253 times.
✗ Branch 1 not taken.
1253 if (link->outcfg.formats)
307 1253 ff_formats_changeref(&link->outcfg.formats,
308 1253 &filt->outputs[filt_dstpad_idx]->outcfg.formats);
309
2/2
✓ Branch 0 taken 622 times.
✓ Branch 1 taken 631 times.
1253 if (link->outcfg.color_spaces)
310 622 ff_formats_changeref(&link->outcfg.color_spaces,
311 622 &filt->outputs[filt_dstpad_idx]->outcfg.color_spaces);
312
2/2
✓ Branch 0 taken 622 times.
✓ Branch 1 taken 631 times.
1253 if (link->outcfg.color_ranges)
313 622 ff_formats_changeref(&link->outcfg.color_ranges,
314 622 &filt->outputs[filt_dstpad_idx]->outcfg.color_ranges);
315
2/2
✓ Branch 0 taken 631 times.
✓ Branch 1 taken 622 times.
1253 if (link->outcfg.samplerates)
316 631 ff_formats_changeref(&link->outcfg.samplerates,
317 631 &filt->outputs[filt_dstpad_idx]->outcfg.samplerates);
318
2/2
✓ Branch 0 taken 631 times.
✓ Branch 1 taken 622 times.
1253 if (link->outcfg.channel_layouts)
319 631 ff_channel_layouts_changeref(&link->outcfg.channel_layouts,
320 631 &filt->outputs[filt_dstpad_idx]->outcfg.channel_layouts);
321
322 1253 return 0;
323 }
324
325 44646 int ff_filter_config_links(AVFilterContext *filter)
326 {
327 int (*config_link)(AVFilterLink *);
328 unsigned i;
329 int ret;
330
331
2/2
✓ Branch 0 taken 36534 times.
✓ Branch 1 taken 44646 times.
81180 for (i = 0; i < filter->nb_inputs; i ++) {
332 36534 AVFilterLink *link = filter->inputs[i];
333 AVFilterLink *inlink;
334 36534 FilterLinkInternal *li = ff_link_internal(link);
335 FilterLinkInternal *li_in;
336
337
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36534 times.
36534 if (!link) continue;
338
2/4
✓ Branch 0 taken 36534 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36534 times.
36534 if (!link->src || !link->dst) {
339 av_log(filter, AV_LOG_ERROR,
340 "Not all input and output are properly linked (%d).\n", i);
341 return AVERROR(EINVAL);
342 }
343
344
2/2
✓ Branch 0 taken 28243 times.
✓ Branch 1 taken 8291 times.
36534 inlink = link->src->nb_inputs ? link->src->inputs[0] : NULL;
345
2/2
✓ Branch 0 taken 28243 times.
✓ Branch 1 taken 8291 times.
36534 li_in = inlink ? ff_link_internal(inlink) : NULL;
346 36534 li->l.current_pts =
347 36534 li->l.current_pts_us = AV_NOPTS_VALUE;
348
349
2/4
✓ Branch 0 taken 109 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36425 times.
✗ Branch 3 not taken.
36534 switch (li->init_state) {
350 109 case AVLINK_INIT:
351 109 continue;
352 case AVLINK_STARTINIT:
353 av_log(filter, AV_LOG_INFO, "circular filter chain detected\n");
354 return 0;
355 36425 case AVLINK_UNINIT:
356 36425 li->init_state = AVLINK_STARTINIT;
357
358
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 36425 times.
36425 if ((ret = ff_filter_config_links(link->src)) < 0)
359 return ret;
360
361
2/2
✓ Branch 0 taken 19080 times.
✓ Branch 1 taken 17345 times.
36425 if (!(config_link = link->srcpad->config_props)) {
362
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19080 times.
19080 if (link->src->nb_inputs != 1) {
363 av_log(link->src, AV_LOG_ERROR, "Source filters and filters "
364 "with more than one input "
365 "must set config_props() "
366 "callbacks on all outputs\n");
367 return AVERROR(EINVAL);
368 }
369 }
370
371 /* Copy side data before link->srcpad->config_props() is called, so the filter
372 * may remove it for the next filter in the chain */
373
5/6
✓ Branch 0 taken 28166 times.
✓ Branch 1 taken 8259 times.
✓ Branch 2 taken 263 times.
✓ Branch 3 taken 27903 times.
✓ Branch 4 taken 263 times.
✗ Branch 5 not taken.
36425 if (inlink && inlink->nb_side_data && !link->nb_side_data) {
374
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 263 times.
535 for (int j = 0; j < inlink->nb_side_data; j++) {
375 272 ret = av_frame_side_data_clone(&link->side_data, &link->nb_side_data,
376 272 inlink->side_data[j], 0);
377
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 272 times.
272 if (ret < 0) {
378 av_frame_side_data_free(&link->side_data, &link->nb_side_data);
379 return ret;
380 }
381 }
382 }
383
384
3/4
✓ Branch 0 taken 17345 times.
✓ Branch 1 taken 19080 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17345 times.
36425 if (config_link && (ret = config_link(link)) < 0) {
385 av_log(link->src, AV_LOG_ERROR,
386 "Failed to configure output pad on %s\n",
387 link->src->name);
388 return ret;
389 }
390
391
2/3
✓ Branch 0 taken 30501 times.
✓ Branch 1 taken 5924 times.
✗ Branch 2 not taken.
36425 switch (link->type) {
392 30501 case AVMEDIA_TYPE_VIDEO:
393
3/4
✓ Branch 0 taken 23358 times.
✓ Branch 1 taken 7143 times.
✓ Branch 2 taken 23358 times.
✗ Branch 3 not taken.
30501 if (!link->time_base.num && !link->time_base.den)
394
1/2
✓ Branch 0 taken 23358 times.
✗ Branch 1 not taken.
23358 link->time_base = inlink ? inlink->time_base : AV_TIME_BASE_Q;
395
396
4/4
✓ Branch 0 taken 26211 times.
✓ Branch 1 taken 4290 times.
✓ Branch 2 taken 16611 times.
✓ Branch 3 taken 9600 times.
30501 if (!link->sample_aspect_ratio.num && !link->sample_aspect_ratio.den)
397 16611 link->sample_aspect_ratio = inlink ?
398
2/2
✓ Branch 0 taken 16596 times.
✓ Branch 1 taken 15 times.
16611 inlink->sample_aspect_ratio : (AVRational){1,1};
399
400
2/2
✓ Branch 0 taken 23611 times.
✓ Branch 1 taken 6890 times.
30501 if (inlink) {
401
3/4
✓ Branch 0 taken 23401 times.
✓ Branch 1 taken 210 times.
✓ Branch 2 taken 23401 times.
✗ Branch 3 not taken.
23611 if (!li->l.frame_rate.num && !li->l.frame_rate.den)
402 23401 li->l.frame_rate = li_in->l.frame_rate;
403
2/2
✓ Branch 0 taken 16114 times.
✓ Branch 1 taken 7497 times.
23611 if (!link->w)
404 16114 link->w = inlink->w;
405
2/2
✓ Branch 0 taken 16114 times.
✓ Branch 1 taken 7497 times.
23611 if (!link->h)
406 16114 link->h = inlink->h;
407
2/4
✓ Branch 0 taken 6890 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6890 times.
6890 } else if (!link->w || !link->h) {
408 av_log(link->src, AV_LOG_ERROR,
409 "Video source filters must set their output link's "
410 "width and height\n");
411 return AVERROR(EINVAL);
412 }
413 30501 break;
414
415 5924 case AVMEDIA_TYPE_AUDIO:
416
2/2
✓ Branch 0 taken 4555 times.
✓ Branch 1 taken 1369 times.
5924 if (inlink) {
417
3/4
✓ Branch 0 taken 3054 times.
✓ Branch 1 taken 1501 times.
✓ Branch 2 taken 3054 times.
✗ Branch 3 not taken.
4555 if (!link->time_base.num && !link->time_base.den)
418 3054 link->time_base = inlink->time_base;
419 }
420
421
3/4
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 5841 times.
✓ Branch 2 taken 83 times.
✗ Branch 3 not taken.
5924 if (!link->time_base.num && !link->time_base.den)
422 83 link->time_base = (AVRational) {1, link->sample_rate};
423 }
424
425
2/2
✓ Branch 0 taken 28166 times.
✓ Branch 1 taken 8259 times.
36425 if (link->src->nb_inputs &&
426
1/2
✓ Branch 1 taken 28166 times.
✗ Branch 2 not taken.
28166 !(fffilter(link->src->filter)->flags_internal & FF_FILTER_FLAG_HWFRAME_AWARE)) {
427 28166 FilterLink *l0 = ff_filter_link(link->src->inputs[0]);
428
429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28166 times.
28166 av_assert0(!li->l.hw_frames_ctx &&
430 "should not be set by non-hwframe-aware filter");
431
432
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28166 times.
28166 if (l0->hw_frames_ctx) {
433 li->l.hw_frames_ctx = av_buffer_ref(l0->hw_frames_ctx);
434 if (!li->l.hw_frames_ctx)
435 return AVERROR(ENOMEM);
436 }
437 }
438
439
2/2
✓ Branch 0 taken 4825 times.
✓ Branch 1 taken 31600 times.
36425 if ((config_link = link->dstpad->config_props))
440
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4825 times.
4825 if ((ret = config_link(link)) < 0) {
441 av_log(link->dst, AV_LOG_ERROR,
442 "Failed to configure input pad on %s\n",
443 link->dst->name);
444 return ret;
445 }
446
447 36425 li->init_state = AVLINK_INIT;
448 }
449 }
450
451 44646 return 0;
452 }
453
454 #ifdef TRACE
455 void ff_tlog_link(void *ctx, AVFilterLink *link, int end)
456 {
457 if (link->type == AVMEDIA_TYPE_VIDEO) {
458 ff_tlog(ctx,
459 "link[%p s:%dx%d fmt:%s %s->%s]%s",
460 link, link->w, link->h,
461 av_get_pix_fmt_name(link->format),
462 link->src ? link->src->filter->name : "",
463 link->dst ? link->dst->filter->name : "",
464 end ? "\n" : "");
465 } else {
466 char buf[128];
467 av_channel_layout_describe(&link->ch_layout, buf, sizeof(buf));
468
469 ff_tlog(ctx,
470 "link[%p r:%d cl:%s fmt:%s %s->%s]%s",
471 link, (int)link->sample_rate, buf,
472 av_get_sample_fmt_name(link->format),
473 link->src ? link->src->filter->name : "",
474 link->dst ? link->dst->filter->name : "",
475 end ? "\n" : "");
476 }
477 }
478 #endif
479
480 708657 int ff_request_frame(AVFilterLink *link)
481 {
482 708657 FilterLinkInternal * const li = ff_link_internal(link);
483
484 FF_TPRINTF_START(NULL, request_frame); ff_tlog_link(NULL, link, 1);
485
486 av_assert1(!fffilter(link->dst->filter)->activate);
487
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 708648 times.
708657 if (li->status_out)
488 9 return li->status_out;
489
2/2
✓ Branch 0 taken 5967 times.
✓ Branch 1 taken 702681 times.
708648 if (li->status_in) {
490
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5967 times.
5967 if (ff_framequeue_queued_frames(&li->fifo)) {
491 av_assert1(!li->frame_wanted_out);
492 av_assert1(fffilterctx(link->dst)->ready >= 300);
493 return 0;
494 } else {
495 /* Acknowledge status change. Filters using ff_request_frame() will
496 handle the change automatically. Filters can also check the
497 status directly but none do yet. */
498 5967 link_set_out_status(link, li->status_in, li->status_in_pts);
499 5967 return li->status_out;
500 }
501 }
502 702681 li->frame_wanted_out = 1;
503 702681 ff_filter_set_ready(link->src, 100);
504 702681 return 0;
505 }
506
507 5962 static int64_t guess_status_pts(AVFilterContext *ctx, int status, AVRational link_time_base)
508 {
509 unsigned i;
510 5962 int64_t r = INT64_MAX;
511
512
2/2
✓ Branch 0 taken 5961 times.
✓ Branch 1 taken 5962 times.
11923 for (i = 0; i < ctx->nb_inputs; i++) {
513 5961 FilterLinkInternal * const li = ff_link_internal(ctx->inputs[i]);
514
1/2
✓ Branch 0 taken 5961 times.
✗ Branch 1 not taken.
5961 if (li->status_out == status)
515 5961 r = FFMIN(r, av_rescale_q(li->l.current_pts, ctx->inputs[i]->time_base, link_time_base));
516 }
517
2/2
✓ Branch 0 taken 5961 times.
✓ Branch 1 taken 1 times.
5962 if (r < INT64_MAX)
518 5961 return r;
519 1 av_log(ctx, AV_LOG_WARNING, "EOF timestamp not reliable\n");
520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 for (i = 0; i < ctx->nb_inputs; i++) {
521 FilterLinkInternal * const li = ff_link_internal(ctx->inputs[i]);
522 r = FFMIN(r, av_rescale_q(li->status_in_pts, ctx->inputs[i]->time_base, link_time_base));
523 }
524
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (r < INT64_MAX)
525 return r;
526 1 return AV_NOPTS_VALUE;
527 }
528
529 708970 static int request_frame_to_filter(AVFilterLink *link)
530 {
531 708970 FilterLinkInternal * const li = ff_link_internal(link);
532 708970 int ret = -1;
533
534 FF_TPRINTF_START(NULL, request_frame_to_filter); ff_tlog_link(NULL, link, 1);
535 /* Assume the filter is blocked, let the method clear it if not */
536 708970 li->frame_blocked_in = 1;
537
2/2
✓ Branch 0 taken 2027 times.
✓ Branch 1 taken 706943 times.
708970 if (link->srcpad->request_frame)
538 2027 ret = link->srcpad->request_frame(link);
539
1/2
✓ Branch 0 taken 706943 times.
✗ Branch 1 not taken.
706943 else if (link->src->inputs[0])
540 706943 ret = ff_request_frame(link->src->inputs[0]);
541
2/2
✓ Branch 0 taken 5962 times.
✓ Branch 1 taken 703008 times.
708970 if (ret < 0) {
542
2/4
✓ Branch 0 taken 5962 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5962 times.
✗ Branch 3 not taken.
5962 if (ret != AVERROR(EAGAIN) && ret != li->status_in)
543 5962 ff_avfilter_link_set_in_status(link, ret, guess_status_pts(link->src, ret, link->time_base));
544
1/2
✓ Branch 0 taken 5962 times.
✗ Branch 1 not taken.
5962 if (ret == AVERROR_EOF)
545 5962 ret = 0;
546 }
547 708970 return ret;
548 }
549
550 static const char *const var_names[] = {
551 "t",
552 "n",
553 "w",
554 "h",
555 NULL
556 };
557
558 enum {
559 VAR_T,
560 VAR_N,
561 VAR_W,
562 VAR_H,
563 VAR_VARS_NB
564 };
565
566 6 static int set_enable_expr(FFFilterContext *ctxi, const char *expr)
567 {
568 6 AVFilterContext *ctx = &ctxi->p;
569 int ret;
570 char *expr_dup;
571 6 AVExpr *old = ctxi->enable;
572
573
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!(ctx->filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE)) {
574 av_log(ctx, AV_LOG_ERROR, "Timeline ('enable' option) not supported "
575 "with filter '%s'\n", ctx->filter->name);
576 return AVERROR_PATCHWELCOME;
577 }
578
579 6 expr_dup = av_strdup(expr);
580
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!expr_dup)
581 return AVERROR(ENOMEM);
582
583
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (!ctxi->var_values) {
584 6 ctxi->var_values = av_calloc(VAR_VARS_NB, sizeof(*ctxi->var_values));
585
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!ctxi->var_values) {
586 av_free(expr_dup);
587 return AVERROR(ENOMEM);
588 }
589 }
590
591 6 ret = av_expr_parse(&ctxi->enable, expr_dup, var_names,
592 NULL, NULL, NULL, NULL, 0, ctx->priv);
593
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ret < 0) {
594 av_log(ctx->priv, AV_LOG_ERROR,
595 "Error when evaluating the expression '%s' for enable\n",
596 expr_dup);
597 av_free(expr_dup);
598 return ret;
599 }
600
601 6 av_expr_free(old);
602 6 av_free(ctx->enable_str);
603 6 ctx->enable_str = expr_dup;
604 6 return 0;
605 }
606
607 int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags)
608 {
609 if(!strcmp(cmd, "ping")){
610 char local_res[256] = {0};
611
612 if (!res) {
613 res = local_res;
614 res_len = sizeof(local_res);
615 }
616 av_strlcatf(res, res_len, "pong from:%s %s\n", filter->filter->name, filter->name);
617 if (res == local_res)
618 av_log(filter, AV_LOG_INFO, "%s", res);
619 return 0;
620 }else if(!strcmp(cmd, "enable")) {
621 return set_enable_expr(fffilterctx(filter), arg);
622 }else if (fffilter(filter->filter)->process_command) {
623 return fffilter(filter->filter)->process_command(filter, cmd, arg, res, res_len, flags);
624 }
625 return AVERROR(ENOSYS);
626 }
627
628 14835 unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output)
629 {
630
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14835 times.
14835 return is_output ? fffilter(filter)->nb_outputs : fffilter(filter)->nb_inputs;
631 }
632
633 582 static const char *default_filter_name(void *filter_ctx)
634 {
635 582 AVFilterContext *ctx = filter_ctx;
636
1/2
✓ Branch 0 taken 582 times.
✗ Branch 1 not taken.
582 return ctx->name ? ctx->name : ctx->filter->name;
637 }
638
639 55896 static void *filter_child_next(void *obj, void *prev)
640 {
641 55896 AVFilterContext *ctx = obj;
642
5/8
✓ Branch 0 taken 55890 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 55890 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 55890 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 55890 times.
✗ Branch 7 not taken.
55896 if (!prev && ctx->filter && ctx->filter->priv_class && ctx->priv)
643 55890 return ctx->priv;
644 6 return NULL;
645 }
646
647 static const AVClass *filter_child_class_iterate(void **iter)
648 {
649 const AVFilter *f;
650
651 while ((f = av_filter_iterate(iter)))
652 if (f->priv_class)
653 return f->priv_class;
654
655 return NULL;
656 }
657
658 #define OFFSET(x) offsetof(AVFilterContext, x)
659 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM
660 #define TFLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
661 static const AVOption avfilter_options[] = {
662 { "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,
663 { .i64 = AVFILTER_THREAD_SLICE }, 0, INT_MAX, FLAGS, .unit = "thread_type" },
664 { "slice", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVFILTER_THREAD_SLICE }, .flags = FLAGS, .unit = "thread_type" },
665 { "enable", "set enable expression", OFFSET(enable_str), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = TFLAGS },
666 { "threads", "Allowed number of threads", OFFSET(nb_threads), AV_OPT_TYPE_INT,
667 { .i64 = 0 }, 0, INT_MAX, FLAGS, .unit = "threads" },
668 {"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, .flags = FLAGS, .unit = "threads"},
669 { "extra_hw_frames", "Number of extra hardware frames to allocate for the user",
670 OFFSET(extra_hw_frames), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS },
671 { NULL },
672 };
673
674 static const AVClass avfilter_class = {
675 .class_name = "AVFilter",
676 .item_name = default_filter_name,
677 .version = LIBAVUTIL_VERSION_INT,
678 .category = AV_CLASS_CATEGORY_FILTER,
679 .child_next = filter_child_next,
680 .child_class_iterate = filter_child_class_iterate,
681 .option = avfilter_options,
682 .state_flags_offset = offsetof(FFFilterContext, state_flags),
683 };
684
685 1276 static int default_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg,
686 int *ret, int nb_jobs)
687 {
688 int i;
689
690
2/2
✓ Branch 0 taken 1276 times.
✓ Branch 1 taken 1276 times.
2552 for (i = 0; i < nb_jobs; i++) {
691 1276 int r = func(ctx, arg, i, nb_jobs);
692
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1276 times.
1276 if (ret)
693 ret[i] = r;
694 }
695 1276 return 0;
696 }
697
698 62835 AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name)
699 {
700 FFFilterContext *ctx;
701 AVFilterContext *ret;
702 62835 const FFFilter *const fi = fffilter(filter);
703 62835 int preinited = 0;
704
705
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62835 times.
62835 if (!filter)
706 return NULL;
707
708 62835 ctx = av_mallocz(sizeof(*ctx));
709
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62835 times.
62835 if (!ctx)
710 return NULL;
711 62835 ret = &ctx->p;
712
713 62835 ret->av_class = &avfilter_class;
714 62835 ret->filter = filter;
715
1/2
✓ Branch 0 taken 62835 times.
✗ Branch 1 not taken.
62835 ret->name = inst_name ? av_strdup(inst_name) : NULL;
716
2/2
✓ Branch 0 taken 56094 times.
✓ Branch 1 taken 6741 times.
62835 if (fi->priv_size) {
717 56094 ret->priv = av_mallocz(fi->priv_size);
718
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56094 times.
56094 if (!ret->priv)
719 goto err;
720 }
721
2/2
✓ Branch 0 taken 13502 times.
✓ Branch 1 taken 49333 times.
62835 if (fi->preinit) {
722
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13502 times.
13502 if (fi->preinit(ret) < 0)
723 goto err;
724 13502 preinited = 1;
725 }
726
727 62835 av_opt_set_defaults(ret);
728
2/2
✓ Branch 0 taken 54837 times.
✓ Branch 1 taken 7998 times.
62835 if (filter->priv_class) {
729 54837 *(const AVClass**)ret->priv = filter->priv_class;
730 54837 av_opt_set_defaults(ret->priv);
731 }
732
733 62835 ctx->execute = default_execute;
734
735 62835 ret->nb_inputs = fi->nb_inputs;
736
2/2
✓ Branch 0 taken 53301 times.
✓ Branch 1 taken 9534 times.
62835 if (ret->nb_inputs ) {
737 53301 ret->input_pads = av_memdup(filter->inputs, ret->nb_inputs * sizeof(*filter->inputs));
738
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53301 times.
53301 if (!ret->input_pads)
739 goto err;
740 53301 ret->inputs = av_calloc(ret->nb_inputs, sizeof(*ret->inputs));
741
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53301 times.
53301 if (!ret->inputs)
742 goto err;
743 }
744
745 62835 ret->nb_outputs = fi->nb_outputs;
746
2/2
✓ Branch 0 taken 54525 times.
✓ Branch 1 taken 8310 times.
62835 if (ret->nb_outputs) {
747 54525 ret->output_pads = av_memdup(filter->outputs, ret->nb_outputs * sizeof(*filter->outputs));
748
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54525 times.
54525 if (!ret->output_pads)
749 goto err;
750 54525 ret->outputs = av_calloc(ret->nb_outputs, sizeof(*ret->outputs));
751
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54525 times.
54525 if (!ret->outputs)
752 goto err;
753 }
754
755 62835 return ret;
756
757 err:
758 if (preinited)
759 fi->uninit(ret);
760 av_freep(&ret->inputs);
761 av_freep(&ret->input_pads);
762 ret->nb_inputs = 0;
763 av_freep(&ret->outputs);
764 av_freep(&ret->output_pads);
765 ret->nb_outputs = 0;
766 av_freep(&ret->priv);
767 av_free(ret);
768 return NULL;
769 }
770
771 108434 static void free_link(AVFilterLink *link)
772 {
773
2/2
✓ Branch 0 taken 61680 times.
✓ Branch 1 taken 46754 times.
108434 if (!link)
774 61680 return;
775
776
2/2
✓ Branch 0 taken 46622 times.
✓ Branch 1 taken 132 times.
46754 if (link->src)
777 46622 link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
778
2/2
✓ Branch 0 taken 46622 times.
✓ Branch 1 taken 132 times.
46754 if (link->dst)
779 46622 link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
780
781 46754 ff_formats_unref(&link->incfg.formats);
782 46754 ff_formats_unref(&link->outcfg.formats);
783 46754 ff_formats_unref(&link->incfg.color_spaces);
784 46754 ff_formats_unref(&link->outcfg.color_spaces);
785 46754 ff_formats_unref(&link->incfg.color_ranges);
786 46754 ff_formats_unref(&link->outcfg.color_ranges);
787 46754 ff_formats_unref(&link->incfg.samplerates);
788 46754 ff_formats_unref(&link->outcfg.samplerates);
789 46754 ff_channel_layouts_unref(&link->incfg.channel_layouts);
790 46754 ff_channel_layouts_unref(&link->outcfg.channel_layouts);
791 46754 link_free(&link);
792 }
793
794 62835 void avfilter_free(AVFilterContext *filter)
795 {
796 FFFilterContext *ctxi;
797 int i;
798
799
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62835 times.
62835 if (!filter)
800 return;
801 62835 ctxi = fffilterctx(filter);
802
803
1/2
✓ Branch 0 taken 62835 times.
✗ Branch 1 not taken.
62835 if (filter->graph)
804 62835 ff_filter_graph_remove_filter(filter->graph, filter);
805
806
2/2
✓ Branch 1 taken 48860 times.
✓ Branch 2 taken 13975 times.
62835 if (fffilter(filter->filter)->uninit)
807 48860 fffilter(filter->filter)->uninit(filter);
808
809
2/2
✓ Branch 0 taken 53624 times.
✓ Branch 1 taken 62835 times.
116459 for (i = 0; i < filter->nb_inputs; i++) {
810 53624 free_link(filter->inputs[i]);
811
2/2
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 53414 times.
53624 if (filter->input_pads[i].flags & AVFILTERPAD_FLAG_FREE_NAME)
812 210 av_freep(&filter->input_pads[i].name);
813 }
814
2/2
✓ Branch 0 taken 54810 times.
✓ Branch 1 taken 62835 times.
117645 for (i = 0; i < filter->nb_outputs; i++) {
815 54810 free_link(filter->outputs[i]);
816
2/2
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 54530 times.
54810 if (filter->output_pads[i].flags & AVFILTERPAD_FLAG_FREE_NAME)
817 280 av_freep(&filter->output_pads[i].name);
818 }
819
820
2/2
✓ Branch 0 taken 54837 times.
✓ Branch 1 taken 7998 times.
62835 if (filter->filter->priv_class)
821 54837 av_opt_free(filter->priv);
822
823 62835 av_buffer_unref(&filter->hw_device_ctx);
824
825 62835 av_freep(&filter->name);
826 62835 av_freep(&filter->input_pads);
827 62835 av_freep(&filter->output_pads);
828 62835 av_freep(&filter->inputs);
829 62835 av_freep(&filter->outputs);
830 62835 av_freep(&filter->priv);
831
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62835 times.
62835 while (ctxi->command_queue)
832 command_queue_pop(filter);
833 62835 av_opt_free(filter);
834 62835 av_expr_free(ctxi->enable);
835 62835 ctxi->enable = NULL;
836 62835 av_freep(&ctxi->var_values);
837 62835 av_free(filter);
838 }
839
840 18863 int ff_filter_get_nb_threads(AVFilterContext *ctx)
841 {
842
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18863 times.
18863 if (ctx->nb_threads > 0)
843 return FFMIN(ctx->nb_threads, ctx->graph->nb_threads);
844 18863 return ctx->graph->nb_threads;
845 }
846
847 33560 int ff_filter_opt_parse(void *logctx, const AVClass *priv_class,
848 AVDictionary **options, const char *args)
849 {
850 33560 const AVOption *o = NULL;
851 int ret;
852 33560 int offset= -1;
853
854
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33560 times.
33560 if (!args)
855 return 0;
856
857
2/2
✓ Branch 0 taken 57637 times.
✓ Branch 1 taken 33560 times.
91197 while (*args) {
858 char *parsed_key, *value;
859 const char *key;
860 57637 const char *shorthand = NULL;
861 57637 int additional_flags = 0;
862
863
4/4
✓ Branch 0 taken 44915 times.
✓ Branch 1 taken 12722 times.
✓ Branch 3 taken 43633 times.
✓ Branch 4 taken 1282 times.
57637 if (priv_class && (o = av_opt_next(&priv_class, o))) {
864
4/4
✓ Branch 0 taken 41863 times.
✓ Branch 1 taken 1770 times.
✓ Branch 2 taken 4468 times.
✓ Branch 3 taken 37395 times.
43633 if (o->type == AV_OPT_TYPE_CONST || o->offset == offset)
865 6238 continue;
866 37395 offset = o->offset;
867 37395 shorthand = o->name;
868 }
869
870 51399 ret = av_opt_get_key_value(&args, "=", ":",
871 shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0,
872 &parsed_key, &value);
873
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51399 times.
51399 if (ret < 0) {
874 if (ret == AVERROR(EINVAL))
875 av_log(logctx, AV_LOG_ERROR, "No option name near '%s'\n", args);
876 else
877 av_log(logctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", args,
878 av_err2str(ret));
879 return ret;
880 }
881
2/2
✓ Branch 0 taken 26695 times.
✓ Branch 1 taken 24704 times.
51399 if (*args)
882 26695 args++;
883
2/2
✓ Branch 0 taken 30712 times.
✓ Branch 1 taken 20687 times.
51399 if (parsed_key) {
884 30712 key = parsed_key;
885 30712 additional_flags = AV_DICT_DONT_STRDUP_KEY;
886 30712 priv_class = NULL; /* reject all remaining shorthand */
887 } else {
888 20687 key = shorthand;
889 }
890
891 51399 av_log(logctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
892
893 51399 av_dict_set(options, key, value,
894 additional_flags | AV_DICT_DONT_STRDUP_VAL | AV_DICT_MULTIKEY);
895 }
896
897 33560 return 0;
898 }
899
900 int ff_filter_process_command(AVFilterContext *ctx, const char *cmd,
901 const char *arg, char *res, int res_len, int flags)
902 {
903 const AVOption *o;
904
905 if (!ctx->filter->priv_class)
906 return 0;
907 o = av_opt_find2(ctx->priv, cmd, NULL, AV_OPT_FLAG_RUNTIME_PARAM | AV_OPT_FLAG_FILTERING_PARAM, AV_OPT_SEARCH_CHILDREN, NULL);
908 if (!o)
909 return AVERROR(ENOSYS);
910 return av_opt_set(ctx->priv, cmd, arg, 0);
911 }
912
913 62835 int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options)
914 {
915 62835 FFFilterContext *ctxi = fffilterctx(ctx);
916 62835 int ret = 0;
917
918
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62835 times.
62835 if (ctxi->state_flags & AV_CLASS_STATE_INITIALIZED) {
919 av_log(ctx, AV_LOG_ERROR, "Filter already initialized\n");
920 return AVERROR(EINVAL);
921 }
922
923 62835 ret = av_opt_set_dict2(ctx, options, AV_OPT_SEARCH_CHILDREN);
924
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62835 times.
62835 if (ret < 0) {
925 av_log(ctx, AV_LOG_ERROR, "Error applying generic filter options.\n");
926 return ret;
927 }
928
929
2/2
✓ Branch 0 taken 1229 times.
✓ Branch 1 taken 61606 times.
62835 if (ctx->filter->flags & AVFILTER_FLAG_SLICE_THREADS &&
930
2/2
✓ Branch 0 taken 147 times.
✓ Branch 1 taken 1082 times.
1229 ctx->thread_type & ctx->graph->thread_type & AVFILTER_THREAD_SLICE &&
931
1/2
✓ Branch 1 taken 147 times.
✗ Branch 2 not taken.
147 fffiltergraph(ctx->graph)->thread_execute) {
932 147 ctx->thread_type = AVFILTER_THREAD_SLICE;
933 147 ctxi->execute = fffiltergraph(ctx->graph)->thread_execute;
934 } else {
935 62688 ctx->thread_type = 0;
936 }
937
938
2/2
✓ Branch 1 taken 49593 times.
✓ Branch 2 taken 13242 times.
62835 if (fffilter(ctx->filter)->init)
939 49593 ret = fffilter(ctx->filter)->init(ctx);
940
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62835 times.
62835 if (ret < 0)
941 return ret;
942
943
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 62829 times.
62835 if (ctx->enable_str) {
944 6 ret = set_enable_expr(ctxi, ctx->enable_str);
945
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ret < 0)
946 return ret;
947 }
948
949 62835 ctxi->state_flags |= AV_CLASS_STATE_INITIALIZED;
950
951 62835 return 0;
952 }
953
954 20489 int avfilter_init_str(AVFilterContext *filter, const char *args)
955 {
956 20489 AVDictionary *options = NULL;
957 const AVDictionaryEntry *e;
958 20489 int ret = 0;
959
960
3/4
✓ Branch 0 taken 10243 times.
✓ Branch 1 taken 10246 times.
✓ Branch 2 taken 10243 times.
✗ Branch 3 not taken.
20489 if (args && *args) {
961 10243 ret = ff_filter_opt_parse(filter, filter->filter->priv_class, &options, args);
962
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10243 times.
10243 if (ret < 0)
963 goto fail;
964 }
965
966 20489 ret = avfilter_init_dict(filter, &options);
967
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20489 times.
20489 if (ret < 0)
968 goto fail;
969
970
1/2
✓ Branch 1 taken 20489 times.
✗ Branch 2 not taken.
20489 if ((e = av_dict_iterate(options, NULL))) {
971 av_log(filter, AV_LOG_ERROR, "No such option: %s.\n", e->key);
972 ret = AVERROR_OPTION_NOT_FOUND;
973 goto fail;
974 }
975
976 20489 fail:
977 20489 av_dict_free(&options);
978
979 20489 return ret;
980 }
981
982 15053 const char *avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx)
983 {
984 15053 return pads[pad_idx].name;
985 }
986
987 30392 enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx)
988 {
989 30392 return pads[pad_idx].type;
990 }
991
992 AVBufferRef *avfilter_link_get_hw_frames_ctx(AVFilterLink *link)
993 {
994 FilterLink *plink = ff_filter_link(link);
995 if (plink->hw_frames_ctx)
996 return av_buffer_ref(plink->hw_frames_ctx);
997
998 return NULL;
999 }
1000
1001 689338 static int default_filter_frame(AVFilterLink *link, AVFrame *frame)
1002 {
1003 689338 return ff_filter_frame(link->dst->outputs[0], frame);
1004 }
1005
1006 /**
1007 * Evaluate the timeline expression of the link for the time and properties
1008 * of the frame.
1009 * @return >0 if enabled, 0 if disabled
1010 * @note It does not update link->dst->is_disabled.
1011 */
1012 2199603 static int evaluate_timeline_at_frame(AVFilterLink *link, const AVFrame *frame)
1013 {
1014 2199603 FilterLink *l = ff_filter_link(link);
1015 2199603 AVFilterContext *dstctx = link->dst;
1016 2199603 FFFilterContext *dsti = fffilterctx(dstctx);
1017 2199603 int64_t pts = frame->pts;
1018
1019
2/2
✓ Branch 0 taken 2199405 times.
✓ Branch 1 taken 198 times.
2199603 if (!dstctx->enable_str)
1020 2199405 return 1;
1021
1022 198 dsti->var_values[VAR_N] = l->frame_count_out;
1023
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);
1024 198 dsti->var_values[VAR_W] = link->w;
1025 198 dsti->var_values[VAR_H] = link->h;
1026
1027 198 return fabs(av_expr_eval(dsti->enable, dsti->var_values, NULL)) >= 0.5;
1028 }
1029
1030 708587 static int filter_frame_framed(AVFilterLink *link, AVFrame *frame)
1031 {
1032 708587 FilterLink *l = ff_filter_link(link);
1033 int (*filter_frame)(AVFilterLink *, AVFrame *);
1034 708587 AVFilterContext *dstctx = link->dst;
1035 708587 AVFilterPad *dst = link->dstpad;
1036 int ret;
1037
1038
2/2
✓ Branch 0 taken 689329 times.
✓ Branch 1 taken 19258 times.
708587 if (!(filter_frame = dst->filter_frame))
1039 689329 filter_frame = default_filter_frame;
1040
1041
2/2
✓ Branch 0 taken 2553 times.
✓ Branch 1 taken 706034 times.
708587 if (dst->flags & AVFILTERPAD_FLAG_NEEDS_WRITABLE) {
1042 2553 ret = ff_inlink_make_frame_writable(link, &frame);
1043
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2553 times.
2553 if (ret < 0)
1044 goto fail;
1045 }
1046
1047 708587 ff_inlink_process_commands(link, frame);
1048 708587 dstctx->is_disabled = !evaluate_timeline_at_frame(link, frame);
1049
1050
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 708568 times.
708587 if (dstctx->is_disabled &&
1051
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 10 times.
19 (dstctx->filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC))
1052 9 filter_frame = default_filter_frame;
1053 708587 ret = filter_frame(link, frame);
1054 708587 l->frame_count_out++;
1055 708587 return ret;
1056
1057 fail:
1058 av_frame_free(&frame);
1059 return ret;
1060 }
1061
1062 1495895 int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
1063 {
1064 1495895 FilterLinkInternal * const li = ff_link_internal(link);
1065 int ret;
1066 1495895 FF_TPRINTF_START(NULL, filter_frame); ff_tlog_link(NULL, link, 1); ff_tlog(NULL, " "); tlog_ref(NULL, frame, 1);
1067
1068 /* Consistency checks */
1069
2/2
✓ Branch 0 taken 567048 times.
✓ Branch 1 taken 928847 times.
1495895 if (link->type == AVMEDIA_TYPE_VIDEO) {
1070
2/2
✓ Branch 0 taken 421822 times.
✓ Branch 1 taken 145226 times.
567048 if (strcmp(link->dst->filter->name, "buffersink") &&
1071
2/2
✓ Branch 0 taken 252336 times.
✓ Branch 1 taken 169486 times.
421822 strcmp(link->dst->filter->name, "format") &&
1072
2/2
✓ Branch 0 taken 252309 times.
✓ Branch 1 taken 27 times.
252336 strcmp(link->dst->filter->name, "idet") &&
1073
2/2
✓ Branch 0 taken 162633 times.
✓ Branch 1 taken 89676 times.
252309 strcmp(link->dst->filter->name, "null") &&
1074
2/2
✓ Branch 0 taken 54634 times.
✓ Branch 1 taken 107999 times.
162633 strcmp(link->dst->filter->name, "scale") &&
1075 54634 strcmp(link->dst->filter->name, "libplacebo")) {
1076 av_assert1(frame->format == link->format);
1077 av_assert1(frame->width == link->w);
1078 av_assert1(frame->height == link->h);
1079 }
1080
1081 567048 frame->sample_aspect_ratio = link->sample_aspect_ratio;
1082 } else {
1083
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 928847 times.
928847 if (frame->format != link->format) {
1084 av_log(link->dst, AV_LOG_ERROR, "Format change is not supported\n");
1085 goto error;
1086 }
1087
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 928847 times.
928847 if (av_channel_layout_compare(&frame->ch_layout, &link->ch_layout)) {
1088 av_log(link->dst, AV_LOG_ERROR, "Channel layout change is not supported\n");
1089 goto error;
1090 }
1091
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 928847 times.
928847 if (frame->sample_rate != link->sample_rate) {
1092 av_log(link->dst, AV_LOG_ERROR, "Sample rate change is not supported\n");
1093 goto error;
1094 }
1095
1096 928847 frame->duration = av_rescale_q(frame->nb_samples, (AVRational){ 1, frame->sample_rate },
1097 link->time_base);
1098 }
1099
1100 1495895 li->frame_blocked_in = li->frame_wanted_out = 0;
1101 1495895 li->l.frame_count_in++;
1102 1495895 li->l.sample_count_in += frame->nb_samples;
1103 1495895 filter_unblock(link->dst);
1104 1495895 ret = ff_framequeue_add(&li->fifo, frame);
1105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1495895 times.
1495895 if (ret < 0) {
1106 av_frame_free(&frame);
1107 return ret;
1108 }
1109 1495895 ff_filter_set_ready(link->dst, 300);
1110 1495895 return 0;
1111
1112 error:
1113 av_frame_free(&frame);
1114 return AVERROR_PATCHWELCOME;
1115 }
1116
1117 2122120 static int samples_ready(FilterLinkInternal *link, unsigned min)
1118 {
1119
2/2
✓ Branch 1 taken 708721 times.
✓ Branch 2 taken 1413399 times.
2830841 return ff_framequeue_queued_frames(&link->fifo) &&
1120
2/2
✓ Branch 1 taken 135 times.
✓ Branch 2 taken 708586 times.
708721 (ff_framequeue_queued_samples(&link->fifo) >= min ||
1121
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 134 times.
135 link->status_in);
1122 }
1123
1124 2445 static int take_samples(FilterLinkInternal *li, unsigned min, unsigned max,
1125 AVFrame **rframe)
1126 {
1127 2445 FilterLink *l = &li->l;
1128 2445 AVFilterLink *link = &l->pub;
1129 AVFrame *frame0, *frame, *buf;
1130 unsigned nb_samples, nb_frames, i, p;
1131 int ret;
1132
1133 /* Note: this function relies on no format changes and must only be
1134 called with enough samples. */
1135 av_assert1(samples_ready(li, l->min_samples));
1136 2445 frame0 = frame = ff_framequeue_peek(&li->fifo, 0);
1137
6/6
✓ Branch 0 taken 932 times.
✓ Branch 1 taken 1513 times.
✓ Branch 2 taken 819 times.
✓ Branch 3 taken 113 times.
✓ Branch 4 taken 547 times.
✓ Branch 5 taken 272 times.
2445 if (!li->fifo.samples_skipped && frame->nb_samples >= min && frame->nb_samples <= max) {
1138 547 *rframe = ff_framequeue_take(&li->fifo);
1139 547 return 0;
1140 }
1141 1898 nb_frames = 0;
1142 1898 nb_samples = 0;
1143 while (1) {
1144
2/2
✓ Branch 0 taken 1513 times.
✓ Branch 1 taken 1416 times.
2929 if (nb_samples + frame->nb_samples > max) {
1145
1/2
✓ Branch 0 taken 1513 times.
✗ Branch 1 not taken.
1513 if (nb_samples < min)
1146 1513 nb_samples = max;
1147 1513 break;
1148 }
1149 1416 nb_samples += frame->nb_samples;
1150 1416 nb_frames++;
1151
2/2
✓ Branch 1 taken 385 times.
✓ Branch 2 taken 1031 times.
1416 if (nb_frames == ff_framequeue_queued_frames(&li->fifo))
1152 385 break;
1153 1031 frame = ff_framequeue_peek(&li->fifo, nb_frames);
1154 }
1155
1156 1898 buf = ff_get_audio_buffer(link, nb_samples);
1157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1898 times.
1898 if (!buf)
1158 return AVERROR(ENOMEM);
1159 1898 ret = av_frame_copy_props(buf, frame0);
1160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1898 times.
1898 if (ret < 0) {
1161 av_frame_free(&buf);
1162 return ret;
1163 }
1164
1165 1898 p = 0;
1166
2/2
✓ Branch 0 taken 1416 times.
✓ Branch 1 taken 1898 times.
3314 for (i = 0; i < nb_frames; i++) {
1167 1416 frame = ff_framequeue_take(&li->fifo);
1168 1416 av_samples_copy(buf->extended_data, frame->extended_data, p, 0,
1169 1416 frame->nb_samples, link->ch_layout.nb_channels, link->format);
1170 1416 p += frame->nb_samples;
1171 1416 av_frame_free(&frame);
1172 }
1173
2/2
✓ Branch 0 taken 1513 times.
✓ Branch 1 taken 385 times.
1898 if (p < nb_samples) {
1174 1513 unsigned n = nb_samples - p;
1175 1513 frame = ff_framequeue_peek(&li->fifo, 0);
1176 1513 av_samples_copy(buf->extended_data, frame->extended_data, p, 0, n,
1177 1513 link->ch_layout.nb_channels, link->format);
1178 1513 ff_framequeue_skip_samples(&li->fifo, n, link->time_base);
1179 }
1180
1181 1898 *rframe = buf;
1182 1898 return 0;
1183 }
1184
1185 708587 static int filter_frame_to_filter(AVFilterLink *link)
1186 {
1187 708587 FilterLinkInternal * const li = ff_link_internal(link);
1188 708587 AVFrame *frame = NULL;
1189 708587 AVFilterContext *dst = link->dst;
1190 int ret;
1191
1192 av_assert1(ff_framequeue_queued_frames(&li->fifo));
1193 1417174 ret = li->l.min_samples ?
1194
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 708551 times.
708587 ff_inlink_consume_samples(link, li->l.min_samples, li->l.max_samples, &frame) :
1195 708551 ff_inlink_consume_frame(link, &frame);
1196 av_assert1(ret);
1197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 708587 times.
708587 if (ret < 0) {
1198 av_assert1(!frame);
1199 return ret;
1200 }
1201 /* The filter will soon have received a new frame, that may allow it to
1202 produce one or more: unblock its outputs. */
1203 708587 filter_unblock(dst);
1204 /* AVFilterPad.filter_frame() expect frame_count_out to have the value
1205 before the frame; filter_frame_framed() will re-increment it. */
1206 708587 li->l.frame_count_out--;
1207 708587 ret = filter_frame_framed(link, frame);
1208
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 708587 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
708587 if (ret < 0 && ret != li->status_out) {
1209 link_set_out_status(link, ret, AV_NOPTS_VALUE);
1210 } else {
1211 /* Run once again, to see if several frames were available, or if
1212 the input status has also changed, or any other reason. */
1213 708587 ff_filter_set_ready(dst, 300);
1214 }
1215 708587 return ret;
1216 }
1217
1218 5967 static int forward_status_change(AVFilterContext *filter, FilterLinkInternal *li_in)
1219 {
1220 5967 AVFilterLink *in = &li_in->l.pub;
1221 5967 unsigned out = 0, progress = 0;
1222 int ret;
1223
1224
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5967 times.
5967 av_assert0(!li_in->status_out);
1225
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5966 times.
5967 if (!filter->nb_outputs) {
1226 /* not necessary with the current API and sinks */
1227 1 return 0;
1228 }
1229
2/2
✓ Branch 0 taken 5966 times.
✓ Branch 1 taken 5966 times.
11932 while (!li_in->status_out) {
1230 5966 FilterLinkInternal *li_out = ff_link_internal(filter->outputs[out]);
1231
1232
1/2
✓ Branch 0 taken 5966 times.
✗ Branch 1 not taken.
5966 if (!li_out->status_in) {
1233 5966 progress++;
1234 5966 ret = request_frame_to_filter(filter->outputs[out]);
1235
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5966 times.
5966 if (ret < 0)
1236 return ret;
1237 }
1238
1/2
✓ Branch 0 taken 5966 times.
✗ Branch 1 not taken.
5966 if (++out == filter->nb_outputs) {
1239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5966 times.
5966 if (!progress) {
1240 /* Every output already closed: input no longer interesting
1241 (example: overlay in shortest mode, other input closed). */
1242 link_set_out_status(in, li_in->status_in, li_in->status_in_pts);
1243 return 0;
1244 }
1245 5966 progress = 0;
1246 5966 out = 0;
1247 }
1248 }
1249 5966 ff_filter_set_ready(filter, 200);
1250 5966 return 0;
1251 }
1252
1253 2129189 static int filter_activate_default(AVFilterContext *filter)
1254 {
1255 unsigned i;
1256 2129189 int nb_eofs = 0;
1257
1258
2/2
✓ Branch 0 taken 2129124 times.
✓ Branch 1 taken 2129189 times.
4258313 for (i = 0; i < filter->nb_outputs; i++)
1259 2129124 nb_eofs += ff_outlink_get_status(filter->outputs[i]) == AVERROR_EOF;
1260
4/4
✓ Branch 0 taken 2129124 times.
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 2122336 times.
2129189 if (filter->nb_outputs && nb_eofs == filter->nb_outputs) {
1261
2/2
✓ Branch 0 taken 6788 times.
✓ Branch 1 taken 6788 times.
13576 for (int j = 0; j < filter->nb_inputs; j++)
1262 6788 ff_inlink_set_status(filter->inputs[j], AVERROR_EOF);
1263 6788 return 0;
1264 }
1265
1266
2/2
✓ Branch 0 taken 2122120 times.
✓ Branch 1 taken 1413814 times.
3535934 for (i = 0; i < filter->nb_inputs; i++) {
1267 2122120 FilterLinkInternal *li = ff_link_internal(filter->inputs[i]);
1268
2/2
✓ Branch 1 taken 708587 times.
✓ Branch 2 taken 1413533 times.
2122120 if (samples_ready(li, li->l.min_samples)) {
1269 708587 return filter_frame_to_filter(filter->inputs[i]);
1270 }
1271 }
1272
2/2
✓ Branch 0 taken 1413533 times.
✓ Branch 1 taken 1407847 times.
2821380 for (i = 0; i < filter->nb_inputs; i++) {
1273 1413533 FilterLinkInternal * const li = ff_link_internal(filter->inputs[i]);
1274
4/4
✓ Branch 0 taken 5996 times.
✓ Branch 1 taken 1407537 times.
✓ Branch 2 taken 5967 times.
✓ Branch 3 taken 29 times.
1413533 if (li->status_in && !li->status_out) {
1275 av_assert1(!ff_framequeue_queued_frames(&li->fifo));
1276 5967 return forward_status_change(filter, li);
1277 }
1278 }
1279
2/2
✓ Branch 0 taken 1407815 times.
✓ Branch 1 taken 709220 times.
2117035 for (i = 0; i < filter->nb_outputs; i++) {
1280 1407815 FilterLinkInternal * const li = ff_link_internal(filter->outputs[i]);
1281
2/2
✓ Branch 0 taken 703004 times.
✓ Branch 1 taken 704811 times.
1407815 if (li->frame_wanted_out &&
1282
2/2
✓ Branch 0 taken 698627 times.
✓ Branch 1 taken 4377 times.
703004 !li->frame_blocked_in) {
1283 698627 return request_frame_to_filter(filter->outputs[i]);
1284 }
1285 }
1286
2/2
✓ Branch 0 taken 709188 times.
✓ Branch 1 taken 704843 times.
1414031 for (i = 0; i < filter->nb_outputs; i++) {
1287 709188 FilterLinkInternal * const li = ff_link_internal(filter->outputs[i]);
1288
2/2
✓ Branch 0 taken 4377 times.
✓ Branch 1 taken 704811 times.
709188 if (li->frame_wanted_out)
1289 4377 return request_frame_to_filter(filter->outputs[i]);
1290 }
1291
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 704811 times.
704843 if (!filter->nb_outputs) {
1292 32 ff_inlink_request_frame(filter->inputs[0]);
1293 32 return 0;
1294 }
1295 704811 return FFERROR_NOT_READY;
1296 }
1297
1298 /*
1299 Filter scheduling and activation
1300
1301 When a filter is activated, it must:
1302 - if possible, output a frame;
1303 - else, if relevant, forward the input status change;
1304 - else, check outputs for wanted frames and forward the requests.
1305
1306 The following AVFilterLink fields are used for activation:
1307
1308 - frame_wanted_out:
1309
1310 This field indicates if a frame is needed on this input of the
1311 destination filter. A positive value indicates that a frame is needed
1312 to process queued frames or internal data or to satisfy the
1313 application; a zero value indicates that a frame is not especially
1314 needed but could be processed anyway; a negative value indicates that a
1315 frame would just be queued.
1316
1317 It is set by filters using ff_request_frame() or ff_request_no_frame(),
1318 when requested by the application through a specific API or when it is
1319 set on one of the outputs.
1320
1321 It is cleared when a frame is sent from the source using
1322 ff_filter_frame().
1323
1324 It is also cleared when a status change is sent from the source using
1325 ff_avfilter_link_set_in_status().
1326
1327 - frame_blocked_in:
1328
1329 This field means that the source filter can not generate a frame as is.
1330 Its goal is to avoid repeatedly calling the request_frame() method on
1331 the same link.
1332
1333 It is set by the framework on all outputs of a filter before activating it.
1334
1335 It is automatically cleared by ff_filter_frame().
1336
1337 It is also automatically cleared by ff_avfilter_link_set_in_status().
1338
1339 It is also cleared on all outputs (using filter_unblock()) when
1340 something happens on an input: processing a frame or changing the
1341 status.
1342
1343 - fifo:
1344
1345 Contains the frames queued on a filter input. If it contains frames and
1346 frame_wanted_out is not set, then the filter can be activated. If that
1347 result in the filter not able to use these frames, the filter must set
1348 frame_wanted_out to ask for more frames.
1349
1350 - status_in and status_in_pts:
1351
1352 Status (EOF or error code) of the link and timestamp of the status
1353 change (in link time base, same as frames) as seen from the input of
1354 the link. The status change is considered happening after the frames
1355 queued in fifo.
1356
1357 It is set by the source filter using ff_avfilter_link_set_in_status().
1358
1359 - status_out:
1360
1361 Status of the link as seen from the output of the link. The status
1362 change is considered having already happened.
1363
1364 It is set by the destination filter using
1365 link_set_out_status().
1366
1367 Filters are activated according to the ready field, set using the
1368 ff_filter_set_ready(). Eventually, a priority queue will be used.
1369 ff_filter_set_ready() is called whenever anything could cause progress to
1370 be possible. Marking a filter ready when it is not is not a problem,
1371 except for the small overhead it causes.
1372
1373 Conditions that cause a filter to be marked ready are:
1374
1375 - frames added on an input link;
1376
1377 - changes in the input or output status of an input link;
1378
1379 - requests for a frame on an output link;
1380
1381 - after any actual processing using the legacy methods (filter_frame(),
1382 and request_frame() to acknowledge status changes), to run once more
1383 and check if enough input was present for several frames.
1384
1385 Examples of scenarios to consider:
1386
1387 - buffersrc: activate if frame_wanted_out to notify the application;
1388 activate when the application adds a frame to push it immediately.
1389
1390 - testsrc: activate only if frame_wanted_out to produce and push a frame.
1391
1392 - concat (not at stitch points): can process a frame on any output.
1393 Activate if frame_wanted_out on output to forward on the corresponding
1394 input. Activate when a frame is present on input to process it
1395 immediately.
1396
1397 - framesync: needs at least one frame on each input; extra frames on the
1398 wrong input will accumulate. When a frame is first added on one input,
1399 set frame_wanted_out<0 on it to avoid getting more (would trigger
1400 testsrc) and frame_wanted_out>0 on the other to allow processing it.
1401
1402 Activation of old filters:
1403
1404 In order to activate a filter implementing the legacy filter_frame() and
1405 request_frame() methods, perform the first possible of the following
1406 actions:
1407
1408 - If an input has frames in fifo and frame_wanted_out == 0, dequeue a
1409 frame and call filter_frame().
1410
1411 Rationale: filter frames as soon as possible instead of leaving them
1412 queued; frame_wanted_out < 0 is not possible since the old API does not
1413 set it nor provides any similar feedback; frame_wanted_out > 0 happens
1414 when min_samples > 0 and there are not enough samples queued.
1415
1416 - If an input has status_in set but not status_out, try to call
1417 request_frame() on one of the outputs in the hope that it will trigger
1418 request_frame() on the input with status_in and acknowledge it. This is
1419 awkward and fragile, filters with several inputs or outputs should be
1420 updated to direct activation as soon as possible.
1421
1422 - If an output has frame_wanted_out > 0 and not frame_blocked_in, call
1423 request_frame().
1424
1425 Rationale: checking frame_blocked_in is necessary to avoid requesting
1426 repeatedly on a blocked input if another is not blocked (example:
1427 [buffersrc1][testsrc1][buffersrc2][testsrc2]concat=v=2).
1428
1429 - If an output has frame_wanted_out > 0 call request_frame().
1430
1431 Rationale: even if all inputs are blocked an activate callback should
1432 request a frame on some if its inputs if a frame is requested on any of
1433 its output.
1434
1435 - Request a frame on the input for sinks.
1436
1437 Rationale: sinks using the old api have no way to request a frame on their
1438 input, so we need to do it for them.
1439 */
1440
1441 3718743 int ff_filter_activate(AVFilterContext *filter)
1442 {
1443 3718743 FFFilterContext *ctxi = fffilterctx(filter);
1444 3718743 const FFFilter *const fi = fffilter(filter->filter);
1445 int ret;
1446
1447 /* Generic timeline support is not yet implemented but should be easy */
1448 av_assert1(!(fi->p.flags & AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC &&
1449 fi->activate));
1450 3718743 ctxi->ready = 0;
1451
2/2
✓ Branch 0 taken 1589554 times.
✓ Branch 1 taken 2129189 times.
3718743 ret = fi->activate ? fi->activate(filter) : filter_activate_default(filter);
1452
2/2
✓ Branch 0 taken 705660 times.
✓ Branch 1 taken 3013083 times.
3718743 if (ret == FFERROR_NOT_READY)
1453 705660 ret = 0;
1454 3718743 return ret;
1455 }
1456
1457 3417714 int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
1458 {
1459 3417714 FilterLinkInternal * const li = ff_link_internal(link);
1460 3417714 *rpts = li->l.current_pts;
1461
2/2
✓ Branch 1 taken 2220 times.
✓ Branch 2 taken 3415494 times.
3417714 if (ff_framequeue_queued_frames(&li->fifo))
1462 2220 return *rstatus = 0;
1463
2/2
✓ Branch 0 taken 7940 times.
✓ Branch 1 taken 3407554 times.
3415494 if (li->status_out)
1464 7940 return *rstatus = li->status_out;
1465
2/2
✓ Branch 0 taken 3399728 times.
✓ Branch 1 taken 7826 times.
3407554 if (!li->status_in)
1466 3399728 return *rstatus = 0;
1467 7826 *rstatus = li->status_out = li->status_in;
1468 7826 update_link_current_pts(li, li->status_in_pts);
1469 7826 *rpts = li->l.current_pts;
1470 7826 return 1;
1471 }
1472
1473 2094 size_t ff_inlink_queued_frames(AVFilterLink *link)
1474 {
1475 2094 FilterLinkInternal * const li = ff_link_internal(link);
1476 2094 return ff_framequeue_queued_frames(&li->fifo);
1477 }
1478
1479 4902132 int ff_inlink_check_available_frame(AVFilterLink *link)
1480 {
1481 4902132 FilterLinkInternal * const li = ff_link_internal(link);
1482 4902132 return ff_framequeue_queued_frames(&li->fifo) > 0;
1483 }
1484
1485 2335 int ff_inlink_queued_samples(AVFilterLink *link)
1486 {
1487 2335 FilterLinkInternal * const li = ff_link_internal(link);
1488 2335 return ff_framequeue_queued_samples(&li->fifo);
1489 }
1490
1491 4523 int ff_inlink_check_available_samples(AVFilterLink *link, unsigned min)
1492 {
1493 4523 FilterLinkInternal * const li = ff_link_internal(link);
1494 4523 uint64_t samples = ff_framequeue_queued_samples(&li->fifo);
1495 av_assert1(min);
1496
6/6
✓ Branch 0 taken 2084 times.
✓ Branch 1 taken 2439 times.
✓ Branch 2 taken 65 times.
✓ Branch 3 taken 2019 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 59 times.
4523 return samples >= min || (li->status_in && samples);
1497 }
1498
1499 1493412 static void consume_update(FilterLinkInternal *li, const AVFrame *frame)
1500 {
1501 1493412 AVFilterLink *const link = &li->l.pub;
1502 1493412 update_link_current_pts(li, frame->pts);
1503 1493412 ff_inlink_process_commands(link, frame);
1504
2/2
✓ Branch 0 taken 1491016 times.
✓ Branch 1 taken 2396 times.
1493412 if (link == link->dst->inputs[0])
1505 1491016 link->dst->is_disabled = !evaluate_timeline_at_frame(link, frame);
1506 1493412 li->l.frame_count_out++;
1507 1493412 li->l.sample_count_out += frame->nb_samples;
1508 1493412 }
1509
1510 4900247 int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
1511 {
1512 4900247 FilterLinkInternal * const li = ff_link_internal(link);
1513 AVFrame *frame;
1514
1515 4900247 *rframe = NULL;
1516
2/2
✓ Branch 1 taken 3409277 times.
✓ Branch 2 taken 1490970 times.
4900247 if (!ff_inlink_check_available_frame(link))
1517 3409277 return 0;
1518
1519
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1490967 times.
1490970 if (li->fifo.samples_skipped) {
1520 3 frame = ff_framequeue_peek(&li->fifo, 0);
1521 3 return ff_inlink_consume_samples(link, frame->nb_samples, frame->nb_samples, rframe);
1522 }
1523
1524 1490967 frame = ff_framequeue_take(&li->fifo);
1525 1490967 consume_update(li, frame);
1526 1490967 *rframe = frame;
1527 1490967 return 1;
1528 }
1529
1530 4523 int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max,
1531 AVFrame **rframe)
1532 {
1533 4523 FilterLinkInternal * const li = ff_link_internal(link);
1534 AVFrame *frame;
1535 int ret;
1536
1537 av_assert1(min);
1538 4523 *rframe = NULL;
1539
2/2
✓ Branch 1 taken 2078 times.
✓ Branch 2 taken 2445 times.
4523 if (!ff_inlink_check_available_samples(link, min))
1540 2078 return 0;
1541
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2437 times.
2445 if (li->status_in)
1542
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
8 min = FFMIN(min, ff_framequeue_queued_samples(&li->fifo));
1543 2445 ret = take_samples(li, min, max, &frame);
1544
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2445 times.
2445 if (ret < 0)
1545 return ret;
1546 2445 consume_update(li, frame);
1547 2445 *rframe = frame;
1548 2445 return 1;
1549 }
1550
1551 89 AVFrame *ff_inlink_peek_frame(AVFilterLink *link, size_t idx)
1552 {
1553 89 FilterLinkInternal * const li = ff_link_internal(link);
1554 89 return ff_framequeue_peek(&li->fifo, idx);
1555 }
1556
1557 4746 int ff_inlink_make_frame_writable(AVFilterLink *link, AVFrame **rframe)
1558 {
1559 4746 AVFrame *frame = *rframe;
1560 AVFrame *out;
1561 int ret;
1562
1563
2/2
✓ Branch 1 taken 2241 times.
✓ Branch 2 taken 2505 times.
4746 if (av_frame_is_writable(frame))
1564 2241 return 0;
1565 2505 av_log(link->dst, AV_LOG_DEBUG, "Copying data in avfilter.\n");
1566
1567
1/3
✓ Branch 0 taken 2505 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
2505 switch (link->type) {
1568 2505 case AVMEDIA_TYPE_VIDEO:
1569 2505 out = ff_get_video_buffer(link, link->w, link->h);
1570 2505 break;
1571 case AVMEDIA_TYPE_AUDIO:
1572 out = ff_get_audio_buffer(link, frame->nb_samples);
1573 break;
1574 default:
1575 return AVERROR(EINVAL);
1576 }
1577
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2505 times.
2505 if (!out)
1578 return AVERROR(ENOMEM);
1579
1580 2505 ret = av_frame_copy_props(out, frame);
1581
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2505 times.
2505 if (ret < 0) {
1582 av_frame_free(&out);
1583 return ret;
1584 }
1585
1586 2505 ret = av_frame_copy(out, frame);
1587
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2505 times.
2505 if (ret < 0) {
1588 av_frame_free(&out);
1589 return ret;
1590 }
1591
1592 2505 av_frame_free(&frame);
1593 2505 *rframe = out;
1594 2505 return 0;
1595 }
1596
1597 2201999 int ff_inlink_process_commands(AVFilterLink *link, const AVFrame *frame)
1598 {
1599 2201999 FFFilterContext *ctxi = fffilterctx(link->dst);
1600 2201999 AVFilterCommand *cmd = ctxi->command_queue;
1601
1602
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2201999 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2201999 while(cmd && cmd->time <= frame->pts * av_q2d(link->time_base)){
1603 av_log(link->dst, AV_LOG_DEBUG,
1604 "Processing command time:%f command:%s arg:%s\n",
1605 cmd->time, cmd->command, cmd->arg);
1606 avfilter_process_command(link->dst, cmd->command, cmd->arg, 0, 0, cmd->flags);
1607 command_queue_pop(link->dst);
1608 cmd = ctxi->command_queue;
1609 }
1610 2201999 return 0;
1611 }
1612
1613 790359 void ff_inlink_request_frame(AVFilterLink *link)
1614 {
1615 790359 av_unused FilterLinkInternal *li = ff_link_internal(link);
1616 av_assert1(!li->status_in);
1617 av_assert1(!li->status_out);
1618 790359 li->frame_wanted_out = 1;
1619 790359 ff_filter_set_ready(link->src, 100);
1620 790359 }
1621
1622 10795 void ff_inlink_set_status(AVFilterLink *link, int status)
1623 {
1624 10795 FilterLinkInternal * const li = ff_link_internal(link);
1625
2/2
✓ Branch 0 taken 8397 times.
✓ Branch 1 taken 2398 times.
10795 if (li->status_out)
1626 8397 return;
1627 2398 li->frame_wanted_out = 0;
1628 2398 li->frame_blocked_in = 0;
1629 2398 link_set_out_status(link, status, AV_NOPTS_VALUE);
1630
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2398 times.
2398 while (ff_framequeue_queued_frames(&li->fifo)) {
1631 AVFrame *frame = ff_framequeue_take(&li->fifo);
1632 av_frame_free(&frame);
1633 }
1634
2/2
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 1 times.
2398 if (!li->status_in)
1635 2397 li->status_in = status;
1636 }
1637
1638 3268941 int ff_outlink_get_status(AVFilterLink *link)
1639 {
1640 3268941 FilterLinkInternal * const li = ff_link_internal(link);
1641 3268941 return li->status_in;
1642 }
1643
1644 1478 int ff_inoutlink_check_flow(AVFilterLink *inlink, AVFilterLink *outlink)
1645 {
1646 1478 FilterLinkInternal * const li_in = ff_link_internal(inlink);
1647
1/2
✓ Branch 1 taken 887 times.
✗ Branch 2 not taken.
2365 return ff_outlink_frame_wanted(outlink) ||
1648
2/2
✓ Branch 0 taken 887 times.
✓ Branch 1 taken 591 times.
2365 ff_inlink_check_available_frame(inlink) ||
1649
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 860 times.
887 li_in->status_out;
1650 }
1651
1652
1653 const AVClass *avfilter_get_class(void)
1654 {
1655 return &avfilter_class;
1656 }
1657
1658 int ff_filter_init_hw_frames(AVFilterContext *avctx, AVFilterLink *link,
1659 int default_pool_size)
1660 {
1661 FilterLink *l = ff_filter_link(link);
1662 AVHWFramesContext *frames;
1663
1664 // Must already be set by caller.
1665 av_assert0(l->hw_frames_ctx);
1666
1667 frames = (AVHWFramesContext*)l->hw_frames_ctx->data;
1668
1669 if (frames->initial_pool_size == 0) {
1670 // Dynamic allocation is necessarily supported.
1671 } else if (avctx->extra_hw_frames >= 0) {
1672 frames->initial_pool_size += avctx->extra_hw_frames;
1673 } else {
1674 frames->initial_pool_size = default_pool_size;
1675 }
1676
1677 return 0;
1678 }
1679
1680 430835 int ff_outlink_frame_wanted(AVFilterLink *link)
1681 {
1682 430835 FilterLinkInternal * const li = ff_link_internal(link);
1683 430835 return li->frame_wanted_out;
1684 }
1685
1686 4857 int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func,
1687 void *arg, int *ret, int nb_jobs)
1688 {
1689 4857 return fffilterctx(ctx)->execute(ctx, func, arg, ret, nb_jobs);
1690 }
1691