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