FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/avfilter.c
Date: 2026-02-17 19:16:38
Exec Total Coverage
Lines: 673 848 79.4%
Functions: 59 66 89.4%
Branches: 362 510 71.0%

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