FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/avfilter.c
Date: 2025-04-25 22:50:00
Exec Total Coverage
Lines: 651 830 78.4%
Functions: 58 65 89.2%
Branches: 346 494 70.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 1473456 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 1473456 }
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 501 static int append_pad(unsigned *count, AVFilterPad **pads,
101 AVFilterLink ***links, AVFilterPad *newpad)
102 {
103 AVFilterLink **newlinks;
104 AVFilterPad *newpads;
105 501 unsigned idx = *count;
106
107 501 newpads = av_realloc_array(*pads, idx + 1, sizeof(*newpads));
108 501 newlinks = av_realloc_array(*links, idx + 1, sizeof(*newlinks));
109
1/2
✓ Branch 0 taken 501 times.
✗ Branch 1 not taken.
501 if (newpads)
110 501 *pads = newpads;
111
1/2
✓ Branch 0 taken 501 times.
✗ Branch 1 not taken.
501 if (newlinks)
112 501 *links = newlinks;
113
2/4
✓ Branch 0 taken 501 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 501 times.
501 if (!newpads || !newlinks) {
114 if (newpad->flags & AVFILTERPAD_FLAG_FREE_NAME)
115 av_freep(&newpad->name);
116 return AVERROR(ENOMEM);
117 }
118
119 501 memcpy(*pads + idx, newpad, sizeof(AVFilterPad));
120 501 (*links)[idx] = NULL;
121
122 501 (*count)++;
123
124 501 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 272 int ff_append_outpad(AVFilterContext *f, AVFilterPad *p)
139 {
140 272 return append_pad(&f->nb_outputs, &f->output_pads, &f->outputs, p);
141 }
142
143 131 int ff_append_outpad_free_name(AVFilterContext *f, AVFilterPad *p)
144 {
145 131 p->flags |= AVFILTERPAD_FLAG_FREE_NAME;
146 131 return ff_append_outpad(f, p);
147 }
148
149 45650 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 45650 times.
45650 av_assert0(src->graph);
156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45650 times.
45650 av_assert0(dst->graph);
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45650 times.
45650 av_assert0(src->graph == dst->graph);
158
159
2/4
✓ Branch 0 taken 45650 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45650 times.
✗ Branch 3 not taken.
45650 if (src->nb_outputs <= srcpad || dst->nb_inputs <= dstpad ||
160
2/4
✓ Branch 0 taken 45650 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45650 times.
45650 src->outputs[srcpad] || dst->inputs[dstpad])
161 return AVERROR(EINVAL);
162
163
1/2
✓ Branch 1 taken 45650 times.
✗ Branch 2 not taken.
45650 if (!(fffilterctx(src)->state_flags & AV_CLASS_STATE_INITIALIZED) ||
164
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 45650 times.
45650 !(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 45650 times.
45650 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 45650 li = av_mallocz(sizeof(*li));
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45650 times.
45650 if (!li)
179 return AVERROR(ENOMEM);
180 45650 link = &li->l.pub;
181
182 45650 src->outputs[srcpad] = dst->inputs[dstpad] = link;
183
184 45650 link->src = src;
185 45650 link->dst = dst;
186 45650 link->srcpad = &src->output_pads[srcpad];
187 45650 link->dstpad = &dst->input_pads[dstpad];
188 45650 link->type = src->output_pads[srcpad].type;
189 45650 li->l.graph = src->graph;
190 av_assert0(AV_PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1);
191 45650 link->format = -1;
192 45650 link->colorspace = AVCOL_SPC_UNSPECIFIED;
193 45650 ff_framequeue_init(&li->fifo, &fffiltergraph(src->graph)->frame_queues);
194
195 45650 return 0;
196 }
197
198 45782 static void link_free(AVFilterLink **link)
199 {
200 FilterLinkInternal *li;
201
202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45782 times.
45782 if (!*link)
203 return;
204 45782 li = ff_link_internal(*link);
205
206 45782 ff_framequeue_free(&li->fifo);
207 45782 ff_frame_pool_uninit(&li->frame_pool);
208 45782 av_channel_layout_uninit(&(*link)->ch_layout);
209 45782 av_frame_side_data_free(&(*link)->side_data, &(*link)->nb_side_data);
210
211 45782 av_buffer_unref(&li->l.hw_frames_ctx);
212
213 45782 av_freep(link);
214 }
215
216 1487546 static void update_link_current_pts(FilterLinkInternal *li, int64_t pts)
217 {
218 1487546 AVFilterLink *const link = &li->l.pub;
219
220
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1487541 times.
1487546 if (pts == AV_NOPTS_VALUE)
221 5 return;
222 1487541 li->l.current_pts = pts;
223 1487541 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 1487541 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 407130 times.
✓ Branch 3 taken 1080411 times.
1487541 if (li->l.graph && li->age_index >= 0)
226 407130 ff_avfilter_graph_update_heap(li->l.graph, li);
227 }
228
229 3662016 void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
230 {
231 3662016 FFFilterContext *ctxi = fffilterctx(filter);
232 3662016 ctxi->ready = FFMAX(ctxi->ready, priority);
233 3662016 }
234
235 /**
236 * Clear frame_blocked_in on all outputs.
237 * This is necessary whenever something changes on input.
238 */
239 2194347 static void filter_unblock(AVFilterContext *filter)
240 {
241 unsigned i;
242
243
2/2
✓ Branch 0 taken 1789101 times.
✓ Branch 1 taken 2194347 times.
3983448 for (i = 0; i < filter->nb_outputs; i++) {
244 1789101 FilterLinkInternal * const li = ff_link_internal(filter->outputs[i]);
245 1789101 li->frame_blocked_in = 0;
246 }
247 2194347 }
248
249
250 17471 void ff_avfilter_link_set_in_status(AVFilterLink *link, int status, int64_t pts)
251 {
252 17471 FilterLinkInternal * const li = ff_link_internal(link);
253
254
2/2
✓ Branch 0 taken 3827 times.
✓ Branch 1 taken 13644 times.
17471 if (li->status_in == status)
255 3827 return;
256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13644 times.
13644 av_assert0(!li->status_in);
257 13644 li->status_in = status;
258 13644 li->status_in_pts = pts;
259 13644 li->frame_wanted_out = 0;
260 13644 li->frame_blocked_in = 0;
261 13644 filter_unblock(link->dst);
262 13644 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 8285 static void link_set_out_status(AVFilterLink *link, int status, int64_t pts)
270 {
271 8285 FilterLinkInternal * const li = ff_link_internal(link);
272
273
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8285 times.
8285 av_assert0(!li->frame_wanted_out);
274
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8285 times.
8285 av_assert0(!li->status_out);
275 8285 li->status_out = status;
276
2/2
✓ Branch 0 taken 5909 times.
✓ Branch 1 taken 2376 times.
8285 if (pts != AV_NOPTS_VALUE)
277 5909 update_link_current_pts(li, pts);
278 8285 filter_unblock(link->dst);
279 8285 ff_filter_set_ready(link->src, 200);
280 8285 }
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 43787 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 35819 times.
✓ Branch 1 taken 43787 times.
79606 for (i = 0; i < filter->nb_inputs; i ++) {
332 35819 AVFilterLink *link = filter->inputs[i];
333 AVFilterLink *inlink;
334 35819 FilterLinkInternal *li = ff_link_internal(link);
335 FilterLinkInternal *li_in;
336
337
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35819 times.
35819 if (!link) continue;
338
2/4
✓ Branch 0 taken 35819 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 35819 times.
35819 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 27675 times.
✓ Branch 1 taken 8144 times.
35819 inlink = link->src->nb_inputs ? link->src->inputs[0] : NULL;
345
2/2
✓ Branch 0 taken 27675 times.
✓ Branch 1 taken 8144 times.
35819 li_in = inlink ? ff_link_internal(inlink) : NULL;
346 35819 li->l.current_pts =
347 35819 li->l.current_pts_us = AV_NOPTS_VALUE;
348
349
2/4
✓ Branch 0 taken 105 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 35714 times.
✗ Branch 3 not taken.
35819 switch (li->init_state) {
350 105 case AVLINK_INIT:
351 105 continue;
352 case AVLINK_STARTINIT:
353 av_log(filter, AV_LOG_INFO, "circular filter chain detected\n");
354 return 0;
355 35714 case AVLINK_UNINIT:
356 35714 li->init_state = AVLINK_STARTINIT;
357
358
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 35714 times.
35714 if ((ret = ff_filter_config_links(link->src)) < 0)
359 return ret;
360
361
2/2
✓ Branch 0 taken 18706 times.
✓ Branch 1 taken 17008 times.
35714 if (!(config_link = link->srcpad->config_props)) {
362
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18706 times.
18706 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 27599 times.
✓ Branch 1 taken 8115 times.
✓ Branch 2 taken 239 times.
✓ Branch 3 taken 27360 times.
✓ Branch 4 taken 239 times.
✗ Branch 5 not taken.
35714 if (inlink && inlink->nb_side_data && !link->nb_side_data) {
374
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 239 times.
485 for (int j = 0; j < inlink->nb_side_data; j++) {
375 246 ret = av_frame_side_data_clone(&link->side_data, &link->nb_side_data,
376 246 inlink->side_data[j], 0);
377
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 246 times.
246 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 17008 times.
✓ Branch 1 taken 18706 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17008 times.
35714 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 29819 times.
✓ Branch 1 taken 5895 times.
✗ Branch 2 not taken.
35714 switch (link->type) {
392 29819 case AVMEDIA_TYPE_VIDEO:
393
3/4
✓ Branch 0 taken 22811 times.
✓ Branch 1 taken 7008 times.
✓ Branch 2 taken 22811 times.
✗ Branch 3 not taken.
29819 if (!link->time_base.num && !link->time_base.den)
394
1/2
✓ Branch 0 taken 22811 times.
✗ Branch 1 not taken.
22811 link->time_base = inlink ? inlink->time_base : AV_TIME_BASE_Q;
395
396
4/4
✓ Branch 0 taken 25599 times.
✓ Branch 1 taken 4220 times.
✓ Branch 2 taken 16238 times.
✓ Branch 3 taken 9361 times.
29819 if (!link->sample_aspect_ratio.num && !link->sample_aspect_ratio.den)
397 16238 link->sample_aspect_ratio = inlink ?
398
2/2
✓ Branch 0 taken 16224 times.
✓ Branch 1 taken 14 times.
16238 inlink->sample_aspect_ratio : (AVRational){1,1};
399
400
2/2
✓ Branch 0 taken 23064 times.
✓ Branch 1 taken 6755 times.
29819 if (inlink) {
401
3/4
✓ Branch 0 taken 22854 times.
✓ Branch 1 taken 210 times.
✓ Branch 2 taken 22854 times.
✗ Branch 3 not taken.
23064 if (!li->l.frame_rate.num && !li->l.frame_rate.den)
402 22854 li->l.frame_rate = li_in->l.frame_rate;
403
2/2
✓ Branch 0 taken 15754 times.
✓ Branch 1 taken 7310 times.
23064 if (!link->w)
404 15754 link->w = inlink->w;
405
2/2
✓ Branch 0 taken 15754 times.
✓ Branch 1 taken 7310 times.
23064 if (!link->h)
406 15754 link->h = inlink->h;
407
2/4
✓ Branch 0 taken 6755 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6755 times.
6755 } 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 29819 break;
414
415 5895 case AVMEDIA_TYPE_AUDIO:
416
2/2
✓ Branch 0 taken 4535 times.
✓ Branch 1 taken 1360 times.
5895 if (inlink) {
417
3/4
✓ Branch 0 taken 3040 times.
✓ Branch 1 taken 1495 times.
✓ Branch 2 taken 3040 times.
✗ Branch 3 not taken.
4535 if (!link->time_base.num && !link->time_base.den)
418 3040 link->time_base = inlink->time_base;
419 }
420
421
3/4
✓ Branch 0 taken 81 times.
✓ Branch 1 taken 5814 times.
✓ Branch 2 taken 81 times.
✗ Branch 3 not taken.
5895 if (!link->time_base.num && !link->time_base.den)
422 81 link->time_base = (AVRational) {1, link->sample_rate};
423 }
424
425
2/2
✓ Branch 0 taken 27599 times.
✓ Branch 1 taken 8115 times.
35714 if (link->src->nb_inputs &&
426
1/2
✓ Branch 1 taken 27599 times.
✗ Branch 2 not taken.
27599 !(fffilter(link->src->filter)->flags_internal & FF_FILTER_FLAG_HWFRAME_AWARE)) {
427 27599 FilterLink *l0 = ff_filter_link(link->src->inputs[0]);
428
429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27599 times.
27599 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 27599 times.
27599 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 4748 times.
✓ Branch 1 taken 30966 times.
35714 if ((config_link = link->dstpad->config_props))
440
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4748 times.
4748 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 35714 li->init_state = AVLINK_INIT;
448 }
449 }
450
451 43787 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 694611 int ff_request_frame(AVFilterLink *link)
481 {
482 694611 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 694602 times.
694611 if (li->status_out)
488 9 return li->status_out;
489
2/2
✓ Branch 0 taken 5910 times.
✓ Branch 1 taken 688692 times.
694602 if (li->status_in) {
490
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5910 times.
5910 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 5910 link_set_out_status(link, li->status_in, li->status_in_pts);
499 5910 return li->status_out;
500 }
501 }
502 688692 li->frame_wanted_out = 1;
503 688692 ff_filter_set_ready(link->src, 100);
504 688692 return 0;
505 }
506
507 5911 static int64_t guess_status_pts(AVFilterContext *ctx, int status, AVRational link_time_base)
508 {
509 unsigned i;
510 5911 int64_t r = INT64_MAX;
511
512
2/2
✓ Branch 0 taken 5910 times.
✓ Branch 1 taken 5911 times.
11821 for (i = 0; i < ctx->nb_inputs; i++) {
513 5910 FilterLinkInternal * const li = ff_link_internal(ctx->inputs[i]);
514
1/2
✓ Branch 0 taken 5910 times.
✗ Branch 1 not taken.
5910 if (li->status_out == status)
515 5910 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 5910 times.
✓ Branch 1 taken 1 times.
5911 if (r < INT64_MAX)
518 5910 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 694950 static int request_frame_to_filter(AVFilterLink *link)
530 {
531 694950 FilterLinkInternal * const li = ff_link_internal(link);
532 694950 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 694950 li->frame_blocked_in = 1;
537
2/2
✓ Branch 0 taken 2860 times.
✓ Branch 1 taken 692090 times.
694950 if (link->srcpad->request_frame)
538 2860 ret = link->srcpad->request_frame(link);
539
1/2
✓ Branch 0 taken 692090 times.
✗ Branch 1 not taken.
692090 else if (link->src->inputs[0])
540 692090 ret = ff_request_frame(link->src->inputs[0]);
541
2/2
✓ Branch 0 taken 5911 times.
✓ Branch 1 taken 689039 times.
694950 if (ret < 0) {
542
2/4
✓ Branch 0 taken 5911 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5911 times.
✗ Branch 3 not taken.
5911 if (ret != AVERROR(EAGAIN) && ret != li->status_in)
543 5911 ff_avfilter_link_set_in_status(link, ret, guess_status_pts(link->src, ret, link->time_base));
544
1/2
✓ Branch 0 taken 5911 times.
✗ Branch 1 not taken.
5911 if (ret == AVERROR_EOF)
545 5911 ret = 0;
546 }
547 694950 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 14496 unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output)
629 {
630
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14496 times.
14496 return is_output ? fffilter(filter)->nb_outputs : fffilter(filter)->nb_inputs;
631 }
632
633 555 static const char *default_filter_name(void *filter_ctx)
634 {
635 555 AVFilterContext *ctx = filter_ctx;
636
1/2
✓ Branch 0 taken 555 times.
✗ Branch 1 not taken.
555 return ctx->name ? ctx->name : ctx->filter->name;
637 }
638
639 54869 static void *filter_child_next(void *obj, void *prev)
640 {
641 54869 AVFilterContext *ctx = obj;
642
5/8
✓ Branch 0 taken 54863 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 54863 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 54863 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 54863 times.
✗ Branch 7 not taken.
54869 if (!prev && ctx->filter && ctx->filter->priv_class && ctx->priv)
643 54863 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 730 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 730 times.
✓ Branch 1 taken 730 times.
1460 for (i = 0; i < nb_jobs; i++) {
691 730 int r = func(ctx, arg, i, nb_jobs);
692
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 730 times.
730 if (ret)
693 ret[i] = r;
694 }
695 730 return 0;
696 }
697
698 61581 AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name)
699 {
700 FFFilterContext *ctx;
701 AVFilterContext *ret;
702 61581 const FFFilter *const fi = fffilter(filter);
703 61581 int preinited = 0;
704
705
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61581 times.
61581 if (!filter)
706 return NULL;
707
708 61581 ctx = av_mallocz(sizeof(*ctx));
709
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61581 times.
61581 if (!ctx)
710 return NULL;
711 61581 ret = &ctx->p;
712
713 61581 ret->av_class = &avfilter_class;
714 61581 ret->filter = filter;
715
1/2
✓ Branch 0 taken 61581 times.
✗ Branch 1 not taken.
61581 ret->name = inst_name ? av_strdup(inst_name) : NULL;
716
2/2
✓ Branch 0 taken 54902 times.
✓ Branch 1 taken 6679 times.
61581 if (fi->priv_size) {
717 54902 ret->priv = av_mallocz(fi->priv_size);
718
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54902 times.
54902 if (!ret->priv)
719 goto err;
720 }
721
2/2
✓ Branch 0 taken 13203 times.
✓ Branch 1 taken 48378 times.
61581 if (fi->preinit) {
722
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13203 times.
13203 if (fi->preinit(ret) < 0)
723 goto err;
724 13203 preinited = 1;
725 }
726
727 61581 av_opt_set_defaults(ret);
728
2/2
✓ Branch 0 taken 53693 times.
✓ Branch 1 taken 7888 times.
61581 if (filter->priv_class) {
729 53693 *(const AVClass**)ret->priv = filter->priv_class;
730 53693 av_opt_set_defaults(ret->priv);
731 }
732
733 61581 ctx->execute = default_execute;
734
735 61581 ret->nb_inputs = fi->nb_inputs;
736
2/2
✓ Branch 0 taken 52211 times.
✓ Branch 1 taken 9370 times.
61581 if (ret->nb_inputs ) {
737 52211 ret->input_pads = av_memdup(filter->inputs, ret->nb_inputs * sizeof(*filter->inputs));
738
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52211 times.
52211 if (!ret->input_pads)
739 goto err;
740 52211 ret->inputs = av_calloc(ret->nb_inputs, sizeof(*ret->inputs));
741
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52211 times.
52211 if (!ret->inputs)
742 goto err;
743 }
744
745 61581 ret->nb_outputs = fi->nb_outputs;
746
2/2
✓ Branch 0 taken 53426 times.
✓ Branch 1 taken 8155 times.
61581 if (ret->nb_outputs) {
747 53426 ret->output_pads = av_memdup(filter->outputs, ret->nb_outputs * sizeof(*filter->outputs));
748
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53426 times.
53426 if (!ret->output_pads)
749 goto err;
750 53426 ret->outputs = av_calloc(ret->nb_outputs, sizeof(*ret->outputs));
751
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53426 times.
53426 if (!ret->outputs)
752 goto err;
753 }
754
755 61581 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 106232 static void free_link(AVFilterLink *link)
772 {
773
2/2
✓ Branch 0 taken 60450 times.
✓ Branch 1 taken 45782 times.
106232 if (!link)
774 60450 return;
775
776
2/2
✓ Branch 0 taken 45650 times.
✓ Branch 1 taken 132 times.
45782 if (link->src)
777 45650 link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
778
2/2
✓ Branch 0 taken 45650 times.
✓ Branch 1 taken 132 times.
45782 if (link->dst)
779 45650 link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
780
781 45782 ff_formats_unref(&link->incfg.formats);
782 45782 ff_formats_unref(&link->outcfg.formats);
783 45782 ff_formats_unref(&link->incfg.color_spaces);
784 45782 ff_formats_unref(&link->outcfg.color_spaces);
785 45782 ff_formats_unref(&link->incfg.color_ranges);
786 45782 ff_formats_unref(&link->outcfg.color_ranges);
787 45782 ff_formats_unref(&link->incfg.samplerates);
788 45782 ff_formats_unref(&link->outcfg.samplerates);
789 45782 ff_channel_layouts_unref(&link->incfg.channel_layouts);
790 45782 ff_channel_layouts_unref(&link->outcfg.channel_layouts);
791 45782 link_free(&link);
792 }
793
794 61581 void avfilter_free(AVFilterContext *filter)
795 {
796 FFFilterContext *ctxi;
797 int i;
798
799
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61581 times.
61581 if (!filter)
800 return;
801 61581 ctxi = fffilterctx(filter);
802
803
1/2
✓ Branch 0 taken 61581 times.
✗ Branch 1 not taken.
61581 if (filter->graph)
804 61581 ff_filter_graph_remove_filter(filter->graph, filter);
805
806
2/2
✓ Branch 1 taken 47820 times.
✓ Branch 2 taken 13761 times.
61581 if (fffilter(filter->filter)->uninit)
807 47820 fffilter(filter->filter)->uninit(filter);
808
809
2/2
✓ Branch 0 taken 52534 times.
✓ Branch 1 taken 61581 times.
114115 for (i = 0; i < filter->nb_inputs; i++) {
810 52534 free_link(filter->inputs[i]);
811
2/2
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 52324 times.
52534 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 53698 times.
✓ Branch 1 taken 61581 times.
115279 for (i = 0; i < filter->nb_outputs; i++) {
815 53698 free_link(filter->outputs[i]);
816
2/2
✓ Branch 0 taken 267 times.
✓ Branch 1 taken 53431 times.
53698 if (filter->output_pads[i].flags & AVFILTERPAD_FLAG_FREE_NAME)
817 267 av_freep(&filter->output_pads[i].name);
818 }
819
820
2/2
✓ Branch 0 taken 53693 times.
✓ Branch 1 taken 7888 times.
61581 if (filter->filter->priv_class)
821 53693 av_opt_free(filter->priv);
822
823 61581 av_buffer_unref(&filter->hw_device_ctx);
824
825 61581 av_freep(&filter->name);
826 61581 av_freep(&filter->input_pads);
827 61581 av_freep(&filter->output_pads);
828 61581 av_freep(&filter->inputs);
829 61581 av_freep(&filter->outputs);
830 61581 av_freep(&filter->priv);
831
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61581 times.
61581 while (ctxi->command_queue)
832 command_queue_pop(filter);
833 61581 av_opt_free(filter);
834 61581 av_expr_free(ctxi->enable);
835 61581 ctxi->enable = NULL;
836 61581 av_freep(&ctxi->var_values);
837 61581 av_free(filter);
838 }
839
840 17234 int ff_filter_get_nb_threads(AVFilterContext *ctx)
841 {
842
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17234 times.
17234 if (ctx->nb_threads > 0)
843 return FFMIN(ctx->nb_threads, ctx->graph->nb_threads);
844 17234 return ctx->graph->nb_threads;
845 }
846
847 32854 int ff_filter_opt_parse(void *logctx, const AVClass *priv_class,
848 AVDictionary **options, const char *args)
849 {
850 32854 const AVOption *o = NULL;
851 int ret;
852 32854 int offset= -1;
853
854
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32854 times.
32854 if (!args)
855 return 0;
856
857
2/2
✓ Branch 0 taken 56638 times.
✓ Branch 1 taken 32854 times.
89492 while (*args) {
858 char *parsed_key, *value;
859 const char *key;
860 56638 const char *shorthand = NULL;
861 56638 int additional_flags = 0;
862
863
4/4
✓ Branch 0 taken 44041 times.
✓ Branch 1 taken 12597 times.
✓ Branch 3 taken 42759 times.
✓ Branch 4 taken 1282 times.
56638 if (priv_class && (o = av_opt_next(&priv_class, o))) {
864
4/4
✓ Branch 0 taken 40989 times.
✓ Branch 1 taken 1770 times.
✓ Branch 2 taken 4364 times.
✓ Branch 3 taken 36625 times.
42759 if (o->type == AV_OPT_TYPE_CONST || o->offset == offset)
865 6134 continue;
866 36625 offset = o->offset;
867 36625 shorthand = o->name;
868 }
869
870 50504 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 50504 times.
50504 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 26308 times.
✓ Branch 1 taken 24196 times.
50504 if (*args)
882 26308 args++;
883
2/2
✓ Branch 0 taken 30302 times.
✓ Branch 1 taken 20202 times.
50504 if (parsed_key) {
884 30302 key = parsed_key;
885 30302 additional_flags = AV_DICT_DONT_STRDUP_KEY;
886 30302 priv_class = NULL; /* reject all remaining shorthand */
887 } else {
888 20202 key = shorthand;
889 }
890
891 50504 av_log(logctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
892
893 50504 av_dict_set(options, key, value,
894 additional_flags | AV_DICT_DONT_STRDUP_VAL | AV_DICT_MULTIKEY);
895 }
896
897 32854 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 61581 int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options)
914 {
915 61581 FFFilterContext *ctxi = fffilterctx(ctx);
916 61581 int ret = 0;
917
918
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61581 times.
61581 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 61581 ret = av_opt_set_dict2(ctx, options, AV_OPT_SEARCH_CHILDREN);
924
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61581 times.
61581 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 1194 times.
✓ Branch 1 taken 60387 times.
61581 if (ctx->filter->flags & AVFILTER_FLAG_SLICE_THREADS &&
930
2/2
✓ Branch 0 taken 147 times.
✓ Branch 1 taken 1047 times.
1194 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 61434 ctx->thread_type = 0;
936 }
937
938
2/2
✓ Branch 1 taken 48548 times.
✓ Branch 2 taken 13033 times.
61581 if (fffilter(ctx->filter)->init)
939 48548 ret = fffilter(ctx->filter)->init(ctx);
940
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61581 times.
61581 if (ret < 0)
941 return ret;
942
943
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 61575 times.
61581 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 61581 ctxi->state_flags |= AV_CLASS_STATE_INITIALIZED;
950
951 61581 return 0;
952 }
953
954 20157 int avfilter_init_str(AVFilterContext *filter, const char *args)
955 {
956 20157 AVDictionary *options = NULL;
957 const AVDictionaryEntry *e;
958 20157 int ret = 0;
959
960
3/4
✓ Branch 0 taken 10077 times.
✓ Branch 1 taken 10080 times.
✓ Branch 2 taken 10077 times.
✗ Branch 3 not taken.
20157 if (args && *args) {
961 10077 ret = ff_filter_opt_parse(filter, filter->filter->priv_class, &options, args);
962
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10077 times.
10077 if (ret < 0)
963 goto fail;
964 }
965
966 20157 ret = avfilter_init_dict(filter, &options);
967
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20157 times.
20157 if (ret < 0)
968 goto fail;
969
970
1/2
✓ Branch 1 taken 20157 times.
✗ Branch 2 not taken.
20157 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 20157 fail:
977 20157 av_dict_free(&options);
978
979 20157 return ret;
980 }
981
982 14798 const char *avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx)
983 {
984 14798 return pads[pad_idx].name;
985 }
986
987 29869 enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx)
988 {
989 29869 return pads[pad_idx].type;
990 }
991
992 680854 static int default_filter_frame(AVFilterLink *link, AVFrame *frame)
993 {
994 680854 return ff_filter_frame(link->dst->outputs[0], frame);
995 }
996
997 /**
998 * Evaluate the timeline expression of the link for the time and properties
999 * of the frame.
1000 * @return >0 if enabled, 0 if disabled
1001 * @note It does not update link->dst->is_disabled.
1002 */
1003 2170493 static int evaluate_timeline_at_frame(AVFilterLink *link, const AVFrame *frame)
1004 {
1005 2170493 FilterLink *l = ff_filter_link(link);
1006 2170493 AVFilterContext *dstctx = link->dst;
1007 2170493 FFFilterContext *dsti = fffilterctx(dstctx);
1008 2170493 int64_t pts = frame->pts;
1009
1010
2/2
✓ Branch 0 taken 2170297 times.
✓ Branch 1 taken 196 times.
2170493 if (!dstctx->enable_str)
1011 2170297 return 1;
1012
1013 196 dsti->var_values[VAR_N] = l->frame_count_out;
1014
1/2
✓ Branch 0 taken 196 times.
✗ Branch 1 not taken.
196 dsti->var_values[VAR_T] = pts == AV_NOPTS_VALUE ? NAN : pts * av_q2d(link->time_base);
1015 196 dsti->var_values[VAR_W] = link->w;
1016 196 dsti->var_values[VAR_H] = link->h;
1017
1018 196 return fabs(av_expr_eval(dsti->enable, dsti->var_values, NULL)) >= 0.5;
1019 }
1020
1021 698962 static int filter_frame_framed(AVFilterLink *link, AVFrame *frame)
1022 {
1023 698962 FilterLink *l = ff_filter_link(link);
1024 int (*filter_frame)(AVFilterLink *, AVFrame *);
1025 698962 AVFilterContext *dstctx = link->dst;
1026 698962 AVFilterPad *dst = link->dstpad;
1027 int ret;
1028
1029
2/2
✓ Branch 0 taken 680845 times.
✓ Branch 1 taken 18117 times.
698962 if (!(filter_frame = dst->filter_frame))
1030 680845 filter_frame = default_filter_frame;
1031
1032
2/2
✓ Branch 0 taken 2551 times.
✓ Branch 1 taken 696411 times.
698962 if (dst->flags & AVFILTERPAD_FLAG_NEEDS_WRITABLE) {
1033 2551 ret = ff_inlink_make_frame_writable(link, &frame);
1034
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2551 times.
2551 if (ret < 0)
1035 goto fail;
1036 }
1037
1038 698962 ff_inlink_process_commands(link, frame);
1039 698962 dstctx->is_disabled = !evaluate_timeline_at_frame(link, frame);
1040
1041
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 698943 times.
698962 if (dstctx->is_disabled &&
1042
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 10 times.
19 (dstctx->filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC))
1043 9 filter_frame = default_filter_frame;
1044 698962 ret = filter_frame(link, frame);
1045 698962 l->frame_count_out++;
1046 698962 return ret;
1047
1048 fail:
1049 av_frame_free(&frame);
1050 return ret;
1051 }
1052
1053 1473456 int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
1054 {
1055 1473456 FilterLinkInternal * const li = ff_link_internal(link);
1056 int ret;
1057 1473456 FF_TPRINTF_START(NULL, filter_frame); ff_tlog_link(NULL, link, 1); ff_tlog(NULL, " "); tlog_ref(NULL, frame, 1);
1058
1059 /* Consistency checks */
1060
2/2
✓ Branch 0 taken 545898 times.
✓ Branch 1 taken 927558 times.
1473456 if (link->type == AVMEDIA_TYPE_VIDEO) {
1061
2/2
✓ Branch 0 taken 405754 times.
✓ Branch 1 taken 140144 times.
545898 if (strcmp(link->dst->filter->name, "buffersink") &&
1062
2/2
✓ Branch 0 taken 243838 times.
✓ Branch 1 taken 161916 times.
405754 strcmp(link->dst->filter->name, "format") &&
1063
2/2
✓ Branch 0 taken 243812 times.
✓ Branch 1 taken 26 times.
243838 strcmp(link->dst->filter->name, "idet") &&
1064
2/2
✓ Branch 0 taken 154597 times.
✓ Branch 1 taken 89215 times.
243812 strcmp(link->dst->filter->name, "null") &&
1065 154597 strcmp(link->dst->filter->name, "scale")) {
1066 av_assert1(frame->format == link->format);
1067 av_assert1(frame->width == link->w);
1068 av_assert1(frame->height == link->h);
1069 }
1070
1071 545898 frame->sample_aspect_ratio = link->sample_aspect_ratio;
1072 } else {
1073
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 927558 times.
927558 if (frame->format != link->format) {
1074 av_log(link->dst, AV_LOG_ERROR, "Format change is not supported\n");
1075 goto error;
1076 }
1077
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 927558 times.
927558 if (av_channel_layout_compare(&frame->ch_layout, &link->ch_layout)) {
1078 av_log(link->dst, AV_LOG_ERROR, "Channel layout change is not supported\n");
1079 goto error;
1080 }
1081
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 927558 times.
927558 if (frame->sample_rate != link->sample_rate) {
1082 av_log(link->dst, AV_LOG_ERROR, "Sample rate change is not supported\n");
1083 goto error;
1084 }
1085
1086 927558 frame->duration = av_rescale_q(frame->nb_samples, (AVRational){ 1, frame->sample_rate },
1087 link->time_base);
1088 }
1089
1090 1473456 li->frame_blocked_in = li->frame_wanted_out = 0;
1091 1473456 li->l.frame_count_in++;
1092 1473456 li->l.sample_count_in += frame->nb_samples;
1093 1473456 filter_unblock(link->dst);
1094 1473456 ret = ff_framequeue_add(&li->fifo, frame);
1095
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1473456 times.
1473456 if (ret < 0) {
1096 av_frame_free(&frame);
1097 return ret;
1098 }
1099 1473456 ff_filter_set_ready(link->dst, 300);
1100 1473456 return 0;
1101
1102 error:
1103 av_frame_free(&frame);
1104 return AVERROR_PATCHWELCOME;
1105 }
1106
1107 2087731 static int samples_ready(FilterLinkInternal *link, unsigned min)
1108 {
1109
2/2
✓ Branch 1 taken 699065 times.
✓ Branch 2 taken 1388666 times.
2786796 return ff_framequeue_queued_frames(&link->fifo) &&
1110
2/2
✓ Branch 1 taken 104 times.
✓ Branch 2 taken 698961 times.
699065 (ff_framequeue_queued_samples(&link->fifo) >= min ||
1111
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 103 times.
104 link->status_in);
1112 }
1113
1114 2482 static int take_samples(FilterLinkInternal *li, unsigned min, unsigned max,
1115 AVFrame **rframe)
1116 {
1117 2482 FilterLink *l = &li->l;
1118 2482 AVFilterLink *link = &l->pub;
1119 AVFrame *frame0, *frame, *buf;
1120 unsigned nb_samples, nb_frames, i, p;
1121 int ret;
1122
1123 /* Note: this function relies on no format changes and must only be
1124 called with enough samples. */
1125 av_assert1(samples_ready(li, l->min_samples));
1126 2482 frame0 = frame = ff_framequeue_peek(&li->fifo, 0);
1127
6/6
✓ Branch 0 taken 926 times.
✓ Branch 1 taken 1556 times.
✓ Branch 2 taken 813 times.
✓ Branch 3 taken 113 times.
✓ Branch 4 taken 541 times.
✓ Branch 5 taken 272 times.
2482 if (!li->fifo.samples_skipped && frame->nb_samples >= min && frame->nb_samples <= max) {
1128 541 *rframe = ff_framequeue_take(&li->fifo);
1129 541 return 0;
1130 }
1131 1941 nb_frames = 0;
1132 1941 nb_samples = 0;
1133 while (1) {
1134
2/2
✓ Branch 0 taken 1558 times.
✓ Branch 1 taken 1465 times.
3023 if (nb_samples + frame->nb_samples > max) {
1135
2/2
✓ Branch 0 taken 1556 times.
✓ Branch 1 taken 2 times.
1558 if (nb_samples < min)
1136 1556 nb_samples = max;
1137 1558 break;
1138 }
1139 1465 nb_samples += frame->nb_samples;
1140 1465 nb_frames++;
1141
2/2
✓ Branch 1 taken 383 times.
✓ Branch 2 taken 1082 times.
1465 if (nb_frames == ff_framequeue_queued_frames(&li->fifo))
1142 383 break;
1143 1082 frame = ff_framequeue_peek(&li->fifo, nb_frames);
1144 }
1145
1146 1941 buf = ff_get_audio_buffer(link, nb_samples);
1147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1941 times.
1941 if (!buf)
1148 return AVERROR(ENOMEM);
1149 1941 ret = av_frame_copy_props(buf, frame0);
1150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1941 times.
1941 if (ret < 0) {
1151 av_frame_free(&buf);
1152 return ret;
1153 }
1154
1155 1941 p = 0;
1156
2/2
✓ Branch 0 taken 1465 times.
✓ Branch 1 taken 1941 times.
3406 for (i = 0; i < nb_frames; i++) {
1157 1465 frame = ff_framequeue_take(&li->fifo);
1158 1465 av_samples_copy(buf->extended_data, frame->extended_data, p, 0,
1159 1465 frame->nb_samples, link->ch_layout.nb_channels, link->format);
1160 1465 p += frame->nb_samples;
1161 1465 av_frame_free(&frame);
1162 }
1163
2/2
✓ Branch 0 taken 1556 times.
✓ Branch 1 taken 385 times.
1941 if (p < nb_samples) {
1164 1556 unsigned n = nb_samples - p;
1165 1556 frame = ff_framequeue_peek(&li->fifo, 0);
1166 1556 av_samples_copy(buf->extended_data, frame->extended_data, p, 0, n,
1167 1556 link->ch_layout.nb_channels, link->format);
1168 1556 ff_framequeue_skip_samples(&li->fifo, n, link->time_base);
1169 }
1170
1171 1941 *rframe = buf;
1172 1941 return 0;
1173 }
1174
1175 698962 static int filter_frame_to_filter(AVFilterLink *link)
1176 {
1177 698962 FilterLinkInternal * const li = ff_link_internal(link);
1178 698962 AVFrame *frame = NULL;
1179 698962 AVFilterContext *dst = link->dst;
1180 int ret;
1181
1182 av_assert1(ff_framequeue_queued_frames(&li->fifo));
1183 1397924 ret = li->l.min_samples ?
1184
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 698926 times.
698962 ff_inlink_consume_samples(link, li->l.min_samples, li->l.max_samples, &frame) :
1185 698926 ff_inlink_consume_frame(link, &frame);
1186 av_assert1(ret);
1187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 698962 times.
698962 if (ret < 0) {
1188 av_assert1(!frame);
1189 return ret;
1190 }
1191 /* The filter will soon have received a new frame, that may allow it to
1192 produce one or more: unblock its outputs. */
1193 698962 filter_unblock(dst);
1194 /* AVFilterPad.filter_frame() expect frame_count_out to have the value
1195 before the frame; filter_frame_framed() will re-increment it. */
1196 698962 li->l.frame_count_out--;
1197 698962 ret = filter_frame_framed(link, frame);
1198
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 698962 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
698962 if (ret < 0 && ret != li->status_out) {
1199 link_set_out_status(link, ret, AV_NOPTS_VALUE);
1200 } else {
1201 /* Run once again, to see if several frames were available, or if
1202 the input status has also changed, or any other reason. */
1203 698962 ff_filter_set_ready(dst, 300);
1204 }
1205 698962 return ret;
1206 }
1207
1208 5910 static int forward_status_change(AVFilterContext *filter, FilterLinkInternal *li_in)
1209 {
1210 5910 AVFilterLink *in = &li_in->l.pub;
1211 5910 unsigned out = 0, progress = 0;
1212 int ret;
1213
1214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5910 times.
5910 av_assert0(!li_in->status_out);
1215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5910 times.
5910 if (!filter->nb_outputs) {
1216 /* not necessary with the current API and sinks */
1217 return 0;
1218 }
1219
2/2
✓ Branch 0 taken 5910 times.
✓ Branch 1 taken 5910 times.
11820 while (!li_in->status_out) {
1220 5910 FilterLinkInternal *li_out = ff_link_internal(filter->outputs[out]);
1221
1222
1/2
✓ Branch 0 taken 5910 times.
✗ Branch 1 not taken.
5910 if (!li_out->status_in) {
1223 5910 progress++;
1224 5910 ret = request_frame_to_filter(filter->outputs[out]);
1225
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5910 times.
5910 if (ret < 0)
1226 return ret;
1227 }
1228
1/2
✓ Branch 0 taken 5910 times.
✗ Branch 1 not taken.
5910 if (++out == filter->nb_outputs) {
1229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5910 times.
5910 if (!progress) {
1230 /* Every output already closed: input no longer interesting
1231 (example: overlay in shortest mode, other input closed). */
1232 link_set_out_status(in, li_in->status_in, li_in->status_in_pts);
1233 return 0;
1234 }
1235 5910 progress = 0;
1236 5910 out = 0;
1237 }
1238 }
1239 5910 ff_filter_set_ready(filter, 200);
1240 5910 return 0;
1241 }
1242
1243 2094735 static int filter_activate_default(AVFilterContext *filter)
1244 {
1245 unsigned i;
1246
1247
2/2
✓ Branch 0 taken 2094735 times.
✓ Branch 1 taken 2088008 times.
4182743 for (i = 0; i < filter->nb_outputs; i++) {
1248 2094735 FilterLinkInternal *li = ff_link_internal(filter->outputs[i]);
1249 2094735 int ret = li->status_in;
1250
1251
2/2
✓ Branch 0 taken 6727 times.
✓ Branch 1 taken 2088008 times.
2094735 if (ret) {
1252
2/2
✓ Branch 0 taken 6727 times.
✓ Branch 1 taken 6727 times.
13454 for (int j = 0; j < filter->nb_inputs; j++)
1253 6727 ff_inlink_set_status(filter->inputs[j], ret);
1254 6727 return 0;
1255 }
1256 }
1257
1258
2/2
✓ Branch 0 taken 2087731 times.
✓ Branch 1 taken 1389046 times.
3476777 for (i = 0; i < filter->nb_inputs; i++) {
1259 2087731 FilterLinkInternal *li = ff_link_internal(filter->inputs[i]);
1260
2/2
✓ Branch 1 taken 698962 times.
✓ Branch 2 taken 1388769 times.
2087731 if (samples_ready(li, li->l.min_samples)) {
1261 698962 return filter_frame_to_filter(filter->inputs[i]);
1262 }
1263 }
1264
2/2
✓ Branch 0 taken 1388769 times.
✓ Branch 1 taken 1383136 times.
2771905 for (i = 0; i < filter->nb_inputs; i++) {
1265 1388769 FilterLinkInternal * const li = ff_link_internal(filter->inputs[i]);
1266
4/4
✓ Branch 0 taken 5934 times.
✓ Branch 1 taken 1382835 times.
✓ Branch 2 taken 5910 times.
✓ Branch 3 taken 24 times.
1388769 if (li->status_in && !li->status_out) {
1267 av_assert1(!ff_framequeue_queued_frames(&li->fifo));
1268 5910 return forward_status_change(filter, li);
1269 }
1270 }
1271
2/2
✓ Branch 0 taken 1383136 times.
✓ Branch 1 taken 694096 times.
2077232 for (i = 0; i < filter->nb_outputs; i++) {
1272 1383136 FilterLinkInternal * const li = ff_link_internal(filter->outputs[i]);
1273
2/2
✓ Branch 0 taken 689190 times.
✓ Branch 1 taken 693946 times.
1383136 if (li->frame_wanted_out &&
1274
2/2
✓ Branch 0 taken 689040 times.
✓ Branch 1 taken 150 times.
689190 !li->frame_blocked_in) {
1275 689040 return request_frame_to_filter(filter->outputs[i]);
1276 }
1277 }
1278 694096 return FFERROR_NOT_READY;
1279 }
1280
1281 /*
1282 Filter scheduling and activation
1283
1284 When a filter is activated, it must:
1285 - if possible, output a frame;
1286 - else, if relevant, forward the input status change;
1287 - else, check outputs for wanted frames and forward the requests.
1288
1289 The following AVFilterLink fields are used for activation:
1290
1291 - frame_wanted_out:
1292
1293 This field indicates if a frame is needed on this input of the
1294 destination filter. A positive value indicates that a frame is needed
1295 to process queued frames or internal data or to satisfy the
1296 application; a zero value indicates that a frame is not especially
1297 needed but could be processed anyway; a negative value indicates that a
1298 frame would just be queued.
1299
1300 It is set by filters using ff_request_frame() or ff_request_no_frame(),
1301 when requested by the application through a specific API or when it is
1302 set on one of the outputs.
1303
1304 It is cleared when a frame is sent from the source using
1305 ff_filter_frame().
1306
1307 It is also cleared when a status change is sent from the source using
1308 ff_avfilter_link_set_in_status().
1309
1310 - frame_blocked_in:
1311
1312 This field means that the source filter can not generate a frame as is.
1313 Its goal is to avoid repeatedly calling the request_frame() method on
1314 the same link.
1315
1316 It is set by the framework on all outputs of a filter before activating it.
1317
1318 It is automatically cleared by ff_filter_frame().
1319
1320 It is also automatically cleared by ff_avfilter_link_set_in_status().
1321
1322 It is also cleared on all outputs (using filter_unblock()) when
1323 something happens on an input: processing a frame or changing the
1324 status.
1325
1326 - fifo:
1327
1328 Contains the frames queued on a filter input. If it contains frames and
1329 frame_wanted_out is not set, then the filter can be activated. If that
1330 result in the filter not able to use these frames, the filter must set
1331 frame_wanted_out to ask for more frames.
1332
1333 - status_in and status_in_pts:
1334
1335 Status (EOF or error code) of the link and timestamp of the status
1336 change (in link time base, same as frames) as seen from the input of
1337 the link. The status change is considered happening after the frames
1338 queued in fifo.
1339
1340 It is set by the source filter using ff_avfilter_link_set_in_status().
1341
1342 - status_out:
1343
1344 Status of the link as seen from the output of the link. The status
1345 change is considered having already happened.
1346
1347 It is set by the destination filter using
1348 link_set_out_status().
1349
1350 Filters are activated according to the ready field, set using the
1351 ff_filter_set_ready(). Eventually, a priority queue will be used.
1352 ff_filter_set_ready() is called whenever anything could cause progress to
1353 be possible. Marking a filter ready when it is not is not a problem,
1354 except for the small overhead it causes.
1355
1356 Conditions that cause a filter to be marked ready are:
1357
1358 - frames added on an input link;
1359
1360 - changes in the input or output status of an input link;
1361
1362 - requests for a frame on an output link;
1363
1364 - after any actual processing using the legacy methods (filter_frame(),
1365 and request_frame() to acknowledge status changes), to run once more
1366 and check if enough input was present for several frames.
1367
1368 Examples of scenarios to consider:
1369
1370 - buffersrc: activate if frame_wanted_out to notify the application;
1371 activate when the application adds a frame to push it immediately.
1372
1373 - testsrc: activate only if frame_wanted_out to produce and push a frame.
1374
1375 - concat (not at stitch points): can process a frame on any output.
1376 Activate if frame_wanted_out on output to forward on the corresponding
1377 input. Activate when a frame is present on input to process it
1378 immediately.
1379
1380 - framesync: needs at least one frame on each input; extra frames on the
1381 wrong input will accumulate. When a frame is first added on one input,
1382 set frame_wanted_out<0 on it to avoid getting more (would trigger
1383 testsrc) and frame_wanted_out>0 on the other to allow processing it.
1384
1385 Activation of old filters:
1386
1387 In order to activate a filter implementing the legacy filter_frame() and
1388 request_frame() methods, perform the first possible of the following
1389 actions:
1390
1391 - If an input has frames in fifo and frame_wanted_out == 0, dequeue a
1392 frame and call filter_frame().
1393
1394 Rationale: filter frames as soon as possible instead of leaving them
1395 queued; frame_wanted_out < 0 is not possible since the old API does not
1396 set it nor provides any similar feedback; frame_wanted_out > 0 happens
1397 when min_samples > 0 and there are not enough samples queued.
1398
1399 - If an input has status_in set but not status_out, try to call
1400 request_frame() on one of the outputs in the hope that it will trigger
1401 request_frame() on the input with status_in and acknowledge it. This is
1402 awkward and fragile, filters with several inputs or outputs should be
1403 updated to direct activation as soon as possible.
1404
1405 - If an output has frame_wanted_out > 0 and not frame_blocked_in, call
1406 request_frame().
1407
1408 Rationale: checking frame_blocked_in is necessary to avoid requesting
1409 repeatedly on a blocked input if another is not blocked (example:
1410 [buffersrc1][testsrc1][buffersrc2][testsrc2]concat=v=2).
1411 */
1412
1413 3649441 int ff_filter_activate(AVFilterContext *filter)
1414 {
1415 3649441 FFFilterContext *ctxi = fffilterctx(filter);
1416 3649441 const FFFilter *const fi = fffilter(filter->filter);
1417 int ret;
1418
1419 /* Generic timeline support is not yet implemented but should be easy */
1420 av_assert1(!(fi->p.flags & AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC &&
1421 fi->activate));
1422 3649441 ctxi->ready = 0;
1423
2/2
✓ Branch 0 taken 1554706 times.
✓ Branch 1 taken 2094735 times.
3649441 ret = fi->activate ? fi->activate(filter) : filter_activate_default(filter);
1424
2/2
✓ Branch 0 taken 1055189 times.
✓ Branch 1 taken 2594252 times.
3649441 if (ret == FFERROR_NOT_READY)
1425 1055189 ret = 0;
1426 3649441 return ret;
1427 }
1428
1429 3300424 int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
1430 {
1431 3300424 FilterLinkInternal * const li = ff_link_internal(link);
1432 3300424 *rpts = li->l.current_pts;
1433
2/2
✓ Branch 1 taken 1970 times.
✓ Branch 2 taken 3298454 times.
3300424 if (ff_framequeue_queued_frames(&li->fifo))
1434 1970 return *rstatus = 0;
1435
2/2
✓ Branch 0 taken 1859 times.
✓ Branch 1 taken 3296595 times.
3298454 if (li->status_out)
1436 1859 return *rstatus = li->status_out;
1437
2/2
✓ Branch 0 taken 3288862 times.
✓ Branch 1 taken 7733 times.
3296595 if (!li->status_in)
1438 3288862 return *rstatus = 0;
1439 7733 *rstatus = li->status_out = li->status_in;
1440 7733 update_link_current_pts(li, li->status_in_pts);
1441 7733 *rpts = li->l.current_pts;
1442 7733 return 1;
1443 }
1444
1445 510788 size_t ff_inlink_queued_frames(AVFilterLink *link)
1446 {
1447 510788 FilterLinkInternal * const li = ff_link_internal(link);
1448 510788 return ff_framequeue_queued_frames(&li->fifo);
1449 }
1450
1451 4511235 int ff_inlink_check_available_frame(AVFilterLink *link)
1452 {
1453 4511235 FilterLinkInternal * const li = ff_link_internal(link);
1454 4511235 return ff_framequeue_queued_frames(&li->fifo) > 0;
1455 }
1456
1457 2075 int ff_inlink_queued_samples(AVFilterLink *link)
1458 {
1459 2075 FilterLinkInternal * const li = ff_link_internal(link);
1460 2075 return ff_framequeue_queued_samples(&li->fifo);
1461 }
1462
1463 4352 int ff_inlink_check_available_samples(AVFilterLink *link, unsigned min)
1464 {
1465 4352 FilterLinkInternal * const li = ff_link_internal(link);
1466 4352 uint64_t samples = ff_framequeue_queued_samples(&li->fifo);
1467 av_assert1(min);
1468
6/6
✓ Branch 0 taken 1876 times.
✓ Branch 1 taken 2476 times.
✓ Branch 2 taken 66 times.
✓ Branch 3 taken 1810 times.
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 59 times.
4352 return samples >= min || (li->status_in && samples);
1469 }
1470
1471 1473904 static void consume_update(FilterLinkInternal *li, const AVFrame *frame)
1472 {
1473 1473904 AVFilterLink *const link = &li->l.pub;
1474 1473904 update_link_current_pts(li, frame->pts);
1475 1473904 ff_inlink_process_commands(link, frame);
1476
2/2
✓ Branch 0 taken 1471531 times.
✓ Branch 1 taken 2373 times.
1473904 if (link == link->dst->inputs[0])
1477 1471531 link->dst->is_disabled = !evaluate_timeline_at_frame(link, frame);
1478 1473904 li->l.frame_count_out++;
1479 1473904 li->l.sample_count_out += frame->nb_samples;
1480 1473904 }
1481
1482 4509350 int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
1483 {
1484 4509350 FilterLinkInternal * const li = ff_link_internal(link);
1485 AVFrame *frame;
1486
1487 4509350 *rframe = NULL;
1488
2/2
✓ Branch 1 taken 3037925 times.
✓ Branch 2 taken 1471425 times.
4509350 if (!ff_inlink_check_available_frame(link))
1489 3037925 return 0;
1490
1491
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1471422 times.
1471425 if (li->fifo.samples_skipped) {
1492 3 frame = ff_framequeue_peek(&li->fifo, 0);
1493 3 return ff_inlink_consume_samples(link, frame->nb_samples, frame->nb_samples, rframe);
1494 }
1495
1496 1471422 frame = ff_framequeue_take(&li->fifo);
1497 1471422 consume_update(li, frame);
1498 1471422 *rframe = frame;
1499 1471422 return 1;
1500 }
1501
1502 4207 int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max,
1503 AVFrame **rframe)
1504 {
1505 4207 FilterLinkInternal * const li = ff_link_internal(link);
1506 AVFrame *frame;
1507 int ret;
1508
1509 av_assert1(min);
1510 4207 *rframe = NULL;
1511
2/2
✓ Branch 1 taken 1725 times.
✓ Branch 2 taken 2482 times.
4207 if (!ff_inlink_check_available_samples(link, min))
1512 1725 return 0;
1513
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2474 times.
2482 if (li->status_in)
1514
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
8 min = FFMIN(min, ff_framequeue_queued_samples(&li->fifo));
1515 2482 ret = take_samples(li, min, max, &frame);
1516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2482 times.
2482 if (ret < 0)
1517 return ret;
1518 2482 consume_update(li, frame);
1519 2482 *rframe = frame;
1520 2482 return 1;
1521 }
1522
1523 AVFrame *ff_inlink_peek_frame(AVFilterLink *link, size_t idx)
1524 {
1525 FilterLinkInternal * const li = ff_link_internal(link);
1526 return ff_framequeue_peek(&li->fifo, idx);
1527 }
1528
1529 4693 int ff_inlink_make_frame_writable(AVFilterLink *link, AVFrame **rframe)
1530 {
1531 4693 AVFrame *frame = *rframe;
1532 AVFrame *out;
1533 int ret;
1534
1535
2/2
✓ Branch 1 taken 2194 times.
✓ Branch 2 taken 2499 times.
4693 if (av_frame_is_writable(frame))
1536 2194 return 0;
1537 2499 av_log(link->dst, AV_LOG_DEBUG, "Copying data in avfilter.\n");
1538
1539
1/3
✓ Branch 0 taken 2499 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
2499 switch (link->type) {
1540 2499 case AVMEDIA_TYPE_VIDEO:
1541 2499 out = ff_get_video_buffer(link, link->w, link->h);
1542 2499 break;
1543 case AVMEDIA_TYPE_AUDIO:
1544 out = ff_get_audio_buffer(link, frame->nb_samples);
1545 break;
1546 default:
1547 return AVERROR(EINVAL);
1548 }
1549
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2499 times.
2499 if (!out)
1550 return AVERROR(ENOMEM);
1551
1552 2499 ret = av_frame_copy_props(out, frame);
1553
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2499 times.
2499 if (ret < 0) {
1554 av_frame_free(&out);
1555 return ret;
1556 }
1557
1558 2499 ret = av_frame_copy(out, frame);
1559
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2499 times.
2499 if (ret < 0) {
1560 av_frame_free(&out);
1561 return ret;
1562 }
1563
1564 2499 av_frame_free(&frame);
1565 2499 *rframe = out;
1566 2499 return 0;
1567 }
1568
1569 2172866 int ff_inlink_process_commands(AVFilterLink *link, const AVFrame *frame)
1570 {
1571 2172866 FFFilterContext *ctxi = fffilterctx(link->dst);
1572 2172866 AVFilterCommand *cmd = ctxi->command_queue;
1573
1574
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2172866 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2172866 while(cmd && cmd->time <= frame->pts * av_q2d(link->time_base)){
1575 av_log(link->dst, AV_LOG_DEBUG,
1576 "Processing command time:%f command:%s arg:%s\n",
1577 cmd->time, cmd->command, cmd->arg);
1578 avfilter_process_command(link->dst, cmd->command, cmd->arg, 0, 0, cmd->flags);
1579 command_queue_pop(link->dst);
1580 cmd = ctxi->command_queue;
1581 }
1582 2172866 return 0;
1583 }
1584
1585 766957 void ff_inlink_request_frame(AVFilterLink *link)
1586 {
1587 766957 av_unused FilterLinkInternal *li = ff_link_internal(link);
1588 av_assert1(!li->status_in);
1589 av_assert1(!li->status_out);
1590 766957 li->frame_wanted_out = 1;
1591 766957 ff_filter_set_ready(link->src, 100);
1592 766957 }
1593
1594 10687 void ff_inlink_set_status(AVFilterLink *link, int status)
1595 {
1596 10687 FilterLinkInternal * const li = ff_link_internal(link);
1597
2/2
✓ Branch 0 taken 8312 times.
✓ Branch 1 taken 2375 times.
10687 if (li->status_out)
1598 8312 return;
1599 2375 li->frame_wanted_out = 0;
1600 2375 li->frame_blocked_in = 0;
1601 2375 link_set_out_status(link, status, AV_NOPTS_VALUE);
1602
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2375 times.
2375 while (ff_framequeue_queued_frames(&li->fifo)) {
1603 AVFrame *frame = ff_framequeue_take(&li->fifo);
1604 av_frame_free(&frame);
1605 }
1606
2/2
✓ Branch 0 taken 2374 times.
✓ Branch 1 taken 1 times.
2375 if (!li->status_in)
1607 2374 li->status_in = status;
1608 }
1609
1610 1112287 int ff_outlink_get_status(AVFilterLink *link)
1611 {
1612 1112287 FilterLinkInternal * const li = ff_link_internal(link);
1613 1112287 return li->status_in;
1614 }
1615
1616 1478 int ff_inoutlink_check_flow(AVFilterLink *inlink, AVFilterLink *outlink)
1617 {
1618 1478 FilterLinkInternal * const li_in = ff_link_internal(inlink);
1619
1/2
✓ Branch 1 taken 887 times.
✗ Branch 2 not taken.
2365 return ff_outlink_frame_wanted(outlink) ||
1620
2/2
✓ Branch 0 taken 887 times.
✓ Branch 1 taken 591 times.
2365 ff_inlink_check_available_frame(inlink) ||
1621
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 860 times.
887 li_in->status_out;
1622 }
1623
1624
1625 const AVClass *avfilter_get_class(void)
1626 {
1627 return &avfilter_class;
1628 }
1629
1630 int ff_filter_init_hw_frames(AVFilterContext *avctx, AVFilterLink *link,
1631 int default_pool_size)
1632 {
1633 FilterLink *l = ff_filter_link(link);
1634 AVHWFramesContext *frames;
1635
1636 // Must already be set by caller.
1637 av_assert0(l->hw_frames_ctx);
1638
1639 frames = (AVHWFramesContext*)l->hw_frames_ctx->data;
1640
1641 if (frames->initial_pool_size == 0) {
1642 // Dynamic allocation is necessarily supported.
1643 } else if (avctx->extra_hw_frames >= 0) {
1644 frames->initial_pool_size += avctx->extra_hw_frames;
1645 } else {
1646 frames->initial_pool_size = default_pool_size;
1647 }
1648
1649 return 0;
1650 }
1651
1652 415565 int ff_outlink_frame_wanted(AVFilterLink *link)
1653 {
1654 415565 FilterLinkInternal * const li = ff_link_internal(link);
1655 415565 return li->frame_wanted_out;
1656 }
1657
1658 4182 int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func,
1659 void *arg, int *ret, int nb_jobs)
1660 {
1661 4182 return fffilterctx(ctx)->execute(ctx, func, arg, ret, nb_jobs);
1662 }
1663