FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/avfilter.c
Date: 2025-07-11 09:13:03
Exec Total Coverage
Lines: 660 843 78.3%
Functions: 58 66 87.9%
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 1492071 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 1492071 }
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 507 static int append_pad(unsigned *count, AVFilterPad **pads,
101 AVFilterLink ***links, AVFilterPad *newpad)
102 {
103 AVFilterLink **newlinks;
104 AVFilterPad *newpads;
105 507 unsigned idx = *count;
106
107 507 newpads = av_realloc_array(*pads, idx + 1, sizeof(*newpads));
108 507 newlinks = av_realloc_array(*links, idx + 1, sizeof(*newlinks));
109
1/2
✓ Branch 0 taken 507 times.
✗ Branch 1 not taken.
507 if (newpads)
110 507 *pads = newpads;
111
1/2
✓ Branch 0 taken 507 times.
✗ Branch 1 not taken.
507 if (newlinks)
112 507 *links = newlinks;
113
2/4
✓ Branch 0 taken 507 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 507 times.
507 if (!newpads || !newlinks) {
114 if (newpad->flags & AVFILTERPAD_FLAG_FREE_NAME)
115 av_freep(&newpad->name);
116 return AVERROR(ENOMEM);
117 }
118
119 507 memcpy(*pads + idx, newpad, sizeof(AVFilterPad));
120 507 (*links)[idx] = NULL;
121
122 507 (*count)++;
123
124 507 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 278 int ff_append_outpad(AVFilterContext *f, AVFilterPad *p)
139 {
140 278 return append_pad(&f->nb_outputs, &f->output_pads, &f->outputs, p);
141 }
142
143 137 int ff_append_outpad_free_name(AVFilterContext *f, AVFilterPad *p)
144 {
145 137 p->flags |= AVFILTERPAD_FLAG_FREE_NAME;
146 137 return ff_append_outpad(f, p);
147 }
148
149 45886 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 45886 times.
45886 av_assert0(src->graph);
156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45886 times.
45886 av_assert0(dst->graph);
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45886 times.
45886 av_assert0(src->graph == dst->graph);
158
159
2/4
✓ Branch 0 taken 45886 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45886 times.
✗ Branch 3 not taken.
45886 if (src->nb_outputs <= srcpad || dst->nb_inputs <= dstpad ||
160
2/4
✓ Branch 0 taken 45886 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45886 times.
45886 src->outputs[srcpad] || dst->inputs[dstpad])
161 return AVERROR(EINVAL);
162
163
1/2
✓ Branch 1 taken 45886 times.
✗ Branch 2 not taken.
45886 if (!(fffilterctx(src)->state_flags & AV_CLASS_STATE_INITIALIZED) ||
164
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 45886 times.
45886 !(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 45886 times.
45886 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 45886 li = av_mallocz(sizeof(*li));
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45886 times.
45886 if (!li)
179 return AVERROR(ENOMEM);
180 45886 link = &li->l.pub;
181
182 45886 src->outputs[srcpad] = dst->inputs[dstpad] = link;
183
184 45886 link->src = src;
185 45886 link->dst = dst;
186 45886 link->srcpad = &src->output_pads[srcpad];
187 45886 link->dstpad = &dst->input_pads[dstpad];
188 45886 link->type = src->output_pads[srcpad].type;
189 45886 li->l.graph = src->graph;
190 av_assert0(AV_PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1);
191 45886 link->format = -1;
192 45886 link->colorspace = AVCOL_SPC_UNSPECIFIED;
193 45886 ff_framequeue_init(&li->fifo, &fffiltergraph(src->graph)->frame_queues);
194
195 45886 return 0;
196 }
197
198 46018 static void link_free(AVFilterLink **link)
199 {
200 FilterLinkInternal *li;
201
202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46018 times.
46018 if (!*link)
203 return;
204 46018 li = ff_link_internal(*link);
205
206 46018 ff_framequeue_free(&li->fifo);
207 46018 ff_frame_pool_uninit(&li->frame_pool);
208 46018 av_channel_layout_uninit(&(*link)->ch_layout);
209 46018 av_frame_side_data_free(&(*link)->side_data, &(*link)->nb_side_data);
210
211 46018 av_buffer_unref(&li->l.hw_frames_ctx);
212
213 46018 av_freep(link);
214 }
215
216 1503436 static void update_link_current_pts(FilterLinkInternal *li, int64_t pts)
217 {
218 1503436 AVFilterLink *const link = &li->l.pub;
219
220
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1503431 times.
1503436 if (pts == AV_NOPTS_VALUE)
221 5 return;
222 1503431 li->l.current_pts = pts;
223 1503431 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 1503431 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 408044 times.
✓ Branch 3 taken 1095387 times.
1503431 if (li->l.graph && li->age_index >= 0)
226 408044 ff_avfilter_graph_update_heap(li->l.graph, li);
227 }
228
229 3723554 void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
230 {
231 3723554 FFFilterContext *ctxi = fffilterctx(filter);
232 3723554 ctxi->ready = FFMAX(ctxi->ready, priority);
233 3723554 }
234
235 /**
236 * Clear frame_blocked_in on all outputs.
237 * This is necessary whenever something changes on input.
238 */
239 2221789 static void filter_unblock(AVFilterContext *filter)
240 {
241 unsigned i;
242
243
2/2
✓ Branch 0 taken 1812786 times.
✓ Branch 1 taken 2221789 times.
4034575 for (i = 0; i < filter->nb_outputs; i++) {
244 1812786 FilterLinkInternal * const li = ff_link_internal(filter->outputs[i]);
245 1812786 li->frame_blocked_in = 0;
246 }
247 2221789 }
248
249
250 17622 void ff_avfilter_link_set_in_status(AVFilterLink *link, int status, int64_t pts)
251 {
252 17622 FilterLinkInternal * const li = ff_link_internal(link);
253
254
2/2
✓ Branch 0 taken 3858 times.
✓ Branch 1 taken 13764 times.
17622 if (li->status_in == status)
255 3858 return;
256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13764 times.
13764 av_assert0(!li->status_in);
257 13764 li->status_in = status;
258 13764 li->status_in_pts = pts;
259 13764 li->frame_wanted_out = 0;
260 13764 li->frame_blocked_in = 0;
261 13764 filter_unblock(link->dst);
262 13764 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 8353 static void link_set_out_status(AVFilterLink *link, int status, int64_t pts)
270 {
271 8353 FilterLinkInternal * const li = ff_link_internal(link);
272
273
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8353 times.
8353 av_assert0(!li->frame_wanted_out);
274
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8353 times.
8353 av_assert0(!li->status_out);
275 8353 li->status_out = status;
276
2/2
✓ Branch 0 taken 5954 times.
✓ Branch 1 taken 2399 times.
8353 if (pts != AV_NOPTS_VALUE)
277 5954 update_link_current_pts(li, pts);
278 8353 filter_unblock(link->dst);
279 8353 ff_filter_set_ready(link->src, 200);
280 8353 }
281
282 1252 int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
283 unsigned filt_srcpad_idx, unsigned filt_dstpad_idx)
284 {
285 int ret;
286 1252 unsigned dstpad_idx = link->dstpad - link->dst->input_pads;
287
288 1252 av_log(link->dst, AV_LOG_VERBOSE, "auto-inserting filter '%s' "
289 "between the filter '%s' and the filter '%s'\n",
290 1252 filt->name, link->src->name, link->dst->name);
291
292 1252 link->dst->inputs[dstpad_idx] = NULL;
293
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1252 times.
1252 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 1252 link->dst = filt;
301 1252 link->dstpad = &filt->input_pads[filt_srcpad_idx];
302 1252 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 1252 times.
✗ Branch 1 not taken.
1252 if (link->outcfg.formats)
307 1252 ff_formats_changeref(&link->outcfg.formats,
308 1252 &filt->outputs[filt_dstpad_idx]->outcfg.formats);
309
2/2
✓ Branch 0 taken 622 times.
✓ Branch 1 taken 630 times.
1252 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 630 times.
1252 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 630 times.
✓ Branch 1 taken 622 times.
1252 if (link->outcfg.samplerates)
316 630 ff_formats_changeref(&link->outcfg.samplerates,
317 630 &filt->outputs[filt_dstpad_idx]->outcfg.samplerates);
318
2/2
✓ Branch 0 taken 630 times.
✓ Branch 1 taken 622 times.
1252 if (link->outcfg.channel_layouts)
319 630 ff_channel_layouts_changeref(&link->outcfg.channel_layouts,
320 630 &filt->outputs[filt_dstpad_idx]->outcfg.channel_layouts);
321
322 1252 return 0;
323 }
324
325 43994 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 35996 times.
✓ Branch 1 taken 43994 times.
79990 for (i = 0; i < filter->nb_inputs; i ++) {
332 35996 AVFilterLink *link = filter->inputs[i];
333 AVFilterLink *inlink;
334 35996 FilterLinkInternal *li = ff_link_internal(link);
335 FilterLinkInternal *li_in;
336
337
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35996 times.
35996 if (!link) continue;
338
2/4
✓ Branch 0 taken 35996 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 35996 times.
35996 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 27821 times.
✓ Branch 1 taken 8175 times.
35996 inlink = link->src->nb_inputs ? link->src->inputs[0] : NULL;
345
2/2
✓ Branch 0 taken 27821 times.
✓ Branch 1 taken 8175 times.
35996 li_in = inlink ? ff_link_internal(inlink) : NULL;
346 35996 li->l.current_pts =
347 35996 li->l.current_pts_us = AV_NOPTS_VALUE;
348
349
2/4
✓ Branch 0 taken 107 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 35889 times.
✗ Branch 3 not taken.
35996 switch (li->init_state) {
350 107 case AVLINK_INIT:
351 107 continue;
352 case AVLINK_STARTINIT:
353 av_log(filter, AV_LOG_INFO, "circular filter chain detected\n");
354 return 0;
355 35889 case AVLINK_UNINIT:
356 35889 li->init_state = AVLINK_STARTINIT;
357
358
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 35889 times.
35889 if ((ret = ff_filter_config_links(link->src)) < 0)
359 return ret;
360
361
2/2
✓ Branch 0 taken 18801 times.
✓ Branch 1 taken 17088 times.
35889 if (!(config_link = link->srcpad->config_props)) {
362
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18801 times.
18801 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 27744 times.
✓ Branch 1 taken 8145 times.
✓ Branch 2 taken 248 times.
✓ Branch 3 taken 27496 times.
✓ Branch 4 taken 248 times.
✗ Branch 5 not taken.
35889 if (inlink && inlink->nb_side_data && !link->nb_side_data) {
374
2/2
✓ Branch 0 taken 257 times.
✓ Branch 1 taken 248 times.
505 for (int j = 0; j < inlink->nb_side_data; j++) {
375 257 ret = av_frame_side_data_clone(&link->side_data, &link->nb_side_data,
376 257 inlink->side_data[j], 0);
377
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 257 times.
257 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 17088 times.
✓ Branch 1 taken 18801 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17088 times.
35889 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 29978 times.
✓ Branch 1 taken 5911 times.
✗ Branch 2 not taken.
35889 switch (link->type) {
392 29978 case AVMEDIA_TYPE_VIDEO:
393
3/4
✓ Branch 0 taken 22945 times.
✓ Branch 1 taken 7033 times.
✓ Branch 2 taken 22945 times.
✗ Branch 3 not taken.
29978 if (!link->time_base.num && !link->time_base.den)
394
1/2
✓ Branch 0 taken 22945 times.
✗ Branch 1 not taken.
22945 link->time_base = inlink ? inlink->time_base : AV_TIME_BASE_Q;
395
396
4/4
✓ Branch 0 taken 25692 times.
✓ Branch 1 taken 4286 times.
✓ Branch 2 taken 16324 times.
✓ Branch 3 taken 9368 times.
29978 if (!link->sample_aspect_ratio.num && !link->sample_aspect_ratio.den)
397 16324 link->sample_aspect_ratio = inlink ?
398
2/2
✓ Branch 0 taken 16310 times.
✓ Branch 1 taken 14 times.
16324 inlink->sample_aspect_ratio : (AVRational){1,1};
399
400
2/2
✓ Branch 0 taken 23198 times.
✓ Branch 1 taken 6780 times.
29978 if (inlink) {
401
3/4
✓ Branch 0 taken 22988 times.
✓ Branch 1 taken 210 times.
✓ Branch 2 taken 22988 times.
✗ Branch 3 not taken.
23198 if (!li->l.frame_rate.num && !li->l.frame_rate.den)
402 22988 li->l.frame_rate = li_in->l.frame_rate;
403
2/2
✓ Branch 0 taken 15840 times.
✓ Branch 1 taken 7358 times.
23198 if (!link->w)
404 15840 link->w = inlink->w;
405
2/2
✓ Branch 0 taken 15840 times.
✓ Branch 1 taken 7358 times.
23198 if (!link->h)
406 15840 link->h = inlink->h;
407
2/4
✓ Branch 0 taken 6780 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6780 times.
6780 } 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 29978 break;
414
415 5911 case AVMEDIA_TYPE_AUDIO:
416
2/2
✓ Branch 0 taken 4546 times.
✓ Branch 1 taken 1365 times.
5911 if (inlink) {
417
3/4
✓ Branch 0 taken 3049 times.
✓ Branch 1 taken 1497 times.
✓ Branch 2 taken 3049 times.
✗ Branch 3 not taken.
4546 if (!link->time_base.num && !link->time_base.den)
418 3049 link->time_base = inlink->time_base;
419 }
420
421
3/4
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 5828 times.
✓ Branch 2 taken 83 times.
✗ Branch 3 not taken.
5911 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 27744 times.
✓ Branch 1 taken 8145 times.
35889 if (link->src->nb_inputs &&
426
1/2
✓ Branch 1 taken 27744 times.
✗ Branch 2 not taken.
27744 !(fffilter(link->src->filter)->flags_internal & FF_FILTER_FLAG_HWFRAME_AWARE)) {
427 27744 FilterLink *l0 = ff_filter_link(link->src->inputs[0]);
428
429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27744 times.
27744 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 27744 times.
27744 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 4768 times.
✓ Branch 1 taken 31121 times.
35889 if ((config_link = link->dstpad->config_props))
440
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4768 times.
4768 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 35889 li->init_state = AVLINK_INIT;
448 }
449 }
450
451 43994 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 707951 int ff_request_frame(AVFilterLink *link)
481 {
482 707951 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 707942 times.
707951 if (li->status_out)
488 9 return li->status_out;
489
2/2
✓ Branch 0 taken 5955 times.
✓ Branch 1 taken 701987 times.
707942 if (li->status_in) {
490
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5955 times.
5955 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 5955 link_set_out_status(link, li->status_in, li->status_in_pts);
499 5955 return li->status_out;
500 }
501 }
502 701987 li->frame_wanted_out = 1;
503 701987 ff_filter_set_ready(link->src, 100);
504 701987 return 0;
505 }
506
507 5950 static int64_t guess_status_pts(AVFilterContext *ctx, int status, AVRational link_time_base)
508 {
509 unsigned i;
510 5950 int64_t r = INT64_MAX;
511
512
2/2
✓ Branch 0 taken 5949 times.
✓ Branch 1 taken 5950 times.
11899 for (i = 0; i < ctx->nb_inputs; i++) {
513 5949 FilterLinkInternal * const li = ff_link_internal(ctx->inputs[i]);
514
1/2
✓ Branch 0 taken 5949 times.
✗ Branch 1 not taken.
5949 if (li->status_out == status)
515 5949 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 5949 times.
✓ Branch 1 taken 1 times.
5950 if (r < INT64_MAX)
518 5949 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 708266 static int request_frame_to_filter(AVFilterLink *link)
530 {
531 708266 FilterLinkInternal * const li = ff_link_internal(link);
532 708266 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 708266 li->frame_blocked_in = 1;
537
2/2
✓ Branch 0 taken 2018 times.
✓ Branch 1 taken 706248 times.
708266 if (link->srcpad->request_frame)
538 2018 ret = link->srcpad->request_frame(link);
539
1/2
✓ Branch 0 taken 706248 times.
✗ Branch 1 not taken.
706248 else if (link->src->inputs[0])
540 706248 ret = ff_request_frame(link->src->inputs[0]);
541
2/2
✓ Branch 0 taken 5950 times.
✓ Branch 1 taken 702316 times.
708266 if (ret < 0) {
542
2/4
✓ Branch 0 taken 5950 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5950 times.
✗ Branch 3 not taken.
5950 if (ret != AVERROR(EAGAIN) && ret != li->status_in)
543 5950 ff_avfilter_link_set_in_status(link, ret, guess_status_pts(link->src, ret, link->time_base));
544
1/2
✓ Branch 0 taken 5950 times.
✗ Branch 1 not taken.
5950 if (ret == AVERROR_EOF)
545 5950 ret = 0;
546 }
547 708266 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 14523 unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output)
629 {
630
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14523 times.
14523 return is_output ? fffilter(filter)->nb_outputs : fffilter(filter)->nb_inputs;
631 }
632
633 559 static const char *default_filter_name(void *filter_ctx)
634 {
635 559 AVFilterContext *ctx = filter_ctx;
636
1/2
✓ Branch 0 taken 559 times.
✗ Branch 1 not taken.
559 return ctx->name ? ctx->name : ctx->filter->name;
637 }
638
639 55219 static void *filter_child_next(void *obj, void *prev)
640 {
641 55219 AVFilterContext *ctx = obj;
642
5/8
✓ Branch 0 taken 55213 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 55213 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 55213 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 55213 times.
✗ Branch 7 not taken.
55219 if (!prev && ctx->filter && ctx->filter->priv_class && ctx->priv)
643 55213 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 1244 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 1244 times.
✓ Branch 1 taken 1244 times.
2488 for (i = 0; i < nb_jobs; i++) {
691 1244 int r = func(ctx, arg, i, nb_jobs);
692
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1244 times.
1244 if (ret)
693 ret[i] = r;
694 }
695 1244 return 0;
696 }
697
698 61873 AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name)
699 {
700 FFFilterContext *ctx;
701 AVFilterContext *ret;
702 61873 const FFFilter *const fi = fffilter(filter);
703 61873 int preinited = 0;
704
705
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61873 times.
61873 if (!filter)
706 return NULL;
707
708 61873 ctx = av_mallocz(sizeof(*ctx));
709
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61873 times.
61873 if (!ctx)
710 return NULL;
711 61873 ret = &ctx->p;
712
713 61873 ret->av_class = &avfilter_class;
714 61873 ret->filter = filter;
715
1/2
✓ Branch 0 taken 61873 times.
✗ Branch 1 not taken.
61873 ret->name = inst_name ? av_strdup(inst_name) : NULL;
716
2/2
✓ Branch 0 taken 55174 times.
✓ Branch 1 taken 6699 times.
61873 if (fi->priv_size) {
717 55174 ret->priv = av_mallocz(fi->priv_size);
718
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55174 times.
55174 if (!ret->priv)
719 goto err;
720 }
721
2/2
✓ Branch 0 taken 13273 times.
✓ Branch 1 taken 48600 times.
61873 if (fi->preinit) {
722
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13273 times.
13273 if (fi->preinit(ret) < 0)
723 goto err;
724 13273 preinited = 1;
725 }
726
727 61873 av_opt_set_defaults(ret);
728
2/2
✓ Branch 0 taken 53965 times.
✓ Branch 1 taken 7908 times.
61873 if (filter->priv_class) {
729 53965 *(const AVClass**)ret->priv = filter->priv_class;
730 53965 av_opt_set_defaults(ret->priv);
731 }
732
733 61873 ctx->execute = default_execute;
734
735 61873 ret->nb_inputs = fi->nb_inputs;
736
2/2
✓ Branch 0 taken 52453 times.
✓ Branch 1 taken 9420 times.
61873 if (ret->nb_inputs ) {
737 52453 ret->input_pads = av_memdup(filter->inputs, ret->nb_inputs * sizeof(*filter->inputs));
738
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52453 times.
52453 if (!ret->input_pads)
739 goto err;
740 52453 ret->inputs = av_calloc(ret->nb_inputs, sizeof(*ret->inputs));
741
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52453 times.
52453 if (!ret->inputs)
742 goto err;
743 }
744
745 61873 ret->nb_outputs = fi->nb_outputs;
746
2/2
✓ Branch 0 taken 53682 times.
✓ Branch 1 taken 8191 times.
61873 if (ret->nb_outputs) {
747 53682 ret->output_pads = av_memdup(filter->outputs, ret->nb_outputs * sizeof(*filter->outputs));
748
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53682 times.
53682 if (!ret->output_pads)
749 goto err;
750 53682 ret->outputs = av_calloc(ret->nb_outputs, sizeof(*ret->outputs));
751
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53682 times.
53682 if (!ret->outputs)
752 goto err;
753 }
754
755 61873 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 106736 static void free_link(AVFilterLink *link)
772 {
773
2/2
✓ Branch 0 taken 60718 times.
✓ Branch 1 taken 46018 times.
106736 if (!link)
774 60718 return;
775
776
2/2
✓ Branch 0 taken 45886 times.
✓ Branch 1 taken 132 times.
46018 if (link->src)
777 45886 link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
778
2/2
✓ Branch 0 taken 45886 times.
✓ Branch 1 taken 132 times.
46018 if (link->dst)
779 45886 link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
780
781 46018 ff_formats_unref(&link->incfg.formats);
782 46018 ff_formats_unref(&link->outcfg.formats);
783 46018 ff_formats_unref(&link->incfg.color_spaces);
784 46018 ff_formats_unref(&link->outcfg.color_spaces);
785 46018 ff_formats_unref(&link->incfg.color_ranges);
786 46018 ff_formats_unref(&link->outcfg.color_ranges);
787 46018 ff_formats_unref(&link->incfg.samplerates);
788 46018 ff_formats_unref(&link->outcfg.samplerates);
789 46018 ff_channel_layouts_unref(&link->incfg.channel_layouts);
790 46018 ff_channel_layouts_unref(&link->outcfg.channel_layouts);
791 46018 link_free(&link);
792 }
793
794 61873 void avfilter_free(AVFilterContext *filter)
795 {
796 FFFilterContext *ctxi;
797 int i;
798
799
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61873 times.
61873 if (!filter)
800 return;
801 61873 ctxi = fffilterctx(filter);
802
803
1/2
✓ Branch 0 taken 61873 times.
✗ Branch 1 not taken.
61873 if (filter->graph)
804 61873 ff_filter_graph_remove_filter(filter->graph, filter);
805
806
2/2
✓ Branch 1 taken 48064 times.
✓ Branch 2 taken 13809 times.
61873 if (fffilter(filter->filter)->uninit)
807 48064 fffilter(filter->filter)->uninit(filter);
808
809
2/2
✓ Branch 0 taken 52776 times.
✓ Branch 1 taken 61873 times.
114649 for (i = 0; i < filter->nb_inputs; i++) {
810 52776 free_link(filter->inputs[i]);
811
2/2
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 52566 times.
52776 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 53960 times.
✓ Branch 1 taken 61873 times.
115833 for (i = 0; i < filter->nb_outputs; i++) {
815 53960 free_link(filter->outputs[i]);
816
2/2
✓ Branch 0 taken 273 times.
✓ Branch 1 taken 53687 times.
53960 if (filter->output_pads[i].flags & AVFILTERPAD_FLAG_FREE_NAME)
817 273 av_freep(&filter->output_pads[i].name);
818 }
819
820
2/2
✓ Branch 0 taken 53965 times.
✓ Branch 1 taken 7908 times.
61873 if (filter->filter->priv_class)
821 53965 av_opt_free(filter->priv);
822
823 61873 av_buffer_unref(&filter->hw_device_ctx);
824
825 61873 av_freep(&filter->name);
826 61873 av_freep(&filter->input_pads);
827 61873 av_freep(&filter->output_pads);
828 61873 av_freep(&filter->inputs);
829 61873 av_freep(&filter->outputs);
830 61873 av_freep(&filter->priv);
831
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61873 times.
61873 while (ctxi->command_queue)
832 command_queue_pop(filter);
833 61873 av_opt_free(filter);
834 61873 av_expr_free(ctxi->enable);
835 61873 ctxi->enable = NULL;
836 61873 av_freep(&ctxi->var_values);
837 61873 av_free(filter);
838 }
839
840 18576 int ff_filter_get_nb_threads(AVFilterContext *ctx)
841 {
842
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18576 times.
18576 if (ctx->nb_threads > 0)
843 return FFMIN(ctx->nb_threads, ctx->graph->nb_threads);
844 18576 return ctx->graph->nb_threads;
845 }
846
847 33061 int ff_filter_opt_parse(void *logctx, const AVClass *priv_class,
848 AVDictionary **options, const char *args)
849 {
850 33061 const AVOption *o = NULL;
851 int ret;
852 33061 int offset= -1;
853
854
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33061 times.
33061 if (!args)
855 return 0;
856
857
2/2
✓ Branch 0 taken 57004 times.
✓ Branch 1 taken 33061 times.
90065 while (*args) {
858 char *parsed_key, *value;
859 const char *key;
860 57004 const char *shorthand = NULL;
861 57004 int additional_flags = 0;
862
863
4/4
✓ Branch 0 taken 44328 times.
✓ Branch 1 taken 12676 times.
✓ Branch 3 taken 43046 times.
✓ Branch 4 taken 1282 times.
57004 if (priv_class && (o = av_opt_next(&priv_class, o))) {
864
4/4
✓ Branch 0 taken 41276 times.
✓ Branch 1 taken 1770 times.
✓ Branch 2 taken 4404 times.
✓ Branch 3 taken 36872 times.
43046 if (o->type == AV_OPT_TYPE_CONST || o->offset == offset)
865 6174 continue;
866 36872 offset = o->offset;
867 36872 shorthand = o->name;
868 }
869
870 50830 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 50830 times.
50830 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 26454 times.
✓ Branch 1 taken 24376 times.
50830 if (*args)
882 26454 args++;
883
2/2
✓ Branch 0 taken 30520 times.
✓ Branch 1 taken 20310 times.
50830 if (parsed_key) {
884 30520 key = parsed_key;
885 30520 additional_flags = AV_DICT_DONT_STRDUP_KEY;
886 30520 priv_class = NULL; /* reject all remaining shorthand */
887 } else {
888 20310 key = shorthand;
889 }
890
891 50830 av_log(logctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
892
893 50830 av_dict_set(options, key, value,
894 additional_flags | AV_DICT_DONT_STRDUP_VAL | AV_DICT_MULTIKEY);
895 }
896
897 33061 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 61873 int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options)
914 {
915 61873 FFFilterContext *ctxi = fffilterctx(ctx);
916 61873 int ret = 0;
917
918
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61873 times.
61873 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 61873 ret = av_opt_set_dict2(ctx, options, AV_OPT_SEARCH_CHILDREN);
924
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61873 times.
61873 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 1197 times.
✓ Branch 1 taken 60676 times.
61873 if (ctx->filter->flags & AVFILTER_FLAG_SLICE_THREADS &&
930
2/2
✓ Branch 0 taken 147 times.
✓ Branch 1 taken 1050 times.
1197 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 61726 ctx->thread_type = 0;
936 }
937
938
2/2
✓ Branch 1 taken 48816 times.
✓ Branch 2 taken 13057 times.
61873 if (fffilter(ctx->filter)->init)
939 48816 ret = fffilter(ctx->filter)->init(ctx);
940
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61873 times.
61873 if (ret < 0)
941 return ret;
942
943
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 61867 times.
61873 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 61873 ctxi->state_flags |= AV_CLASS_STATE_INITIALIZED;
950
951 61873 return 0;
952 }
953
954 20261 int avfilter_init_str(AVFilterContext *filter, const char *args)
955 {
956 20261 AVDictionary *options = NULL;
957 const AVDictionaryEntry *e;
958 20261 int ret = 0;
959
960
3/4
✓ Branch 0 taken 10132 times.
✓ Branch 1 taken 10129 times.
✓ Branch 2 taken 10132 times.
✗ Branch 3 not taken.
20261 if (args && *args) {
961 10132 ret = ff_filter_opt_parse(filter, filter->filter->priv_class, &options, args);
962
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10132 times.
10132 if (ret < 0)
963 goto fail;
964 }
965
966 20261 ret = avfilter_init_dict(filter, &options);
967
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20261 times.
20261 if (ret < 0)
968 goto fail;
969
970
1/2
✓ Branch 1 taken 20261 times.
✗ Branch 2 not taken.
20261 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 20261 fail:
977 20261 av_dict_free(&options);
978
979 20261 return ret;
980 }
981
982 14830 const char *avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx)
983 {
984 14830 return pads[pad_idx].name;
985 }
986
987 29938 enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx)
988 {
989 29938 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 688563 static int default_filter_frame(AVFilterLink *link, AVFrame *frame)
1002 {
1003 688563 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 2194900 static int evaluate_timeline_at_frame(AVFilterLink *link, const AVFrame *frame)
1013 {
1014 2194900 FilterLink *l = ff_filter_link(link);
1015 2194900 AVFilterContext *dstctx = link->dst;
1016 2194900 FFFilterContext *dsti = fffilterctx(dstctx);
1017 2194900 int64_t pts = frame->pts;
1018
1019
2/2
✓ Branch 0 taken 2194702 times.
✓ Branch 1 taken 198 times.
2194900 if (!dstctx->enable_str)
1020 2194702 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 707601 static int filter_frame_framed(AVFilterLink *link, AVFrame *frame)
1031 {
1032 707601 FilterLink *l = ff_filter_link(link);
1033 int (*filter_frame)(AVFilterLink *, AVFrame *);
1034 707601 AVFilterContext *dstctx = link->dst;
1035 707601 AVFilterPad *dst = link->dstpad;
1036 int ret;
1037
1038
2/2
✓ Branch 0 taken 688554 times.
✓ Branch 1 taken 19047 times.
707601 if (!(filter_frame = dst->filter_frame))
1039 688554 filter_frame = default_filter_frame;
1040
1041
2/2
✓ Branch 0 taken 2553 times.
✓ Branch 1 taken 705048 times.
707601 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 707601 ff_inlink_process_commands(link, frame);
1048 707601 dstctx->is_disabled = !evaluate_timeline_at_frame(link, frame);
1049
1050
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 707582 times.
707601 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 707601 ret = filter_frame(link, frame);
1054 707601 l->frame_count_out++;
1055 707601 return ret;
1056
1057 fail:
1058 av_frame_free(&frame);
1059 return ret;
1060 }
1061
1062 1492071 int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
1063 {
1064 1492071 FilterLinkInternal * const li = ff_link_internal(link);
1065 int ret;
1066 1492071 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 563676 times.
✓ Branch 1 taken 928395 times.
1492071 if (link->type == AVMEDIA_TYPE_VIDEO) {
1070
2/2
✓ Branch 0 taken 420076 times.
✓ Branch 1 taken 143600 times.
563676 if (strcmp(link->dst->filter->name, "buffersink") &&
1071
2/2
✓ Branch 0 taken 251220 times.
✓ Branch 1 taken 168856 times.
420076 strcmp(link->dst->filter->name, "format") &&
1072
2/2
✓ Branch 0 taken 251193 times.
✓ Branch 1 taken 27 times.
251220 strcmp(link->dst->filter->name, "idet") &&
1073
2/2
✓ Branch 0 taken 161535 times.
✓ Branch 1 taken 89658 times.
251193 strcmp(link->dst->filter->name, "null") &&
1074
2/2
✓ Branch 0 taken 53918 times.
✓ Branch 1 taken 107617 times.
161535 strcmp(link->dst->filter->name, "scale") &&
1075 53918 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 563676 frame->sample_aspect_ratio = link->sample_aspect_ratio;
1082 } else {
1083
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 928395 times.
928395 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 928395 times.
928395 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 928395 times.
928395 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 928395 frame->duration = av_rescale_q(frame->nb_samples, (AVRational){ 1, frame->sample_rate },
1097 link->time_base);
1098 }
1099
1100 1492071 li->frame_blocked_in = li->frame_wanted_out = 0;
1101 1492071 li->l.frame_count_in++;
1102 1492071 li->l.sample_count_in += frame->nb_samples;
1103 1492071 filter_unblock(link->dst);
1104 1492071 ret = ff_framequeue_add(&li->fifo, frame);
1105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1492071 times.
1492071 if (ret < 0) {
1106 av_frame_free(&frame);
1107 return ret;
1108 }
1109 1492071 ff_filter_set_ready(link->dst, 300);
1110 1492071 return 0;
1111
1112 error:
1113 av_frame_free(&frame);
1114 return AVERROR_PATCHWELCOME;
1115 }
1116
1117 2119441 static int samples_ready(FilterLinkInternal *link, unsigned min)
1118 {
1119
2/2
✓ Branch 1 taken 707735 times.
✓ Branch 2 taken 1411706 times.
2827176 return ff_framequeue_queued_frames(&link->fifo) &&
1120
2/2
✓ Branch 1 taken 135 times.
✓ Branch 2 taken 707600 times.
707735 (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 2488 static int take_samples(FilterLinkInternal *li, unsigned min, unsigned max,
1125 AVFrame **rframe)
1126 {
1127 2488 FilterLink *l = &li->l;
1128 2488 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 2488 frame0 = frame = ff_framequeue_peek(&li->fifo, 0);
1137
6/6
✓ Branch 0 taken 932 times.
✓ Branch 1 taken 1556 times.
✓ Branch 2 taken 819 times.
✓ Branch 3 taken 113 times.
✓ Branch 4 taken 547 times.
✓ Branch 5 taken 272 times.
2488 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 1941 nb_frames = 0;
1142 1941 nb_samples = 0;
1143 while (1) {
1144
2/2
✓ Branch 0 taken 1556 times.
✓ Branch 1 taken 1459 times.
3015 if (nb_samples + frame->nb_samples > max) {
1145
1/2
✓ Branch 0 taken 1556 times.
✗ Branch 1 not taken.
1556 if (nb_samples < min)
1146 1556 nb_samples = max;
1147 1556 break;
1148 }
1149 1459 nb_samples += frame->nb_samples;
1150 1459 nb_frames++;
1151
2/2
✓ Branch 1 taken 385 times.
✓ Branch 2 taken 1074 times.
1459 if (nb_frames == ff_framequeue_queued_frames(&li->fifo))
1152 385 break;
1153 1074 frame = ff_framequeue_peek(&li->fifo, nb_frames);
1154 }
1155
1156 1941 buf = ff_get_audio_buffer(link, nb_samples);
1157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1941 times.
1941 if (!buf)
1158 return AVERROR(ENOMEM);
1159 1941 ret = av_frame_copy_props(buf, frame0);
1160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1941 times.
1941 if (ret < 0) {
1161 av_frame_free(&buf);
1162 return ret;
1163 }
1164
1165 1941 p = 0;
1166
2/2
✓ Branch 0 taken 1459 times.
✓ Branch 1 taken 1941 times.
3400 for (i = 0; i < nb_frames; i++) {
1167 1459 frame = ff_framequeue_take(&li->fifo);
1168 1459 av_samples_copy(buf->extended_data, frame->extended_data, p, 0,
1169 1459 frame->nb_samples, link->ch_layout.nb_channels, link->format);
1170 1459 p += frame->nb_samples;
1171 1459 av_frame_free(&frame);
1172 }
1173
2/2
✓ Branch 0 taken 1556 times.
✓ Branch 1 taken 385 times.
1941 if (p < nb_samples) {
1174 1556 unsigned n = nb_samples - p;
1175 1556 frame = ff_framequeue_peek(&li->fifo, 0);
1176 1556 av_samples_copy(buf->extended_data, frame->extended_data, p, 0, n,
1177 1556 link->ch_layout.nb_channels, link->format);
1178 1556 ff_framequeue_skip_samples(&li->fifo, n, link->time_base);
1179 }
1180
1181 1941 *rframe = buf;
1182 1941 return 0;
1183 }
1184
1185 707601 static int filter_frame_to_filter(AVFilterLink *link)
1186 {
1187 707601 FilterLinkInternal * const li = ff_link_internal(link);
1188 707601 AVFrame *frame = NULL;
1189 707601 AVFilterContext *dst = link->dst;
1190 int ret;
1191
1192 av_assert1(ff_framequeue_queued_frames(&li->fifo));
1193 1415202 ret = li->l.min_samples ?
1194
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 707565 times.
707601 ff_inlink_consume_samples(link, li->l.min_samples, li->l.max_samples, &frame) :
1195 707565 ff_inlink_consume_frame(link, &frame);
1196 av_assert1(ret);
1197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 707601 times.
707601 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 707601 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 707601 li->l.frame_count_out--;
1207 707601 ret = filter_frame_framed(link, frame);
1208
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 707601 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
707601 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 707601 ff_filter_set_ready(dst, 300);
1214 }
1215 707601 return ret;
1216 }
1217
1218 5955 static int forward_status_change(AVFilterContext *filter, FilterLinkInternal *li_in)
1219 {
1220 5955 AVFilterLink *in = &li_in->l.pub;
1221 5955 unsigned out = 0, progress = 0;
1222 int ret;
1223
1224
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5955 times.
5955 av_assert0(!li_in->status_out);
1225
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5954 times.
5955 if (!filter->nb_outputs) {
1226 /* not necessary with the current API and sinks */
1227 1 return 0;
1228 }
1229
2/2
✓ Branch 0 taken 5954 times.
✓ Branch 1 taken 5954 times.
11908 while (!li_in->status_out) {
1230 5954 FilterLinkInternal *li_out = ff_link_internal(filter->outputs[out]);
1231
1232
1/2
✓ Branch 0 taken 5954 times.
✗ Branch 1 not taken.
5954 if (!li_out->status_in) {
1233 5954 progress++;
1234 5954 ret = request_frame_to_filter(filter->outputs[out]);
1235
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5954 times.
5954 if (ret < 0)
1236 return ret;
1237 }
1238
1/2
✓ Branch 0 taken 5954 times.
✗ Branch 1 not taken.
5954 if (++out == filter->nb_outputs) {
1239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5954 times.
5954 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 5954 progress = 0;
1246 5954 out = 0;
1247 }
1248 }
1249 5954 ff_filter_set_ready(filter, 200);
1250 5954 return 0;
1251 }
1252
1253 2126489 static int filter_activate_default(AVFilterContext *filter)
1254 {
1255 unsigned i;
1256 2126489 int nb_eofs = 0;
1257
1258
2/2
✓ Branch 0 taken 2126446 times.
✓ Branch 1 taken 2126489 times.
4252935 for (i = 0; i < filter->nb_outputs; i++)
1259 2126446 nb_eofs += ff_outlink_get_status(filter->outputs[i]) == AVERROR_EOF;
1260
4/4
✓ Branch 0 taken 2126446 times.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 6776 times.
✓ Branch 3 taken 2119670 times.
2126489 if (filter->nb_outputs && nb_eofs == filter->nb_outputs) {
1261
2/2
✓ Branch 0 taken 6776 times.
✓ Branch 1 taken 6776 times.
13552 for (int j = 0; j < filter->nb_inputs; j++)
1262 6776 ff_inlink_set_status(filter->inputs[j], AVERROR_EOF);
1263 6776 return 0;
1264 }
1265
1266
2/2
✓ Branch 0 taken 2119441 times.
✓ Branch 1 taken 1412112 times.
3531553 for (i = 0; i < filter->nb_inputs; i++) {
1267 2119441 FilterLinkInternal *li = ff_link_internal(filter->inputs[i]);
1268
2/2
✓ Branch 1 taken 707601 times.
✓ Branch 2 taken 1411840 times.
2119441 if (samples_ready(li, li->l.min_samples)) {
1269 707601 return filter_frame_to_filter(filter->inputs[i]);
1270 }
1271 }
1272
2/2
✓ Branch 0 taken 1411840 times.
✓ Branch 1 taken 1406157 times.
2817997 for (i = 0; i < filter->nb_inputs; i++) {
1273 1411840 FilterLinkInternal * const li = ff_link_internal(filter->inputs[i]);
1274
4/4
✓ Branch 0 taken 5984 times.
✓ Branch 1 taken 1405856 times.
✓ Branch 2 taken 5955 times.
✓ Branch 3 taken 29 times.
1411840 if (li->status_in && !li->status_out) {
1275 av_assert1(!ff_framequeue_queued_frames(&li->fifo));
1276 5955 return forward_status_change(filter, li);
1277 }
1278 }
1279
2/2
✓ Branch 0 taken 1406136 times.
✓ Branch 1 taken 708224 times.
2114360 for (i = 0; i < filter->nb_outputs; i++) {
1280 1406136 FilterLinkInternal * const li = ff_link_internal(filter->outputs[i]);
1281
2/2
✓ Branch 0 taken 702312 times.
✓ Branch 1 taken 703824 times.
1406136 if (li->frame_wanted_out &&
1282
2/2
✓ Branch 0 taken 697933 times.
✓ Branch 1 taken 4379 times.
702312 !li->frame_blocked_in) {
1283 697933 return request_frame_to_filter(filter->outputs[i]);
1284 }
1285 }
1286
2/2
✓ Branch 0 taken 708203 times.
✓ Branch 1 taken 703845 times.
1412048 for (i = 0; i < filter->nb_outputs; i++) {
1287 708203 FilterLinkInternal * const li = ff_link_internal(filter->outputs[i]);
1288
2/2
✓ Branch 0 taken 4379 times.
✓ Branch 1 taken 703824 times.
708203 if (li->frame_wanted_out)
1289 4379 return request_frame_to_filter(filter->outputs[i]);
1290 }
1291
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 703824 times.
703845 if (!filter->nb_outputs) {
1292 21 ff_inlink_request_frame(filter->inputs[0]);
1293 21 return 0;
1294 }
1295 703824 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 3710889 int ff_filter_activate(AVFilterContext *filter)
1442 {
1443 3710889 FFFilterContext *ctxi = fffilterctx(filter);
1444 3710889 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 3710889 ctxi->ready = 0;
1451
2/2
✓ Branch 0 taken 1584400 times.
✓ Branch 1 taken 2126489 times.
3710889 ret = fi->activate ? fi->activate(filter) : filter_activate_default(filter);
1452
2/2
✓ Branch 0 taken 704679 times.
✓ Branch 1 taken 3006210 times.
3710889 if (ret == FFERROR_NOT_READY)
1453 704679 ret = 0;
1454 3710889 return ret;
1455 }
1456
1457 3406542 int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
1458 {
1459 3406542 FilterLinkInternal * const li = ff_link_internal(link);
1460 3406542 *rpts = li->l.current_pts;
1461
2/2
✓ Branch 1 taken 2243 times.
✓ Branch 2 taken 3404299 times.
3406542 if (ff_framequeue_queued_frames(&li->fifo))
1462 2243 return *rstatus = 0;
1463
2/2
✓ Branch 0 taken 6345 times.
✓ Branch 1 taken 3397954 times.
3404299 if (li->status_out)
1464 6345 return *rstatus = li->status_out;
1465
2/2
✓ Branch 0 taken 3390152 times.
✓ Branch 1 taken 7802 times.
3397954 if (!li->status_in)
1466 3390152 return *rstatus = 0;
1467 7802 *rstatus = li->status_out = li->status_in;
1468 7802 update_link_current_pts(li, li->status_in_pts);
1469 7802 *rpts = li->l.current_pts;
1470 7802 return 1;
1471 }
1472
1473 87050 size_t ff_inlink_queued_frames(AVFilterLink *link)
1474 {
1475 87050 FilterLinkInternal * const li = ff_link_internal(link);
1476 87050 return ff_framequeue_queued_frames(&li->fifo);
1477 }
1478
1479 4844473 int ff_inlink_check_available_frame(AVFilterLink *link)
1480 {
1481 4844473 FilterLinkInternal * const li = ff_link_internal(link);
1482 4844473 return ff_framequeue_queued_frames(&li->fifo) > 0;
1483 }
1484
1485 2599 int ff_inlink_queued_samples(AVFilterLink *link)
1486 {
1487 2599 FilterLinkInternal * const li = ff_link_internal(link);
1488 2599 return ff_framequeue_queued_samples(&li->fifo);
1489 }
1490
1491 4805 int ff_inlink_check_available_samples(AVFilterLink *link, unsigned min)
1492 {
1493 4805 FilterLinkInternal * const li = ff_link_internal(link);
1494 4805 uint64_t samples = ff_framequeue_queued_samples(&li->fifo);
1495 av_assert1(min);
1496
6/6
✓ Branch 0 taken 2323 times.
✓ Branch 1 taken 2482 times.
✓ Branch 2 taken 66 times.
✓ Branch 3 taken 2257 times.
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 59 times.
4805 return samples >= min || (li->status_in && samples);
1497 }
1498
1499 1489680 static void consume_update(FilterLinkInternal *li, const AVFrame *frame)
1500 {
1501 1489680 AVFilterLink *const link = &li->l.pub;
1502 1489680 update_link_current_pts(li, frame->pts);
1503 1489680 ff_inlink_process_commands(link, frame);
1504
2/2
✓ Branch 0 taken 1487299 times.
✓ Branch 1 taken 2381 times.
1489680 if (link == link->dst->inputs[0])
1505 1487299 link->dst->is_disabled = !evaluate_timeline_at_frame(link, frame);
1506 1489680 li->l.frame_count_out++;
1507 1489680 li->l.sample_count_out += frame->nb_samples;
1508 1489680 }
1509
1510 4842588 int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
1511 {
1512 4842588 FilterLinkInternal * const li = ff_link_internal(link);
1513 AVFrame *frame;
1514
1515 4842588 *rframe = NULL;
1516
2/2
✓ Branch 1 taken 3355393 times.
✓ Branch 2 taken 1487195 times.
4842588 if (!ff_inlink_check_available_frame(link))
1517 3355393 return 0;
1518
1519
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1487192 times.
1487195 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 1487192 frame = ff_framequeue_take(&li->fifo);
1525 1487192 consume_update(li, frame);
1526 1487192 *rframe = frame;
1527 1487192 return 1;
1528 }
1529
1530 4586 int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max,
1531 AVFrame **rframe)
1532 {
1533 4586 FilterLinkInternal * const li = ff_link_internal(link);
1534 AVFrame *frame;
1535 int ret;
1536
1537 av_assert1(min);
1538 4586 *rframe = NULL;
1539
2/2
✓ Branch 1 taken 2098 times.
✓ Branch 2 taken 2488 times.
4586 if (!ff_inlink_check_available_samples(link, min))
1540 2098 return 0;
1541
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 2465 times.
2488 if (li->status_in)
1542
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 17 times.
23 min = FFMIN(min, ff_framequeue_queued_samples(&li->fifo));
1543 2488 ret = take_samples(li, min, max, &frame);
1544
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2488 times.
2488 if (ret < 0)
1545 return ret;
1546 2488 consume_update(li, frame);
1547 2488 *rframe = frame;
1548 2488 return 1;
1549 }
1550
1551 AVFrame *ff_inlink_peek_frame(AVFilterLink *link, size_t idx)
1552 {
1553 FilterLinkInternal * const li = ff_link_internal(link);
1554 return ff_framequeue_peek(&li->fifo, idx);
1555 }
1556
1557 4747 int ff_inlink_make_frame_writable(AVFilterLink *link, AVFrame **rframe)
1558 {
1559 4747 AVFrame *frame = *rframe;
1560 AVFrame *out;
1561 int ret;
1562
1563
2/2
✓ Branch 1 taken 2198 times.
✓ Branch 2 taken 2549 times.
4747 if (av_frame_is_writable(frame))
1564 2198 return 0;
1565 2549 av_log(link->dst, AV_LOG_DEBUG, "Copying data in avfilter.\n");
1566
1567
1/3
✓ Branch 0 taken 2549 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
2549 switch (link->type) {
1568 2549 case AVMEDIA_TYPE_VIDEO:
1569 2549 out = ff_get_video_buffer(link, link->w, link->h);
1570 2549 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 2549 times.
2549 if (!out)
1578 return AVERROR(ENOMEM);
1579
1580 2549 ret = av_frame_copy_props(out, frame);
1581
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2549 times.
2549 if (ret < 0) {
1582 av_frame_free(&out);
1583 return ret;
1584 }
1585
1586 2549 ret = av_frame_copy(out, frame);
1587
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2549 times.
2549 if (ret < 0) {
1588 av_frame_free(&out);
1589 return ret;
1590 }
1591
1592 2549 av_frame_free(&frame);
1593 2549 *rframe = out;
1594 2549 return 0;
1595 }
1596
1597 2197281 int ff_inlink_process_commands(AVFilterLink *link, const AVFrame *frame)
1598 {
1599 2197281 FFFilterContext *ctxi = fffilterctx(link->dst);
1600 2197281 AVFilterCommand *cmd = ctxi->command_queue;
1601
1602
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2197281 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2197281 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 2197281 return 0;
1611 }
1612
1613 787714 void ff_inlink_request_frame(AVFilterLink *link)
1614 {
1615 787714 av_unused FilterLinkInternal *li = ff_link_internal(link);
1616 av_assert1(!li->status_in);
1617 av_assert1(!li->status_out);
1618 787714 li->frame_wanted_out = 1;
1619 787714 ff_filter_set_ready(link->src, 100);
1620 787714 }
1621
1622 10776 void ff_inlink_set_status(AVFilterLink *link, int status)
1623 {
1624 10776 FilterLinkInternal * const li = ff_link_internal(link);
1625
2/2
✓ Branch 0 taken 8378 times.
✓ Branch 1 taken 2398 times.
10776 if (li->status_out)
1626 8378 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 3260837 int ff_outlink_get_status(AVFilterLink *link)
1639 {
1640 3260837 FilterLinkInternal * const li = ff_link_internal(link);
1641 3260837 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 428357 int ff_outlink_frame_wanted(AVFilterLink *link)
1681 {
1682 428357 FilterLinkInternal * const li = ff_link_internal(link);
1683 428357 return li->frame_wanted_out;
1684 }
1685
1686 4825 int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func,
1687 void *arg, int *ret, int nb_jobs)
1688 {
1689 4825 return fffilterctx(ctx)->execute(ctx, func, arg, ret, nb_jobs);
1690 }
1691