FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_filter.c
Date: 2025-10-16 05:50:53
Exec Total Coverage
Lines: 1306 1741 75.0%
Functions: 66 72 91.7%
Branches: 770 1175 65.5%

Line Branch Exec Source
1 /*
2 * ffmpeg filter configuration
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <stdint.h>
22
23 #include "ffmpeg.h"
24 #include "graph/graphprint.h"
25
26 #include "libavfilter/avfilter.h"
27 #include "libavfilter/buffersink.h"
28 #include "libavfilter/buffersrc.h"
29
30 #include "libavutil/avassert.h"
31 #include "libavutil/avstring.h"
32 #include "libavutil/bprint.h"
33 #include "libavutil/channel_layout.h"
34 #include "libavutil/downmix_info.h"
35 #include "libavutil/mem.h"
36 #include "libavutil/opt.h"
37 #include "libavutil/pixdesc.h"
38 #include "libavutil/pixfmt.h"
39 #include "libavutil/samplefmt.h"
40 #include "libavutil/time.h"
41 #include "libavutil/timestamp.h"
42
43 // FIXME private header, used for mid_pred()
44 #include "libavcodec/mathops.h"
45
46 typedef struct FilterGraphPriv {
47 FilterGraph fg;
48
49 // name used for logging
50 char log_name[32];
51
52 int is_simple;
53 // true when the filtergraph contains only meta filters
54 // that do not modify the frame data
55 int is_meta;
56 // source filters are present in the graph
57 int have_sources;
58 int disable_conversions;
59
60 unsigned nb_outputs_done;
61
62 int nb_threads;
63
64 // frame for temporarily holding output from the filtergraph
65 AVFrame *frame;
66 // frame for sending output to the encoder
67 AVFrame *frame_enc;
68
69 Scheduler *sch;
70 unsigned sch_idx;
71 } FilterGraphPriv;
72
73 2091169 static FilterGraphPriv *fgp_from_fg(FilterGraph *fg)
74 {
75 2091169 return (FilterGraphPriv*)fg;
76 }
77
78 38060 static const FilterGraphPriv *cfgp_from_cfg(const FilterGraph *fg)
79 {
80 38060 return (const FilterGraphPriv*)fg;
81 }
82
83 // data that is local to the filter thread and not visible outside of it
84 typedef struct FilterGraphThread {
85 AVFilterGraph *graph;
86
87 AVFrame *frame;
88
89 // Temporary buffer for output frames, since on filtergraph reset
90 // we cannot send them to encoders immediately.
91 // The output index is stored in frame opaque.
92 AVFifo *frame_queue_out;
93
94 // index of the next input to request from the scheduler
95 unsigned next_in;
96 // set to 1 after at least one frame passed through this output
97 int got_frame;
98
99 // EOF status of each input/output, as received by the thread
100 uint8_t *eof_in;
101 uint8_t *eof_out;
102 } FilterGraphThread;
103
104 typedef struct InputFilterPriv {
105 InputFilter ifilter;
106
107 InputFilterOptions opts;
108
109 // used to hold submitted input
110 AVFrame *frame;
111
112 // source data type: AVMEDIA_TYPE_SUBTITLE for sub2video,
113 // same as type otherwise
114 enum AVMediaType type_src;
115
116 int eof;
117 int bound;
118 int drop_warned;
119 uint64_t nb_dropped;
120
121 // parameters configured for this input
122 int format;
123
124 int width, height;
125 AVRational sample_aspect_ratio;
126 enum AVColorSpace color_space;
127 enum AVColorRange color_range;
128 enum AVAlphaMode alpha_mode;
129
130 int sample_rate;
131 AVChannelLayout ch_layout;
132
133 AVRational time_base;
134
135 AVFrameSideData **side_data;
136 int nb_side_data;
137
138 AVFifo *frame_queue;
139
140 AVBufferRef *hw_frames_ctx;
141
142 int displaymatrix_present;
143 int displaymatrix_applied;
144 int32_t displaymatrix[9];
145
146 int downmixinfo_present;
147 AVDownmixInfo downmixinfo;
148
149 struct {
150 AVFrame *frame;
151
152 int64_t last_pts;
153 int64_t end_pts;
154
155 /// marks if sub2video_update should force an initialization
156 unsigned int initialize;
157 } sub2video;
158 } InputFilterPriv;
159
160 813637 static InputFilterPriv *ifp_from_ifilter(InputFilter *ifilter)
161 {
162 813637 return (InputFilterPriv*)ifilter;
163 }
164
165 typedef struct FPSConvContext {
166 AVFrame *last_frame;
167 /* number of frames emitted by the video-encoding sync code */
168 int64_t frame_number;
169 /* history of nb_frames_prev, i.e. the number of times the
170 * previous frame was duplicated by vsync code in recent
171 * do_video_out() calls */
172 int64_t frames_prev_hist[3];
173
174 uint64_t dup_warning;
175
176 int last_dropped;
177 int dropped_keyframe;
178
179 enum VideoSyncMethod vsync_method;
180
181 AVRational framerate;
182 AVRational framerate_max;
183 const AVRational *framerate_supported;
184 int framerate_clip;
185 } FPSConvContext;
186
187 typedef struct OutputFilterPriv {
188 OutputFilter ofilter;
189
190 void *log_parent;
191 char log_name[32];
192
193 /* desired output stream properties */
194 int format;
195 int width, height;
196 int sample_rate;
197 AVChannelLayout ch_layout;
198 enum AVColorSpace color_space;
199 enum AVColorRange color_range;
200 enum AVAlphaMode alpha_mode;
201
202 AVFrameSideData **side_data;
203 int nb_side_data;
204
205 // time base in which the output is sent to our downstream
206 // does not need to match the filtersink's timebase
207 AVRational tb_out;
208 // at least one frame with the above timebase was sent
209 // to our downstream, so it cannot change anymore
210 int tb_out_locked;
211
212 AVRational sample_aspect_ratio;
213
214 AVDictionary *sws_opts;
215 AVDictionary *swr_opts;
216
217 // those are only set if no format is specified and the encoder gives us multiple options
218 // They point directly to the relevant lists of the encoder.
219 const int *formats;
220 const AVChannelLayout *ch_layouts;
221 const int *sample_rates;
222 const enum AVColorSpace *color_spaces;
223 const enum AVColorRange *color_ranges;
224 const enum AVAlphaMode *alpha_modes;
225
226 AVRational enc_timebase;
227 int64_t trim_start_us;
228 int64_t trim_duration_us;
229 // offset for output timestamps, in AV_TIME_BASE_Q
230 int64_t ts_offset;
231 int64_t next_pts;
232 FPSConvContext fps;
233
234 unsigned flags;
235 } OutputFilterPriv;
236
237 504610 static OutputFilterPriv *ofp_from_ofilter(OutputFilter *ofilter)
238 {
239 504610 return (OutputFilterPriv*)ofilter;
240 }
241
242 typedef struct FilterCommand {
243 char *target;
244 char *command;
245 char *arg;
246
247 double time;
248 int all_filters;
249 } FilterCommand;
250
251 static void filter_command_free(void *opaque, uint8_t *data)
252 {
253 FilterCommand *fc = (FilterCommand*)data;
254
255 av_freep(&fc->target);
256 av_freep(&fc->command);
257 av_freep(&fc->arg);
258
259 av_free(data);
260 }
261
262 180 static int sub2video_get_blank_frame(InputFilterPriv *ifp)
263 {
264 180 AVFrame *frame = ifp->sub2video.frame;
265 int ret;
266
267 180 av_frame_unref(frame);
268
269 180 frame->width = ifp->width;
270 180 frame->height = ifp->height;
271 180 frame->format = ifp->format;
272 180 frame->colorspace = ifp->color_space;
273 180 frame->color_range = ifp->color_range;
274 180 frame->alpha_mode = ifp->alpha_mode;
275
276 180 ret = av_frame_get_buffer(frame, 0);
277
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 180 times.
180 if (ret < 0)
278 return ret;
279
280 180 memset(frame->data[0], 0, frame->height * frame->linesize[0]);
281
282 180 return 0;
283 }
284
285 89 static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h,
286 AVSubtitleRect *r)
287 {
288 uint32_t *pal, *dst2;
289 uint8_t *src, *src2;
290 int x, y;
291
292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 89 times.
89 if (r->type != SUBTITLE_BITMAP) {
293 av_log(NULL, AV_LOG_WARNING, "sub2video: non-bitmap subtitle\n");
294 return;
295 }
296
4/8
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 89 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 89 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 89 times.
89 if (r->x < 0 || r->x + r->w > w || r->y < 0 || r->y + r->h > h) {
297 av_log(NULL, AV_LOG_WARNING, "sub2video: rectangle (%d %d %d %d) overflowing %d %d\n",
298 r->x, r->y, r->w, r->h, w, h
299 );
300 return;
301 }
302
303 89 dst += r->y * dst_linesize + r->x * 4;
304 89 src = r->data[0];
305 89 pal = (uint32_t *)r->data[1];
306
2/2
✓ Branch 0 taken 3291 times.
✓ Branch 1 taken 89 times.
3380 for (y = 0; y < r->h; y++) {
307 3291 dst2 = (uint32_t *)dst;
308 3291 src2 = src;
309
2/2
✓ Branch 0 taken 1036075 times.
✓ Branch 1 taken 3291 times.
1039366 for (x = 0; x < r->w; x++)
310 1036075 *(dst2++) = pal[*(src2++)];
311 3291 dst += dst_linesize;
312 3291 src += r->linesize[0];
313 }
314 }
315
316 271 static void sub2video_push_ref(InputFilterPriv *ifp, int64_t pts)
317 {
318 271 AVFrame *frame = ifp->sub2video.frame;
319 int ret;
320
321 av_assert1(frame->data[0]);
322 271 ifp->sub2video.last_pts = frame->pts = pts;
323 271 ret = av_buffersrc_add_frame_flags(ifp->ifilter.filter, frame,
324 AV_BUFFERSRC_FLAG_KEEP_REF |
325 AV_BUFFERSRC_FLAG_PUSH);
326
2/4
✓ Branch 0 taken 271 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 271 times.
271 if (ret != AVERROR_EOF && ret < 0)
327 av_log(ifp->ifilter.graph, AV_LOG_WARNING,
328 "Error while add the frame to buffer source(%s).\n",
329 av_err2str(ret));
330 271 }
331
332 180 static void sub2video_update(InputFilterPriv *ifp, int64_t heartbeat_pts,
333 const AVSubtitle *sub)
334 {
335 180 AVFrame *frame = ifp->sub2video.frame;
336 int8_t *dst;
337 int dst_linesize;
338 int num_rects;
339 int64_t pts, end_pts;
340
341
2/2
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 92 times.
180 if (sub) {
342 88 pts = av_rescale_q(sub->pts + sub->start_display_time * 1000LL,
343 88 AV_TIME_BASE_Q, ifp->time_base);
344 88 end_pts = av_rescale_q(sub->pts + sub->end_display_time * 1000LL,
345 88 AV_TIME_BASE_Q, ifp->time_base);
346 88 num_rects = sub->num_rects;
347 } else {
348 /* If we are initializing the system, utilize current heartbeat
349 PTS as the start time, and show until the following subpicture
350 is received. Otherwise, utilize the previous subpicture's end time
351 as the fall-back value. */
352 184 pts = ifp->sub2video.initialize ?
353
2/2
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 4 times.
92 heartbeat_pts : ifp->sub2video.end_pts;
354 92 end_pts = INT64_MAX;
355 92 num_rects = 0;
356 }
357
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 180 times.
180 if (sub2video_get_blank_frame(ifp) < 0) {
358 av_log(ifp->ifilter.graph, AV_LOG_ERROR,
359 "Impossible to get a blank canvas.\n");
360 return;
361 }
362 180 dst = frame->data [0];
363 180 dst_linesize = frame->linesize[0];
364
2/2
✓ Branch 0 taken 89 times.
✓ Branch 1 taken 180 times.
269 for (int i = 0; i < num_rects; i++)
365 89 sub2video_copy_rect(dst, dst_linesize, frame->width, frame->height, sub->rects[i]);
366 180 sub2video_push_ref(ifp, pts);
367 180 ifp->sub2video.end_pts = end_pts;
368 180 ifp->sub2video.initialize = 0;
369 }
370
371 /* Define a function for appending a list of allowed formats
372 * to an AVBPrint. If nonempty, the list will have a header. */
373 #define DEF_CHOOSE_FORMAT(name, type, var, supported_list, none, printf_format, get_name) \
374 static void choose_ ## name (OutputFilterPriv *ofp, AVBPrint *bprint) \
375 { \
376 if (ofp->var == none && !ofp->supported_list) \
377 return; \
378 av_bprintf(bprint, #name "="); \
379 if (ofp->var != none) { \
380 av_bprintf(bprint, printf_format, get_name(ofp->var)); \
381 } else { \
382 const type *p; \
383 \
384 for (p = ofp->supported_list; *p != none; p++) { \
385 av_bprintf(bprint, printf_format "|", get_name(*p)); \
386 } \
387 if (bprint->len > 0) \
388 bprint->str[--bprint->len] = '\0'; \
389 } \
390 av_bprint_chars(bprint, ':', 1); \
391 }
392
393
9/10
✓ Branch 0 taken 1491 times.
✓ Branch 1 taken 5347 times.
✓ Branch 2 taken 1145 times.
✓ Branch 3 taken 346 times.
✓ Branch 5 taken 5347 times.
✓ Branch 6 taken 346 times.
✓ Branch 11 taken 2307 times.
✓ Branch 12 taken 346 times.
✓ Branch 13 taken 346 times.
✗ Branch 14 not taken.
9145 DEF_CHOOSE_FORMAT(pix_fmts, enum AVPixelFormat, format, formats,
394 AV_PIX_FMT_NONE, "%s", av_get_pix_fmt_name)
395
396
8/10
✓ Branch 0 taken 1337 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1337 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1337 times.
✓ Branch 11 taken 1439 times.
✓ Branch 12 taken 1337 times.
✓ Branch 13 taken 1337 times.
✗ Branch 14 not taken.
2777 DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
397 AV_SAMPLE_FMT_NONE, "%s", av_get_sample_fmt_name)
398
399
9/10
✓ Branch 0 taken 1323 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 1270 times.
✓ Branch 3 taken 53 times.
✓ Branch 5 taken 15 times.
✓ Branch 6 taken 53 times.
✓ Branch 9 taken 311 times.
✓ Branch 10 taken 53 times.
✓ Branch 11 taken 53 times.
✗ Branch 12 not taken.
1649 DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
400 "%d", )
401
402
4/10
✓ Branch 0 taken 6818 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 6818 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
6838 DEF_CHOOSE_FORMAT(color_spaces, enum AVColorSpace, color_space, color_spaces,
403 AVCOL_SPC_UNSPECIFIED, "%s", av_color_space_name);
404
405
9/10
✓ Branch 0 taken 5201 times.
✓ Branch 1 taken 1637 times.
✓ Branch 2 taken 4700 times.
✓ Branch 3 taken 501 times.
✓ Branch 5 taken 1637 times.
✓ Branch 6 taken 501 times.
✓ Branch 11 taken 538 times.
✓ Branch 12 taken 501 times.
✓ Branch 13 taken 501 times.
✗ Branch 14 not taken.
7376 DEF_CHOOSE_FORMAT(color_ranges, enum AVColorRange, color_range, color_ranges,
406 AVCOL_RANGE_UNSPECIFIED, "%s", av_color_range_name);
407
408
9/10
✓ Branch 0 taken 6830 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 6801 times.
✓ Branch 3 taken 29 times.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 29 times.
✓ Branch 11 taken 29 times.
✓ Branch 12 taken 29 times.
✓ Branch 13 taken 29 times.
✗ Branch 14 not taken.
6867 DEF_CHOOSE_FORMAT(alpha_modes, enum AVAlphaMode, alpha_mode, alpha_modes,
409 AVALPHA_MODE_UNSPECIFIED, "%s", av_alpha_mode_name);
410
411 1338 static void choose_channel_layouts(OutputFilterPriv *ofp, AVBPrint *bprint)
412 {
413
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 1326 times.
1338 if (av_channel_layout_check(&ofp->ch_layout)) {
414 12 av_bprintf(bprint, "channel_layouts=");
415 12 av_channel_layout_describe_bprint(&ofp->ch_layout, bprint);
416
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 1247 times.
1326 } else if (ofp->ch_layouts) {
417 const AVChannelLayout *p;
418
419 79 av_bprintf(bprint, "channel_layouts=");
420
2/2
✓ Branch 0 taken 386 times.
✓ Branch 1 taken 79 times.
465 for (p = ofp->ch_layouts; p->nb_channels; p++) {
421 386 av_channel_layout_describe_bprint(p, bprint);
422 386 av_bprintf(bprint, "|");
423 }
424
1/2
✓ Branch 0 taken 79 times.
✗ Branch 1 not taken.
79 if (bprint->len > 0)
425 79 bprint->str[--bprint->len] = '\0';
426 } else
427 1247 return;
428 91 av_bprint_chars(bprint, ':', 1);
429 }
430
431 static int read_binary(void *logctx, const char *path,
432 uint8_t **data, int *len)
433 {
434 AVIOContext *io = NULL;
435 int64_t fsize;
436 int ret;
437
438 *data = NULL;
439 *len = 0;
440
441 ret = avio_open2(&io, path, AVIO_FLAG_READ, &int_cb, NULL);
442 if (ret < 0) {
443 av_log(logctx, AV_LOG_ERROR, "Cannot open file '%s': %s\n",
444 path, av_err2str(ret));
445 return ret;
446 }
447
448 fsize = avio_size(io);
449 if (fsize < 0 || fsize > INT_MAX) {
450 av_log(logctx, AV_LOG_ERROR, "Cannot obtain size of file %s\n", path);
451 ret = AVERROR(EIO);
452 goto fail;
453 }
454
455 *data = av_malloc(fsize);
456 if (!*data) {
457 ret = AVERROR(ENOMEM);
458 goto fail;
459 }
460
461 ret = avio_read(io, *data, fsize);
462 if (ret != fsize) {
463 av_log(logctx, AV_LOG_ERROR, "Error reading file %s\n", path);
464 ret = ret < 0 ? ret : AVERROR(EIO);
465 goto fail;
466 }
467
468 *len = fsize;
469
470 ret = 0;
471 fail:
472 avio_close(io);
473 if (ret < 0) {
474 av_freep(data);
475 *len = 0;
476 }
477 return ret;
478 }
479
480 32203 static int filter_opt_apply(void *logctx, AVFilterContext *f,
481 const char *key, const char *val)
482 {
483 32203 const AVOption *o = NULL;
484 int ret;
485
486 32203 ret = av_opt_set(f, key, val, AV_OPT_SEARCH_CHILDREN);
487
1/2
✓ Branch 0 taken 32203 times.
✗ Branch 1 not taken.
32203 if (ret >= 0)
488 32203 return 0;
489
490 if (ret == AVERROR_OPTION_NOT_FOUND && key[0] == '/')
491 o = av_opt_find(f, key + 1, NULL, 0, AV_OPT_SEARCH_CHILDREN);
492 if (!o)
493 goto err_apply;
494
495 // key is a valid option name prefixed with '/'
496 // interpret value as a path from which to load the actual option value
497 key++;
498
499 if (o->type == AV_OPT_TYPE_BINARY) {
500 uint8_t *data;
501 int len;
502
503 ret = read_binary(logctx, val, &data, &len);
504 if (ret < 0)
505 goto err_load;
506
507 ret = av_opt_set_bin(f, key, data, len, AV_OPT_SEARCH_CHILDREN);
508 av_freep(&data);
509 } else {
510 char *data = file_read(val);
511 if (!data) {
512 ret = AVERROR(EIO);
513 goto err_load;
514 }
515
516 ret = av_opt_set(f, key, data, AV_OPT_SEARCH_CHILDREN);
517 av_freep(&data);
518 }
519 if (ret < 0)
520 goto err_apply;
521
522 return 0;
523
524 err_apply:
525 av_log(logctx, AV_LOG_ERROR,
526 "Error applying option '%s' to filter '%s': %s\n",
527 key, f->filter->name, av_err2str(ret));
528 return ret;
529 err_load:
530 av_log(logctx, AV_LOG_ERROR,
531 "Error loading value for option '%s' from file '%s'\n",
532 key, val);
533 return ret;
534 }
535
536 16042 static int graph_opts_apply(void *logctx, AVFilterGraphSegment *seg)
537 {
538
2/2
✓ Branch 0 taken 16452 times.
✓ Branch 1 taken 16042 times.
32494 for (size_t i = 0; i < seg->nb_chains; i++) {
539 16452 AVFilterChain *ch = seg->chains[i];
540
541
2/2
✓ Branch 0 taken 36541 times.
✓ Branch 1 taken 16452 times.
52993 for (size_t j = 0; j < ch->nb_filters; j++) {
542 36541 AVFilterParams *p = ch->filters[j];
543 36541 const AVDictionaryEntry *e = NULL;
544
545
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36541 times.
36541 av_assert0(p->filter);
546
547
2/2
✓ Branch 1 taken 32203 times.
✓ Branch 2 taken 36541 times.
68744 while ((e = av_dict_iterate(p->opts, e))) {
548 32203 int ret = filter_opt_apply(logctx, p->filter, e->key, e->value);
549
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32203 times.
32203 if (ret < 0)
550 return ret;
551 }
552
553 36541 av_dict_free(&p->opts);
554 }
555 }
556
557 16042 return 0;
558 }
559
560 16042 static int graph_parse(void *logctx,
561 AVFilterGraph *graph, const char *desc,
562 AVFilterInOut **inputs, AVFilterInOut **outputs,
563 AVBufferRef *hw_device)
564 {
565 AVFilterGraphSegment *seg;
566 int ret;
567
568 16042 *inputs = NULL;
569 16042 *outputs = NULL;
570
571 16042 ret = avfilter_graph_segment_parse(graph, desc, 0, &seg);
572
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16042 times.
16042 if (ret < 0)
573 return ret;
574
575 16042 ret = avfilter_graph_segment_create_filters(seg, 0);
576
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16042 times.
16042 if (ret < 0)
577 goto fail;
578
579
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16042 times.
16042 if (hw_device) {
580 for (int i = 0; i < graph->nb_filters; i++) {
581 AVFilterContext *f = graph->filters[i];
582
583 if (!(f->filter->flags & AVFILTER_FLAG_HWDEVICE))
584 continue;
585 f->hw_device_ctx = av_buffer_ref(hw_device);
586 if (!f->hw_device_ctx) {
587 ret = AVERROR(ENOMEM);
588 goto fail;
589 }
590 }
591 }
592
593 16042 ret = graph_opts_apply(logctx, seg);
594
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16042 times.
16042 if (ret < 0)
595 goto fail;
596
597 16042 ret = avfilter_graph_segment_apply(seg, 0, inputs, outputs);
598
599 16042 fail:
600 16042 avfilter_graph_segment_free(&seg);
601 16042 return ret;
602 }
603
604 // Filters can be configured only if the formats of all inputs are known.
605 15019 static int ifilter_has_all_input_formats(FilterGraph *fg)
606 {
607
2/2
✓ Branch 0 taken 14222 times.
✓ Branch 1 taken 8045 times.
22267 for (int i = 0; i < fg->nb_inputs; i++) {
608 14222 InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[i]);
609
2/2
✓ Branch 0 taken 6974 times.
✓ Branch 1 taken 7248 times.
14222 if (ifp->format < 0)
610 6974 return 0;
611 }
612 8045 return 1;
613 }
614
615 static int filter_thread(void *arg);
616
617 15075 static char *describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in)
618 {
619 15075 AVFilterContext *ctx = inout->filter_ctx;
620
2/2
✓ Branch 0 taken 6945 times.
✓ Branch 1 taken 8130 times.
15075 AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads;
621
2/2
✓ Branch 0 taken 6945 times.
✓ Branch 1 taken 8130 times.
15075 int nb_pads = in ? ctx->nb_inputs : ctx->nb_outputs;
622
623
2/2
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 14937 times.
15075 if (nb_pads > 1)
624 138 return av_strdup(ctx->filter->name);
625 14937 return av_asprintf("%s:%s", ctx->filter->name,
626 avfilter_pad_get_name(pads, inout->pad_idx));
627 }
628
629 3 static const char *ofilter_item_name(void *obj)
630 {
631 3 OutputFilterPriv *ofp = obj;
632 3 return ofp->log_name;
633 }
634
635 static const AVClass ofilter_class = {
636 .class_name = "OutputFilter",
637 .version = LIBAVUTIL_VERSION_INT,
638 .item_name = ofilter_item_name,
639 .parent_log_context_offset = offsetof(OutputFilterPriv, log_parent),
640 .category = AV_CLASS_CATEGORY_FILTER,
641 };
642
643 8130 static OutputFilter *ofilter_alloc(FilterGraph *fg, enum AVMediaType type)
644 {
645 OutputFilterPriv *ofp;
646 OutputFilter *ofilter;
647
648 8130 ofp = allocate_array_elem(&fg->outputs, sizeof(*ofp), &fg->nb_outputs);
649
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8130 times.
8130 if (!ofp)
650 return NULL;
651
652 8130 ofilter = &ofp->ofilter;
653 8130 ofilter->class = &ofilter_class;
654 8130 ofp->log_parent = fg;
655 8130 ofilter->graph = fg;
656 8130 ofilter->type = type;
657 8130 ofp->format = -1;
658 8130 ofp->color_space = AVCOL_SPC_UNSPECIFIED;
659 8130 ofp->color_range = AVCOL_RANGE_UNSPECIFIED;
660 8130 ofp->alpha_mode = AVALPHA_MODE_UNSPECIFIED;
661 8130 ofilter->index = fg->nb_outputs - 1;
662
663 16260 snprintf(ofp->log_name, sizeof(ofp->log_name), "%co%d",
664 8130 av_get_media_type_string(type)[0], ofilter->index);
665
666 8130 return ofilter;
667 }
668
669 6944 static int ifilter_bind_ist(InputFilter *ifilter, InputStream *ist,
670 const ViewSpecifier *vs)
671 {
672 6944 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
673 6944 FilterGraphPriv *fgp = fgp_from_fg(ifilter->graph);
674 SchedulerNode src;
675 int ret;
676
677
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6944 times.
6944 av_assert0(!ifp->bound);
678 6944 ifp->bound = 1;
679
680
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6940 times.
6944 if (ifilter->type != ist->par->codec_type &&
681
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 !(ifilter->type == AVMEDIA_TYPE_VIDEO && ist->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
682 av_log(fgp, AV_LOG_ERROR, "Tried to connect %s stream to %s filtergraph input\n",
683 av_get_media_type_string(ist->par->codec_type), av_get_media_type_string(ifilter->type));
684 return AVERROR(EINVAL);
685 }
686
687 6944 ifp->type_src = ist->st->codecpar->codec_type;
688
689 6944 ifp->opts.fallback = av_frame_alloc();
690
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6944 times.
6944 if (!ifp->opts.fallback)
691 return AVERROR(ENOMEM);
692
693 6944 ret = ist_filter_add(ist, ifilter, filtergraph_is_simple(ifilter->graph),
694 vs, &ifp->opts, &src);
695
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6944 times.
6944 if (ret < 0)
696 return ret;
697
698 6944 ifilter->input_name = av_strdup(ifp->opts.name);
699
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6944 times.
6944 if (!ifilter->input_name)
700 return AVERROR(EINVAL);
701
702 6944 ret = sch_connect(fgp->sch,
703 6944 src, SCH_FILTER_IN(fgp->sch_idx, ifilter->index));
704
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6944 times.
6944 if (ret < 0)
705 return ret;
706
707
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6940 times.
6944 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
708 4 ifp->sub2video.frame = av_frame_alloc();
709
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!ifp->sub2video.frame)
710 return AVERROR(ENOMEM);
711
712 4 ifp->width = ifp->opts.sub2video_width;
713 4 ifp->height = ifp->opts.sub2video_height;
714
715 /* rectangles are AV_PIX_FMT_PAL8, but we have no guarantee that the
716 palettes for all rectangles are identical or compatible */
717 4 ifp->format = AV_PIX_FMT_RGB32;
718
719 4 ifp->time_base = AV_TIME_BASE_Q;
720
721 4 av_log(fgp, AV_LOG_VERBOSE, "sub2video: using %dx%d canvas\n",
722 ifp->width, ifp->height);
723 }
724
725 6944 return 0;
726 }
727
728 1 static int ifilter_bind_dec(InputFilterPriv *ifp, Decoder *dec,
729 const ViewSpecifier *vs)
730 {
731 1 FilterGraphPriv *fgp = fgp_from_fg(ifp->ifilter.graph);
732 SchedulerNode src;
733 int ret;
734
735
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 av_assert0(!ifp->bound);
736 1 ifp->bound = 1;
737
738
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ifp->ifilter.type != dec->type) {
739 av_log(fgp, AV_LOG_ERROR, "Tried to connect %s decoder to %s filtergraph input\n",
740 av_get_media_type_string(dec->type), av_get_media_type_string(ifp->ifilter.type));
741 return AVERROR(EINVAL);
742 }
743
744 1 ifp->type_src = ifp->ifilter.type;
745
746 1 ret = dec_filter_add(dec, &ifp->ifilter, &ifp->opts, vs, &src);
747
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
748 return ret;
749
750 1 ifp->ifilter.input_name = av_strdup(ifp->opts.name);
751
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!ifp->ifilter.input_name)
752 return AVERROR(EINVAL);
753
754 1 ret = sch_connect(fgp->sch, src, SCH_FILTER_IN(fgp->sch_idx, ifp->ifilter.index));
755
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
756 return ret;
757
758 1 return 0;
759 }
760
761 11 static int set_channel_layout(OutputFilterPriv *f, const AVChannelLayout *layouts_allowed,
762 const AVChannelLayout *layout_requested)
763 {
764 int i, err;
765
766
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10 times.
11 if (layout_requested->order != AV_CHANNEL_ORDER_UNSPEC) {
767 /* Pass the layout through for all orders but UNSPEC */
768 1 err = av_channel_layout_copy(&f->ch_layout, layout_requested);
769
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (err < 0)
770 return err;
771 1 return 0;
772 }
773
774 /* Requested layout is of order UNSPEC */
775
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if (!layouts_allowed) {
776 /* Use the default native layout for the requested amount of channels when the
777 encoder doesn't have a list of supported layouts */
778 10 av_channel_layout_default(&f->ch_layout, layout_requested->nb_channels);
779 10 return 0;
780 }
781 /* Encoder has a list of supported layouts. Pick the first layout in it with the
782 same amount of channels as the requested layout */
783 for (i = 0; layouts_allowed[i].nb_channels; i++) {
784 if (layouts_allowed[i].nb_channels == layout_requested->nb_channels)
785 break;
786 }
787 if (layouts_allowed[i].nb_channels) {
788 /* Use it if one is found */
789 err = av_channel_layout_copy(&f->ch_layout, &layouts_allowed[i]);
790 if (err < 0)
791 return err;
792 return 0;
793 }
794 /* If no layout for the amount of channels requested was found, use the default
795 native layout for it. */
796 av_channel_layout_default(&f->ch_layout, layout_requested->nb_channels);
797
798 return 0;
799 }
800
801 8130 int ofilter_bind_enc(OutputFilter *ofilter, unsigned sched_idx_enc,
802 const OutputFilterOptions *opts)
803 {
804 8130 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
805 8130 FilterGraph *fg = ofilter->graph;
806 8130 FilterGraphPriv *fgp = fgp_from_fg(fg);
807 int ret;
808
809
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8130 times.
8130 av_assert0(!ofilter->bound);
810
2/4
✓ Branch 0 taken 8130 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8130 times.
8130 av_assert0(!opts->enc ||
811 ofilter->type == opts->enc->type);
812
813 8130 ofilter->bound = 1;
814 8130 av_freep(&ofilter->linklabel);
815
816 8130 ofp->flags = opts->flags;
817 8130 ofp->ts_offset = opts->ts_offset;
818 8130 ofp->enc_timebase = opts->output_tb;
819
820 8130 ofp->trim_start_us = opts->trim_start_us;
821 8130 ofp->trim_duration_us = opts->trim_duration_us;
822
823 8130 ofilter->output_name = av_strdup(opts->name);
824
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8130 times.
8130 if (!ofilter->output_name)
825 return AVERROR(EINVAL);
826
827 8130 ret = av_dict_copy(&ofp->sws_opts, opts->sws_opts, 0);
828
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8130 times.
8130 if (ret < 0)
829 return ret;
830
831 8130 ret = av_dict_copy(&ofp->swr_opts, opts->swr_opts, 0);
832
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8130 times.
8130 if (ret < 0)
833 return ret;
834
835
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 8071 times.
8130 if (opts->flags & OFILTER_FLAG_AUDIO_24BIT)
836 59 av_dict_set(&ofp->swr_opts, "output_sample_bits", "24", 0);
837
838
2/2
✓ Branch 0 taken 6793 times.
✓ Branch 1 taken 1337 times.
8130 if (fgp->is_simple) {
839 // for simple filtergraph there is just one output,
840 // so use only graph-level information for logging
841 6793 ofp->log_parent = NULL;
842 6793 av_strlcpy(ofp->log_name, fgp->log_name, sizeof(ofp->log_name));
843 } else
844 1337 av_strlcatf(ofp->log_name, sizeof(ofp->log_name), "->%s", ofilter->output_name);
845
846
2/3
✓ Branch 0 taken 6793 times.
✓ Branch 1 taken 1337 times.
✗ Branch 2 not taken.
8130 switch (ofilter->type) {
847 6793 case AVMEDIA_TYPE_VIDEO:
848 6793 ofp->width = opts->width;
849 6793 ofp->height = opts->height;
850
2/2
✓ Branch 0 taken 5302 times.
✓ Branch 1 taken 1491 times.
6793 if (opts->format != AV_PIX_FMT_NONE) {
851 5302 ofp->format = opts->format;
852 } else
853 1491 ofp->formats = opts->formats;
854
855
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6793 times.
6793 if (opts->color_space != AVCOL_SPC_UNSPECIFIED)
856 ofp->color_space = opts->color_space;
857 else
858 6793 ofp->color_spaces = opts->color_spaces;
859
860
2/2
✓ Branch 0 taken 1607 times.
✓ Branch 1 taken 5186 times.
6793 if (opts->color_range != AVCOL_RANGE_UNSPECIFIED)
861 1607 ofp->color_range = opts->color_range;
862 else
863 5186 ofp->color_ranges = opts->color_ranges;
864
865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6793 times.
6793 if (opts->alpha_mode != AVALPHA_MODE_UNSPECIFIED)
866 ofp->alpha_mode = opts->alpha_mode;
867 else
868 6793 ofp->alpha_modes = opts->alpha_modes;
869
870 6793 fgp->disable_conversions |= !!(ofp->flags & OFILTER_FLAG_DISABLE_CONVERT);
871
872 6793 ofp->fps.last_frame = av_frame_alloc();
873
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6793 times.
6793 if (!ofp->fps.last_frame)
874 return AVERROR(ENOMEM);
875
876 6793 ofp->fps.vsync_method = opts->vsync_method;
877 6793 ofp->fps.framerate = opts->frame_rate;
878 6793 ofp->fps.framerate_max = opts->max_frame_rate;
879 6793 ofp->fps.framerate_supported = opts->frame_rates;
880
881 // reduce frame rate for mpeg4 to be within the spec limits
882
3/4
✓ Branch 0 taken 6793 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 63 times.
✓ Branch 3 taken 6730 times.
6793 if (opts->enc && opts->enc->id == AV_CODEC_ID_MPEG4)
883 63 ofp->fps.framerate_clip = 65535;
884
885 6793 ofp->fps.dup_warning = 1000;
886
887 6793 break;
888 1337 case AVMEDIA_TYPE_AUDIO:
889
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1337 times.
1337 if (opts->format != AV_SAMPLE_FMT_NONE) {
890 ofp->format = opts->format;
891 } else {
892 1337 ofp->formats = opts->formats;
893 }
894
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 1323 times.
1337 if (opts->sample_rate) {
895 14 ofp->sample_rate = opts->sample_rate;
896 } else
897 1323 ofp->sample_rates = opts->sample_rates;
898
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 1326 times.
1337 if (opts->ch_layout.nb_channels) {
899 11 int ret = set_channel_layout(ofp, opts->ch_layouts, &opts->ch_layout);
900
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (ret < 0)
901 return ret;
902 } else {
903 1326 ofp->ch_layouts = opts->ch_layouts;
904 }
905 1337 break;
906 }
907
908 8130 ret = sch_connect(fgp->sch, SCH_FILTER_OUT(fgp->sch_idx, ofilter->index),
909 8130 SCH_ENC(sched_idx_enc));
910
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8130 times.
8130 if (ret < 0)
911 return ret;
912
913 8130 return 0;
914 }
915
916 static int ofilter_bind_ifilter(OutputFilter *ofilter, InputFilterPriv *ifp,
917 const OutputFilterOptions *opts)
918 {
919 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
920
921 av_assert0(!ofilter->bound);
922 av_assert0(ofilter->type == ifp->ifilter.type);
923
924 ofilter->bound = 1;
925 av_freep(&ofilter->linklabel);
926
927 ofilter->output_name = av_strdup(opts->name);
928 if (!ofilter->output_name)
929 return AVERROR(EINVAL);
930
931 av_strlcatf(ofp->log_name, sizeof(ofp->log_name), "->%s", ofilter->output_name);
932
933 return 0;
934 }
935
936 static int ifilter_bind_fg(InputFilterPriv *ifp, FilterGraph *fg_src, int out_idx)
937 {
938 FilterGraphPriv *fgp = fgp_from_fg(ifp->ifilter.graph);
939 OutputFilter *ofilter_src = fg_src->outputs[out_idx];
940 OutputFilterOptions opts;
941 char name[32];
942 int ret;
943
944 av_assert0(!ifp->bound);
945 ifp->bound = 1;
946
947 if (ifp->ifilter.type != ofilter_src->type) {
948 av_log(fgp, AV_LOG_ERROR, "Tried to connect %s output to %s input\n",
949 av_get_media_type_string(ofilter_src->type),
950 av_get_media_type_string(ifp->ifilter.type));
951 return AVERROR(EINVAL);
952 }
953
954 ifp->type_src = ifp->ifilter.type;
955
956 memset(&opts, 0, sizeof(opts));
957
958 snprintf(name, sizeof(name), "fg:%d:%d", fgp->fg.index, ifp->ifilter.index);
959 opts.name = name;
960
961 ret = ofilter_bind_ifilter(ofilter_src, ifp, &opts);
962 if (ret < 0)
963 return ret;
964
965 ret = sch_connect(fgp->sch, SCH_FILTER_OUT(fg_src->index, out_idx),
966 SCH_FILTER_IN(fgp->sch_idx, ifp->ifilter.index));
967 if (ret < 0)
968 return ret;
969
970 return 0;
971 }
972
973 6945 static InputFilter *ifilter_alloc(FilterGraph *fg)
974 {
975 InputFilterPriv *ifp;
976 InputFilter *ifilter;
977
978 6945 ifp = allocate_array_elem(&fg->inputs, sizeof(*ifp), &fg->nb_inputs);
979
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6945 times.
6945 if (!ifp)
980 return NULL;
981
982 6945 ifilter = &ifp->ifilter;
983 6945 ifilter->graph = fg;
984
985 6945 ifp->frame = av_frame_alloc();
986
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6945 times.
6945 if (!ifp->frame)
987 return NULL;
988
989 6945 ifilter->index = fg->nb_inputs - 1;
990 6945 ifp->format = -1;
991 6945 ifp->color_space = AVCOL_SPC_UNSPECIFIED;
992 6945 ifp->color_range = AVCOL_RANGE_UNSPECIFIED;
993 6945 ifp->alpha_mode = AVALPHA_MODE_UNSPECIFIED;
994
995 6945 ifp->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
996
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6945 times.
6945 if (!ifp->frame_queue)
997 return NULL;
998
999 6945 return ifilter;
1000 }
1001
1002 10101 void fg_free(FilterGraph **pfg)
1003 {
1004 10101 FilterGraph *fg = *pfg;
1005 FilterGraphPriv *fgp;
1006
1007
2/2
✓ Branch 0 taken 2103 times.
✓ Branch 1 taken 7998 times.
10101 if (!fg)
1008 2103 return;
1009 7998 fgp = fgp_from_fg(fg);
1010
1011
2/2
✓ Branch 0 taken 6945 times.
✓ Branch 1 taken 7998 times.
14943 for (int j = 0; j < fg->nb_inputs; j++) {
1012 6945 InputFilter *ifilter = fg->inputs[j];
1013 6945 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1014
1015
1/2
✓ Branch 0 taken 6945 times.
✗ Branch 1 not taken.
6945 if (ifp->frame_queue) {
1016 AVFrame *frame;
1017
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6945 times.
6945 while (av_fifo_read(ifp->frame_queue, &frame, 1) >= 0)
1018 av_frame_free(&frame);
1019 6945 av_fifo_freep2(&ifp->frame_queue);
1020 }
1021 6945 av_frame_free(&ifp->sub2video.frame);
1022
1023 6945 av_frame_free(&ifp->frame);
1024 6945 av_frame_free(&ifp->opts.fallback);
1025
1026 6945 av_buffer_unref(&ifp->hw_frames_ctx);
1027 6945 av_freep(&ifilter->linklabel);
1028 6945 av_freep(&ifp->opts.name);
1029 6945 av_frame_side_data_free(&ifp->side_data, &ifp->nb_side_data);
1030 6945 av_freep(&ifilter->name);
1031 6945 av_freep(&ifilter->input_name);
1032 6945 av_freep(&fg->inputs[j]);
1033 }
1034 7998 av_freep(&fg->inputs);
1035
2/2
✓ Branch 0 taken 8130 times.
✓ Branch 1 taken 7998 times.
16128 for (int j = 0; j < fg->nb_outputs; j++) {
1036 8130 OutputFilter *ofilter = fg->outputs[j];
1037 8130 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1038
1039 8130 av_frame_free(&ofp->fps.last_frame);
1040 8130 av_dict_free(&ofp->sws_opts);
1041 8130 av_dict_free(&ofp->swr_opts);
1042
1043 8130 av_freep(&ofilter->linklabel);
1044 8130 av_freep(&ofilter->name);
1045 8130 av_freep(&ofilter->output_name);
1046 8130 av_freep(&ofilter->apad);
1047 8130 av_channel_layout_uninit(&ofp->ch_layout);
1048 8130 av_frame_side_data_free(&ofp->side_data, &ofp->nb_side_data);
1049 8130 av_freep(&fg->outputs[j]);
1050 }
1051 7998 av_freep(&fg->outputs);
1052 7998 av_freep(&fg->graph_desc);
1053
1054 7998 av_frame_free(&fgp->frame);
1055 7998 av_frame_free(&fgp->frame_enc);
1056
1057 7998 av_freep(pfg);
1058 }
1059
1060 54 static const char *fg_item_name(void *obj)
1061 {
1062 54 const FilterGraphPriv *fgp = obj;
1063
1064 54 return fgp->log_name;
1065 }
1066
1067 static const AVClass fg_class = {
1068 .class_name = "FilterGraph",
1069 .version = LIBAVUTIL_VERSION_INT,
1070 .item_name = fg_item_name,
1071 .category = AV_CLASS_CATEGORY_FILTER,
1072 };
1073
1074 7998 int fg_create(FilterGraph **pfg, char *graph_desc, Scheduler *sch)
1075 {
1076 FilterGraphPriv *fgp;
1077 FilterGraph *fg;
1078
1079 AVFilterInOut *inputs, *outputs;
1080 AVFilterGraph *graph;
1081 7998 int ret = 0;
1082
1083 7998 fgp = av_mallocz(sizeof(*fgp));
1084
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7998 times.
7998 if (!fgp) {
1085 av_freep(&graph_desc);
1086 return AVERROR(ENOMEM);
1087 }
1088 7998 fg = &fgp->fg;
1089
1090
2/2
✓ Branch 0 taken 6793 times.
✓ Branch 1 taken 1205 times.
7998 if (pfg) {
1091 6793 *pfg = fg;
1092 6793 fg->index = -1;
1093 } else {
1094 1205 ret = av_dynarray_add_nofree(&filtergraphs, &nb_filtergraphs, fgp);
1095
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1205 times.
1205 if (ret < 0) {
1096 av_freep(&graph_desc);
1097 av_freep(&fgp);
1098 return ret;
1099 }
1100
1101 1205 fg->index = nb_filtergraphs - 1;
1102 }
1103
1104 7998 fg->class = &fg_class;
1105 7998 fg->graph_desc = graph_desc;
1106 7998 fgp->disable_conversions = !auto_conversion_filters;
1107 7998 fgp->nb_threads = -1;
1108 7998 fgp->sch = sch;
1109
1110 7998 snprintf(fgp->log_name, sizeof(fgp->log_name), "fc#%d", fg->index);
1111
1112 7998 fgp->frame = av_frame_alloc();
1113 7998 fgp->frame_enc = av_frame_alloc();
1114
2/4
✓ Branch 0 taken 7998 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7998 times.
7998 if (!fgp->frame || !fgp->frame_enc)
1115 return AVERROR(ENOMEM);
1116
1117 /* this graph is only used for determining the kinds of inputs
1118 * and outputs we have, and is discarded on exit from this function */
1119 7998 graph = avfilter_graph_alloc();
1120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7998 times.
7998 if (!graph)
1121 return AVERROR(ENOMEM);;
1122 7998 graph->nb_threads = 1;
1123
1124 7998 ret = graph_parse(fg, graph, fg->graph_desc, &inputs, &outputs,
1125 hw_device_for_filter());
1126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7998 times.
7998 if (ret < 0)
1127 goto fail;
1128
1129
2/2
✓ Branch 0 taken 14843 times.
✓ Branch 1 taken 6848 times.
21691 for (unsigned i = 0; i < graph->nb_filters; i++) {
1130 14843 const AVFilter *f = graph->filters[i]->filter;
1131
2/2
✓ Branch 1 taken 1168 times.
✓ Branch 2 taken 13675 times.
14843 if ((!avfilter_filter_pad_count(f, 0) &&
1132
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 1149 times.
1168 !(f->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)) ||
1133
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 13693 times.
13694 !strcmp(f->name, "apad")) {
1134 1150 fgp->have_sources = 1;
1135 1150 break;
1136 }
1137 }
1138
1139
2/2
✓ Branch 0 taken 6945 times.
✓ Branch 1 taken 7998 times.
14943 for (AVFilterInOut *cur = inputs; cur; cur = cur->next) {
1140 6945 InputFilter *const ifilter = ifilter_alloc(fg);
1141
1142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6945 times.
6945 if (!ifilter) {
1143 ret = AVERROR(ENOMEM);
1144 goto fail;
1145 }
1146
1147 6945 ifilter->linklabel = cur->name;
1148 6945 cur->name = NULL;
1149
1150 6945 ifilter->type = avfilter_pad_get_type(cur->filter_ctx->input_pads,
1151 cur->pad_idx);
1152
1153
3/4
✓ Branch 0 taken 1269 times.
✓ Branch 1 taken 5676 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1269 times.
6945 if (ifilter->type != AVMEDIA_TYPE_VIDEO && ifilter->type != AVMEDIA_TYPE_AUDIO) {
1154 av_log(fg, AV_LOG_FATAL, "Only video and audio filters supported "
1155 "currently.\n");
1156 ret = AVERROR(ENOSYS);
1157 goto fail;
1158 }
1159
1160 6945 ifilter->name = describe_filter_link(fg, cur, 1);
1161
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6945 times.
6945 if (!ifilter->name) {
1162 ret = AVERROR(ENOMEM);
1163 goto fail;
1164 }
1165 }
1166
1167
2/2
✓ Branch 0 taken 8130 times.
✓ Branch 1 taken 7998 times.
16128 for (AVFilterInOut *cur = outputs; cur; cur = cur->next) {
1168 8130 const enum AVMediaType type = avfilter_pad_get_type(cur->filter_ctx->output_pads,
1169 cur->pad_idx);
1170 8130 OutputFilter *const ofilter = ofilter_alloc(fg, type);
1171
1172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8130 times.
8130 if (!ofilter) {
1173 ret = AVERROR(ENOMEM);
1174 goto fail;
1175 }
1176
1177 8130 ofilter->linklabel = cur->name;
1178 8130 cur->name = NULL;
1179
1180 8130 ofilter->name = describe_filter_link(fg, cur, 0);
1181
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8130 times.
8130 if (!ofilter->name) {
1182 ret = AVERROR(ENOMEM);
1183 goto fail;
1184 }
1185 }
1186
1187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7998 times.
7998 if (!fg->nb_outputs) {
1188 av_log(fg, AV_LOG_FATAL, "A filtergraph has zero outputs, this is not supported\n");
1189 ret = AVERROR(ENOSYS);
1190 goto fail;
1191 }
1192
1193 7998 ret = sch_add_filtergraph(sch, fg->nb_inputs, fg->nb_outputs,
1194 filter_thread, fgp);
1195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7998 times.
7998 if (ret < 0)
1196 goto fail;
1197 7998 fgp->sch_idx = ret;
1198
1199 7998 fail:
1200 7998 avfilter_inout_free(&inputs);
1201 7998 avfilter_inout_free(&outputs);
1202 7998 avfilter_graph_free(&graph);
1203
1204
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7998 times.
7998 if (ret < 0)
1205 return ret;
1206
1207 7998 return 0;
1208 }
1209
1210 6793 int fg_create_simple(FilterGraph **pfg,
1211 InputStream *ist,
1212 char *graph_desc,
1213 Scheduler *sch, unsigned sched_idx_enc,
1214 const OutputFilterOptions *opts)
1215 {
1216 6793 const enum AVMediaType type = ist->par->codec_type;
1217 FilterGraph *fg;
1218 FilterGraphPriv *fgp;
1219 int ret;
1220
1221 6793 ret = fg_create(pfg, graph_desc, sch);
1222
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6793 times.
6793 if (ret < 0)
1223 return ret;
1224 6793 fg = *pfg;
1225 6793 fgp = fgp_from_fg(fg);
1226
1227 6793 fgp->is_simple = 1;
1228
1229 6793 snprintf(fgp->log_name, sizeof(fgp->log_name), "%cf%s",
1230 6793 av_get_media_type_string(type)[0], opts->name);
1231
1232
2/4
✓ Branch 0 taken 6793 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6793 times.
6793 if (fg->nb_inputs != 1 || fg->nb_outputs != 1) {
1233 av_log(fg, AV_LOG_ERROR, "Simple filtergraph '%s' was expected "
1234 "to have exactly 1 input and 1 output. "
1235 "However, it had %d input(s) and %d output(s). Please adjust, "
1236 "or use a complex filtergraph (-filter_complex) instead.\n",
1237 graph_desc, fg->nb_inputs, fg->nb_outputs);
1238 return AVERROR(EINVAL);
1239 }
1240
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6793 times.
6793 if (fg->outputs[0]->type != type) {
1241 av_log(fg, AV_LOG_ERROR, "Filtergraph has a %s output, cannot connect "
1242 "it to %s output stream\n",
1243 av_get_media_type_string(fg->outputs[0]->type),
1244 av_get_media_type_string(type));
1245 return AVERROR(EINVAL);
1246 }
1247
1248 6793 ret = ifilter_bind_ist(fg->inputs[0], ist, opts->vs);
1249
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6793 times.
6793 if (ret < 0)
1250 return ret;
1251
1252 6793 ret = ofilter_bind_enc(fg->outputs[0], sched_idx_enc, opts);
1253
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6793 times.
6793 if (ret < 0)
1254 return ret;
1255
1256
2/2
✓ Branch 0 taken 4246 times.
✓ Branch 1 taken 2547 times.
6793 if (opts->nb_threads >= 0)
1257 4246 fgp->nb_threads = opts->nb_threads;
1258
1259 6793 return 0;
1260 }
1261
1262 152 static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter)
1263 {
1264 152 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1265 152 InputStream *ist = NULL;
1266 152 enum AVMediaType type = ifilter->type;
1267 152 ViewSpecifier vs = { .type = VIEW_SPECIFIER_TYPE_NONE };
1268 const char *spec;
1269 char *p;
1270 int i, ret;
1271
1272
4/4
✓ Branch 0 taken 95 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 94 times.
152 if (ifilter->linklabel && !strncmp(ifilter->linklabel, "dec:", 4)) {
1273 // bind to a standalone decoder
1274 int dec_idx;
1275
1276 1 dec_idx = strtol(ifilter->linklabel + 4, &p, 0);
1277
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (dec_idx < 0 || dec_idx >= nb_decoders) {
1278 av_log(fg, AV_LOG_ERROR, "Invalid decoder index %d in filtergraph description %s\n",
1279 dec_idx, fg->graph_desc);
1280 return AVERROR(EINVAL);
1281 }
1282
1283
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (type == AVMEDIA_TYPE_VIDEO) {
1284
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 spec = *p == ':' ? p + 1 : p;
1285 1 ret = view_specifier_parse(&spec, &vs);
1286
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
1287 return ret;
1288 }
1289
1290 1 ret = ifilter_bind_dec(ifp, decoders[dec_idx], &vs);
1291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
1292 av_log(fg, AV_LOG_ERROR, "Error binding a decoder to filtergraph input %s\n",
1293 ifilter->name);
1294 1 return ret;
1295
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 57 times.
151 } else if (ifilter->linklabel) {
1296 StreamSpecifier ss;
1297 AVFormatContext *s;
1298 94 AVStream *st = NULL;
1299 int file_idx;
1300
1301 // try finding an unbound filtergraph output with this label
1302
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 94 times.
188 for (int i = 0; i < nb_filtergraphs; i++) {
1303 94 FilterGraph *fg_src = filtergraphs[i];
1304
1305
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 if (fg == fg_src)
1306 94 continue;
1307
1308 for (int j = 0; j < fg_src->nb_outputs; j++) {
1309 OutputFilter *ofilter = fg_src->outputs[j];
1310
1311 if (!ofilter->bound && ofilter->linklabel &&
1312 !strcmp(ofilter->linklabel, ifilter->linklabel)) {
1313 av_log(fg, AV_LOG_VERBOSE,
1314 "Binding input with label '%s' to filtergraph output %d:%d\n",
1315 ifilter->linklabel, i, j);
1316
1317 ret = ifilter_bind_fg(ifp, fg_src, j);
1318 if (ret < 0)
1319 av_log(fg, AV_LOG_ERROR, "Error binding filtergraph input %s\n",
1320 ifilter->linklabel);
1321 return ret;
1322 }
1323 }
1324 }
1325
1326 // bind to an explicitly specified demuxer stream
1327 94 file_idx = strtol(ifilter->linklabel, &p, 0);
1328
2/4
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 94 times.
94 if (file_idx < 0 || file_idx >= nb_input_files) {
1329 av_log(fg, AV_LOG_FATAL, "Invalid file index %d in filtergraph description %s.\n",
1330 file_idx, fg->graph_desc);
1331 return AVERROR(EINVAL);
1332 }
1333 94 s = input_files[file_idx]->ctx;
1334
1335
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 4 times.
94 ret = stream_specifier_parse(&ss, *p == ':' ? p + 1 : p, 1, fg);
1336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
94 if (ret < 0) {
1337 av_log(fg, AV_LOG_ERROR, "Invalid stream specifier: %s\n", p);
1338 return ret;
1339 }
1340
1341
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 73 times.
94 if (type == AVMEDIA_TYPE_VIDEO) {
1342
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 spec = ss.remainder ? ss.remainder : "";
1343 21 ret = view_specifier_parse(&spec, &vs);
1344
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (ret < 0) {
1345 stream_specifier_uninit(&ss);
1346 return ret;
1347 }
1348 }
1349
1350
1/2
✓ Branch 0 taken 99 times.
✗ Branch 1 not taken.
99 for (i = 0; i < s->nb_streams; i++) {
1351 99 enum AVMediaType stream_type = s->streams[i]->codecpar->codec_type;
1352
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 91 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 3 times.
99 if (stream_type != type &&
1353
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 !(stream_type == AVMEDIA_TYPE_SUBTITLE &&
1354 type == AVMEDIA_TYPE_VIDEO /* sub2video hack */))
1355 3 continue;
1356
2/2
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 2 times.
96 if (stream_specifier_match(&ss, s, s->streams[i], fg)) {
1357 94 st = s->streams[i];
1358 94 break;
1359 }
1360 }
1361 94 stream_specifier_uninit(&ss);
1362
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
94 if (!st) {
1363 av_log(fg, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s "
1364 "matches no streams.\n", p, fg->graph_desc);
1365 return AVERROR(EINVAL);
1366 }
1367 94 ist = input_files[file_idx]->streams[st->index];
1368
1369 94 av_log(fg, AV_LOG_VERBOSE,
1370 "Binding input with label '%s' to input stream %d:%d\n",
1371 94 ifilter->linklabel, ist->file->index, ist->index);
1372 } else {
1373 57 ist = ist_find_unused(type);
1374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if (!ist) {
1375 av_log(fg, AV_LOG_FATAL,
1376 "Cannot find an unused %s input stream to feed the "
1377 "unlabeled input pad %s.\n",
1378 av_get_media_type_string(type), ifilter->name);
1379 return AVERROR(EINVAL);
1380 }
1381
1382 57 av_log(fg, AV_LOG_VERBOSE,
1383 "Binding unlabeled input %d to input stream %d:%d\n",
1384 57 ifilter->index, ist->file->index, ist->index);
1385 }
1386
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 151 times.
151 av_assert0(ist);
1387
1388 151 ret = ifilter_bind_ist(ifilter, ist, &vs);
1389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 151 times.
151 if (ret < 0) {
1390 av_log(fg, AV_LOG_ERROR,
1391 "Error binding an input stream to complex filtergraph input %s.\n",
1392 ifilter->name);
1393 return ret;
1394 }
1395
1396 151 return 0;
1397 }
1398
1399 1205 static int bind_inputs(FilterGraph *fg)
1400 {
1401 // bind filtergraph inputs to input streams or other filtergraphs
1402
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 1205 times.
1357 for (int i = 0; i < fg->nb_inputs; i++) {
1403 152 InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[i]);
1404 int ret;
1405
1406
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 152 times.
152 if (ifp->bound)
1407 continue;
1408
1409 152 ret = fg_complex_bind_input(fg, &ifp->ifilter);
1410
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 152 times.
152 if (ret < 0)
1411 return ret;
1412 }
1413
1414 1205 return 0;
1415 }
1416
1417 8402 int fg_finalise_bindings(void)
1418 {
1419 int ret;
1420
1421
2/2
✓ Branch 0 taken 1205 times.
✓ Branch 1 taken 8402 times.
9607 for (int i = 0; i < nb_filtergraphs; i++) {
1422 1205 ret = bind_inputs(filtergraphs[i]);
1423
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1205 times.
1205 if (ret < 0)
1424 return ret;
1425 }
1426
1427 // check that all outputs were bound
1428
2/2
✓ Branch 0 taken 1205 times.
✓ Branch 1 taken 8402 times.
9607 for (int i = 0; i < nb_filtergraphs; i++) {
1429 1205 FilterGraph *fg = filtergraphs[i];
1430
1431
2/2
✓ Branch 0 taken 1337 times.
✓ Branch 1 taken 1205 times.
2542 for (int j = 0; j < fg->nb_outputs; j++) {
1432 1337 OutputFilter *output = fg->outputs[j];
1433
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1337 times.
1337 if (!output->bound) {
1434 av_log(fg, AV_LOG_FATAL,
1435 "Filter '%s' has output %d (%s) unconnected\n",
1436 output->name, j,
1437 output->linklabel ? (const char *)output->linklabel : "unlabeled");
1438 return AVERROR(EINVAL);
1439 }
1440 }
1441 }
1442
1443 8402 return 0;
1444 }
1445
1446 15167 static int insert_trim(void *logctx, int64_t start_time, int64_t duration,
1447 AVFilterContext **last_filter, int *pad_idx,
1448 const char *filter_name)
1449 {
1450 15167 AVFilterGraph *graph = (*last_filter)->graph;
1451 AVFilterContext *ctx;
1452 const AVFilter *trim;
1453 15167 enum AVMediaType type = avfilter_pad_get_type((*last_filter)->output_pads, *pad_idx);
1454
2/2
✓ Branch 0 taken 12559 times.
✓ Branch 1 taken 2608 times.
15167 const char *name = (type == AVMEDIA_TYPE_VIDEO) ? "trim" : "atrim";
1455 15167 int ret = 0;
1456
1457
4/4
✓ Branch 0 taken 13864 times.
✓ Branch 1 taken 1303 times.
✓ Branch 2 taken 13847 times.
✓ Branch 3 taken 17 times.
15167 if (duration == INT64_MAX && start_time == AV_NOPTS_VALUE)
1458 13847 return 0;
1459
1460 1320 trim = avfilter_get_by_name(name);
1461
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1320 times.
1320 if (!trim) {
1462 av_log(logctx, AV_LOG_ERROR, "%s filter not present, cannot limit "
1463 "recording time.\n", name);
1464 return AVERROR_FILTER_NOT_FOUND;
1465 }
1466
1467 1320 ctx = avfilter_graph_alloc_filter(graph, trim, filter_name);
1468
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1320 times.
1320 if (!ctx)
1469 return AVERROR(ENOMEM);
1470
1471
2/2
✓ Branch 0 taken 1303 times.
✓ Branch 1 taken 17 times.
1320 if (duration != INT64_MAX) {
1472 1303 ret = av_opt_set_int(ctx, "durationi", duration,
1473 AV_OPT_SEARCH_CHILDREN);
1474 }
1475
3/4
✓ Branch 0 taken 1320 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 1302 times.
1320 if (ret >= 0 && start_time != AV_NOPTS_VALUE) {
1476 18 ret = av_opt_set_int(ctx, "starti", start_time,
1477 AV_OPT_SEARCH_CHILDREN);
1478 }
1479
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1320 times.
1320 if (ret < 0) {
1480 av_log(ctx, AV_LOG_ERROR, "Error configuring the %s filter", name);
1481 return ret;
1482 }
1483
1484 1320 ret = avfilter_init_str(ctx, NULL);
1485
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1320 times.
1320 if (ret < 0)
1486 return ret;
1487
1488 1320 ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
1489
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1320 times.
1320 if (ret < 0)
1490 return ret;
1491
1492 1320 *last_filter = ctx;
1493 1320 *pad_idx = 0;
1494 1320 return 0;
1495 }
1496
1497 11 static int insert_filter(AVFilterContext **last_filter, int *pad_idx,
1498 const char *filter_name, const char *args)
1499 {
1500 11 AVFilterGraph *graph = (*last_filter)->graph;
1501 11 const AVFilter *filter = avfilter_get_by_name(filter_name);
1502 AVFilterContext *ctx;
1503 int ret;
1504
1505
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (!filter)
1506 return AVERROR_BUG;
1507
1508 11 ret = avfilter_graph_create_filter(&ctx,
1509 filter,
1510 filter_name, args, NULL, graph);
1511
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (ret < 0)
1512 return ret;
1513
1514 11 ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
1515
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (ret < 0)
1516 return ret;
1517
1518 11 *last_filter = ctx;
1519 11 *pad_idx = 0;
1520 11 return 0;
1521 }
1522
1523 6838 static int configure_output_video_filter(FilterGraphPriv *fgp, AVFilterGraph *graph,
1524 OutputFilter *ofilter, AVFilterInOut *out)
1525 {
1526 6838 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1527 6838 AVFilterContext *last_filter = out->filter_ctx;
1528 AVBPrint bprint;
1529 6838 int pad_idx = out->pad_idx;
1530 int ret;
1531 char name[255];
1532
1533 6838 snprintf(name, sizeof(name), "out_%s", ofilter->output_name);
1534 6838 ret = avfilter_graph_create_filter(&ofilter->filter,
1535 avfilter_get_by_name("buffersink"),
1536 name, NULL, NULL, graph);
1537
1538
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6838 times.
6838 if (ret < 0)
1539 return ret;
1540
1541
4/6
✓ Branch 0 taken 5487 times.
✓ Branch 1 taken 1351 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5487 times.
✓ Branch 4 taken 1351 times.
✗ Branch 5 not taken.
6838 if ((ofp->width || ofp->height) && (ofp->flags & OFILTER_FLAG_AUTOSCALE)) {
1542 char args[255];
1543 AVFilterContext *filter;
1544 1351 const AVDictionaryEntry *e = NULL;
1545
1546 1351 snprintf(args, sizeof(args), "%d:%d",
1547 ofp->width, ofp->height);
1548
1549
2/2
✓ Branch 1 taken 1337 times.
✓ Branch 2 taken 1351 times.
2688 while ((e = av_dict_iterate(ofp->sws_opts, e))) {
1550 1337 av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
1551 }
1552
1553 1351 snprintf(name, sizeof(name), "scaler_out_%s", ofilter->output_name);
1554
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1351 times.
1351 if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
1555 name, args, NULL, graph)) < 0)
1556 return ret;
1557
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1351 times.
1351 if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
1558 return ret;
1559
1560 1351 last_filter = filter;
1561 1351 pad_idx = 0;
1562 }
1563
1564
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 6838 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
6838 av_assert0(!(ofp->flags & OFILTER_FLAG_DISABLE_CONVERT) ||
1565 ofp->format != AV_PIX_FMT_NONE || !ofp->formats);
1566 6838 av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
1567 6838 choose_pix_fmts(ofp, &bprint);
1568 6838 choose_color_spaces(ofp, &bprint);
1569 6838 choose_color_ranges(ofp, &bprint);
1570 6838 choose_alpha_modes(ofp, &bprint);
1571
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6838 times.
6838 if (!av_bprint_is_complete(&bprint))
1572 return AVERROR(ENOMEM);
1573
1574
2/2
✓ Branch 0 taken 5693 times.
✓ Branch 1 taken 1145 times.
6838 if (bprint.len) {
1575 AVFilterContext *filter;
1576
1577 5693 ret = avfilter_graph_create_filter(&filter,
1578 avfilter_get_by_name("format"),
1579 5693 "format", bprint.str, NULL, graph);
1580 5693 av_bprint_finalize(&bprint, NULL);
1581
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5693 times.
5693 if (ret < 0)
1582 return ret;
1583
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5693 times.
5693 if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
1584 return ret;
1585
1586 5693 last_filter = filter;
1587 5693 pad_idx = 0;
1588 }
1589
1590 6838 snprintf(name, sizeof(name), "trim_out_%s", ofilter->output_name);
1591 6838 ret = insert_trim(fgp, ofp->trim_start_us, ofp->trim_duration_us,
1592 &last_filter, &pad_idx, name);
1593
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6838 times.
6838 if (ret < 0)
1594 return ret;
1595
1596
1597
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6838 times.
6838 if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
1598 return ret;
1599
1600 6838 return 0;
1601 }
1602
1603 1338 static int configure_output_audio_filter(FilterGraphPriv *fgp, AVFilterGraph *graph,
1604 OutputFilter *ofilter, AVFilterInOut *out)
1605 {
1606 1338 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1607 1338 AVFilterContext *last_filter = out->filter_ctx;
1608 1338 int pad_idx = out->pad_idx;
1609 AVBPrint args;
1610 char name[255];
1611 int ret;
1612
1613 1338 snprintf(name, sizeof(name), "out_%s", ofilter->output_name);
1614 1338 ret = avfilter_graph_create_filter(&ofilter->filter,
1615 avfilter_get_by_name("abuffersink"),
1616 name, NULL, NULL, graph);
1617
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1338 times.
1338 if (ret < 0)
1618 return ret;
1619
1620 #define AUTO_INSERT_FILTER(opt_name, filter_name, arg) do { \
1621 AVFilterContext *filt_ctx; \
1622 \
1623 av_log(ofilter, AV_LOG_INFO, opt_name " is forwarded to lavfi " \
1624 "similarly to -af " filter_name "=%s.\n", arg); \
1625 \
1626 ret = avfilter_graph_create_filter(&filt_ctx, \
1627 avfilter_get_by_name(filter_name), \
1628 filter_name, arg, NULL, graph); \
1629 if (ret < 0) \
1630 goto fail; \
1631 \
1632 ret = avfilter_link(last_filter, pad_idx, filt_ctx, 0); \
1633 if (ret < 0) \
1634 goto fail; \
1635 \
1636 last_filter = filt_ctx; \
1637 pad_idx = 0; \
1638 } while (0)
1639 1338 av_bprint_init(&args, 0, AV_BPRINT_SIZE_UNLIMITED);
1640
1641 1338 choose_sample_fmts(ofp, &args);
1642 1338 choose_sample_rates(ofp, &args);
1643 1338 choose_channel_layouts(ofp, &args);
1644
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1338 times.
1338 if (!av_bprint_is_complete(&args)) {
1645 ret = AVERROR(ENOMEM);
1646 goto fail;
1647 }
1648
1/2
✓ Branch 0 taken 1338 times.
✗ Branch 1 not taken.
1338 if (args.len) {
1649 AVFilterContext *format;
1650
1651 1338 snprintf(name, sizeof(name), "format_out_%s", ofilter->output_name);
1652 1338 ret = avfilter_graph_create_filter(&format,
1653 avfilter_get_by_name("aformat"),
1654 1338 name, args.str, NULL, graph);
1655
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1338 times.
1338 if (ret < 0)
1656 goto fail;
1657
1658 1338 ret = avfilter_link(last_filter, pad_idx, format, 0);
1659
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1338 times.
1338 if (ret < 0)
1660 goto fail;
1661
1662 1338 last_filter = format;
1663 1338 pad_idx = 0;
1664 }
1665
1666
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1338 times.
1338 if (ofilter->apad) {
1667 AUTO_INSERT_FILTER("-apad", "apad", ofilter->apad);
1668 fgp->have_sources = 1;
1669 }
1670
1671 1338 snprintf(name, sizeof(name), "trim for output %s", ofilter->output_name);
1672 1338 ret = insert_trim(fgp, ofp->trim_start_us, ofp->trim_duration_us,
1673 &last_filter, &pad_idx, name);
1674
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1338 times.
1338 if (ret < 0)
1675 goto fail;
1676
1677
1/2
✓ Branch 1 taken 1338 times.
✗ Branch 2 not taken.
1338 if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
1678 goto fail;
1679 1338 fail:
1680 1338 av_bprint_finalize(&args, NULL);
1681
1682 1338 return ret;
1683 }
1684
1685 8176 static int configure_output_filter(FilterGraphPriv *fgp, AVFilterGraph *graph,
1686 OutputFilter *ofilter, AVFilterInOut *out)
1687 {
1688
2/3
✓ Branch 0 taken 6838 times.
✓ Branch 1 taken 1338 times.
✗ Branch 2 not taken.
8176 switch (ofilter->type) {
1689 6838 case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fgp, graph, ofilter, out);
1690 1338 case AVMEDIA_TYPE_AUDIO: return configure_output_audio_filter(fgp, graph, ofilter, out);
1691 default: av_assert0(0); return 0;
1692 }
1693 }
1694
1695 4 static void sub2video_prepare(InputFilterPriv *ifp)
1696 {
1697 4 ifp->sub2video.last_pts = INT64_MIN;
1698 4 ifp->sub2video.end_pts = INT64_MIN;
1699
1700 /* sub2video structure has been (re-)initialized.
1701 Mark it as such so that the system will be
1702 initialized with the first received heartbeat. */
1703 4 ifp->sub2video.initialize = 1;
1704 4 }
1705
1706 5721 static int configure_input_video_filter(FilterGraph *fg, AVFilterGraph *graph,
1707 InputFilter *ifilter, AVFilterInOut *in)
1708 {
1709 5721 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1710
1711 AVFilterContext *last_filter;
1712 5721 const AVFilter *buffer_filt = avfilter_get_by_name("buffer");
1713 const AVPixFmtDescriptor *desc;
1714 char name[255];
1715 5721 int ret, pad_idx = 0;
1716 5721 AVBufferSrcParameters *par = av_buffersrc_parameters_alloc();
1717
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5721 times.
5721 if (!par)
1718 return AVERROR(ENOMEM);
1719
1720
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5717 times.
5721 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE)
1721 4 sub2video_prepare(ifp);
1722
1723 5721 snprintf(name, sizeof(name), "graph %d input from stream %s", fg->index,
1724 ifp->opts.name);
1725
1726 5721 ifilter->filter = avfilter_graph_alloc_filter(graph, buffer_filt, name);
1727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5721 times.
5721 if (!ifilter->filter) {
1728 ret = AVERROR(ENOMEM);
1729 goto fail;
1730 }
1731
1732 5721 par->format = ifp->format;
1733 5721 par->time_base = ifp->time_base;
1734 5721 par->frame_rate = ifp->opts.framerate;
1735 5721 par->width = ifp->width;
1736 5721 par->height = ifp->height;
1737 5721 par->sample_aspect_ratio = ifp->sample_aspect_ratio.den > 0 ?
1738
2/2
✓ Branch 0 taken 5717 times.
✓ Branch 1 taken 4 times.
5721 ifp->sample_aspect_ratio : (AVRational){ 0, 1 };
1739 5721 par->color_space = ifp->color_space;
1740 5721 par->color_range = ifp->color_range;
1741 5721 par->alpha_mode = ifp->alpha_mode;
1742 5721 par->hw_frames_ctx = ifp->hw_frames_ctx;
1743 5721 par->side_data = ifp->side_data;
1744 5721 par->nb_side_data = ifp->nb_side_data;
1745
1746 5721 ret = av_buffersrc_parameters_set(ifilter->filter, par);
1747
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5721 times.
5721 if (ret < 0)
1748 goto fail;
1749 5721 av_freep(&par);
1750
1751 5721 ret = avfilter_init_dict(ifilter->filter, NULL);
1752
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5721 times.
5721 if (ret < 0)
1753 goto fail;
1754
1755 5721 last_filter = ifilter->filter;
1756
1757 5721 desc = av_pix_fmt_desc_get(ifp->format);
1758
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5721 times.
5721 av_assert0(desc);
1759
1760
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 5715 times.
5721 if ((ifp->opts.flags & IFILTER_FLAG_CROP)) {
1761 char crop_buf[64];
1762 6 snprintf(crop_buf, sizeof(crop_buf), "w=iw-%u-%u:h=ih-%u-%u:x=%u:y=%u",
1763 ifp->opts.crop_left, ifp->opts.crop_right,
1764 ifp->opts.crop_top, ifp->opts.crop_bottom,
1765 ifp->opts.crop_left, ifp->opts.crop_top);
1766 6 ret = insert_filter(&last_filter, &pad_idx, "crop", crop_buf);
1767
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ret < 0)
1768 return ret;
1769 }
1770
1771 // TODO: insert hwaccel enabled filters like transpose_vaapi into the graph
1772 5721 ifp->displaymatrix_applied = 0;
1773
2/2
✓ Branch 0 taken 5717 times.
✓ Branch 1 taken 4 times.
5721 if ((ifp->opts.flags & IFILTER_FLAG_AUTOROTATE) &&
1774
1/2
✓ Branch 0 taken 5717 times.
✗ Branch 1 not taken.
5717 !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
1775 5717 int32_t *displaymatrix = ifp->displaymatrix;
1776 double theta;
1777
1778 5717 theta = get_rotation(displaymatrix);
1779
1780
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5712 times.
5717 if (fabs(theta - 90) < 1.0) {
1781 5 ret = insert_filter(&last_filter, &pad_idx, "transpose",
1782
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 displaymatrix[3] > 0 ? "cclock_flip" : "clock");
1783
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5712 times.
5712 } else if (fabs(theta - 180) < 1.0) {
1784 if (displaymatrix[0] < 0) {
1785 ret = insert_filter(&last_filter, &pad_idx, "hflip", NULL);
1786 if (ret < 0)
1787 return ret;
1788 }
1789 if (displaymatrix[4] < 0) {
1790 ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
1791 }
1792
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5712 times.
5712 } else if (fabs(theta - 270) < 1.0) {
1793 ret = insert_filter(&last_filter, &pad_idx, "transpose",
1794 displaymatrix[3] < 0 ? "clock_flip" : "cclock");
1795
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5712 times.
5712 } else if (fabs(theta) > 1.0) {
1796 char rotate_buf[64];
1797 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1798 ret = insert_filter(&last_filter, &pad_idx, "rotate", rotate_buf);
1799
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 5703 times.
5712 } else if (fabs(theta) < 1.0) {
1800
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
9 if (displaymatrix && displaymatrix[4] < 0) {
1801 ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
1802 }
1803 }
1804
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5717 times.
5717 if (ret < 0)
1805 return ret;
1806
1807 5717 ifp->displaymatrix_applied = 1;
1808 }
1809
1810 5721 snprintf(name, sizeof(name), "trim_in_%s", ifp->opts.name);
1811 5721 ret = insert_trim(fg, ifp->opts.trim_start_us, ifp->opts.trim_end_us,
1812 &last_filter, &pad_idx, name);
1813
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5721 times.
5721 if (ret < 0)
1814 return ret;
1815
1816
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5721 times.
5721 if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
1817 return ret;
1818 5721 return 0;
1819 fail:
1820 av_freep(&par);
1821
1822 return ret;
1823 }
1824
1825 1270 static int configure_input_audio_filter(FilterGraph *fg, AVFilterGraph *graph,
1826 InputFilter *ifilter, AVFilterInOut *in)
1827 {
1828 1270 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1829 AVFilterContext *last_filter;
1830 AVBufferSrcParameters *par;
1831 1270 const AVFilter *abuffer_filt = avfilter_get_by_name("abuffer");
1832 AVBPrint args;
1833 char name[255];
1834 1270 int ret, pad_idx = 0;
1835
1836 1270 av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);
1837 1270 av_bprintf(&args, "time_base=%d/%d:sample_rate=%d:sample_fmt=%s",
1838 ifp->time_base.num, ifp->time_base.den,
1839 ifp->sample_rate,
1840 1270 av_get_sample_fmt_name(ifp->format));
1841
1/2
✓ Branch 1 taken 1270 times.
✗ Branch 2 not taken.
1270 if (av_channel_layout_check(&ifp->ch_layout) &&
1842
2/2
✓ Branch 0 taken 1257 times.
✓ Branch 1 taken 13 times.
1270 ifp->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
1843 1257 av_bprintf(&args, ":channel_layout=");
1844 1257 av_channel_layout_describe_bprint(&ifp->ch_layout, &args);
1845 } else
1846 13 av_bprintf(&args, ":channels=%d", ifp->ch_layout.nb_channels);
1847 1270 snprintf(name, sizeof(name), "graph_%d_in_%s", fg->index, ifp->opts.name);
1848
1849
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1270 times.
1270 if ((ret = avfilter_graph_create_filter(&ifilter->filter, abuffer_filt,
1850 1270 name, args.str, NULL,
1851 graph)) < 0)
1852 return ret;
1853 1270 par = av_buffersrc_parameters_alloc();
1854
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1270 times.
1270 if (!par)
1855 return AVERROR(ENOMEM);
1856 1270 par->side_data = ifp->side_data;
1857 1270 par->nb_side_data = ifp->nb_side_data;
1858 1270 ret = av_buffersrc_parameters_set(ifilter->filter, par);
1859 1270 av_free(par);
1860
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1270 times.
1270 if (ret < 0)
1861 return ret;
1862 1270 last_filter = ifilter->filter;
1863
1864 1270 snprintf(name, sizeof(name), "trim for input stream %s", ifp->opts.name);
1865 1270 ret = insert_trim(fg, ifp->opts.trim_start_us, ifp->opts.trim_end_us,
1866 &last_filter, &pad_idx, name);
1867
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1270 times.
1270 if (ret < 0)
1868 return ret;
1869
1870
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1270 times.
1270 if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
1871 return ret;
1872
1873 1270 return 0;
1874 }
1875
1876 6991 static int configure_input_filter(FilterGraph *fg, AVFilterGraph *graph,
1877 InputFilter *ifilter, AVFilterInOut *in)
1878 {
1879
2/3
✓ Branch 0 taken 5721 times.
✓ Branch 1 taken 1270 times.
✗ Branch 2 not taken.
6991 switch (ifilter->type) {
1880 5721 case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, graph, ifilter, in);
1881 1270 case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, graph, ifilter, in);
1882 default: av_assert0(0); return 0;
1883 }
1884 }
1885
1886 8044 static void cleanup_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
1887 {
1888
2/2
✓ Branch 0 taken 8176 times.
✓ Branch 1 taken 8044 times.
16220 for (int i = 0; i < fg->nb_outputs; i++)
1889 8176 fg->outputs[i]->filter = NULL;
1890
2/2
✓ Branch 0 taken 6991 times.
✓ Branch 1 taken 8044 times.
15035 for (int i = 0; i < fg->nb_inputs; i++)
1891 6991 fg->inputs[i]->filter = NULL;
1892 8044 avfilter_graph_free(&fgt->graph);
1893 8044 }
1894
1895 9245 static int filter_is_buffersrc(const AVFilterContext *f)
1896 {
1897
2/2
✓ Branch 0 taken 4106 times.
✓ Branch 1 taken 5139 times.
13351 return f->nb_inputs == 0 &&
1898
2/2
✓ Branch 0 taken 1753 times.
✓ Branch 1 taken 2353 times.
4106 (!strcmp(f->filter->name, "buffer") ||
1899
2/2
✓ Branch 0 taken 612 times.
✓ Branch 1 taken 1141 times.
1753 !strcmp(f->filter->name, "abuffer"));
1900 }
1901
1902 8044 static int graph_is_meta(AVFilterGraph *graph)
1903 {
1904
2/2
✓ Branch 0 taken 17566 times.
✓ Branch 1 taken 1764 times.
19330 for (unsigned i = 0; i < graph->nb_filters; i++) {
1905 17566 const AVFilterContext *f = graph->filters[i];
1906
1907 /* in addition to filters flagged as meta, also
1908 * disregard sinks and buffersources (but not other sources,
1909 * since they introduce data we are not aware of)
1910 */
1911
4/4
✓ Branch 0 taken 12210 times.
✓ Branch 1 taken 5356 times.
✓ Branch 2 taken 6280 times.
✓ Branch 3 taken 2965 times.
26811 if (!((f->filter->flags & AVFILTER_FLAG_METADATA_ONLY) ||
1912
2/2
✓ Branch 0 taken 9245 times.
✓ Branch 1 taken 2965 times.
12210 f->nb_outputs == 0 ||
1913 9245 filter_is_buffersrc(f)))
1914 6280 return 0;
1915 }
1916 1764 return 1;
1917 }
1918
1919 static int sub2video_frame(InputFilter *ifilter, AVFrame *frame, int buffer);
1920
1921 8044 static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
1922 {
1923 8044 FilterGraphPriv *fgp = fgp_from_fg(fg);
1924 AVBufferRef *hw_device;
1925 AVFilterInOut *inputs, *outputs, *cur;
1926 8044 int ret = AVERROR_BUG, i, simple = filtergraph_is_simple(fg);
1927 8044 int have_input_eof = 0;
1928 8044 const char *graph_desc = fg->graph_desc;
1929
1930 8044 cleanup_filtergraph(fg, fgt);
1931 8044 fgt->graph = avfilter_graph_alloc();
1932
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8044 times.
8044 if (!fgt->graph)
1933 return AVERROR(ENOMEM);
1934
1935
2/2
✓ Branch 0 taken 6839 times.
✓ Branch 1 taken 1205 times.
8044 if (simple) {
1936 6839 OutputFilterPriv *ofp = ofp_from_ofilter(fg->outputs[0]);
1937
1938
2/2
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 6462 times.
6839 if (filter_nbthreads) {
1939 377 ret = av_opt_set(fgt->graph, "threads", filter_nbthreads, 0);
1940
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 377 times.
377 if (ret < 0)
1941 goto fail;
1942
2/2
✓ Branch 0 taken 4034 times.
✓ Branch 1 taken 2428 times.
6462 } else if (fgp->nb_threads >= 0) {
1943 4034 ret = av_opt_set_int(fgt->graph, "threads", fgp->nb_threads, 0);
1944
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4034 times.
4034 if (ret < 0)
1945 return ret;
1946 }
1947
1948
2/2
✓ Branch 1 taken 4387 times.
✓ Branch 2 taken 2452 times.
6839 if (av_dict_count(ofp->sws_opts)) {
1949 4387 ret = av_dict_get_string(ofp->sws_opts,
1950 4387 &fgt->graph->scale_sws_opts,
1951 '=', ':');
1952
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4387 times.
4387 if (ret < 0)
1953 goto fail;
1954 }
1955
1956
2/2
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 6780 times.
6839 if (av_dict_count(ofp->swr_opts)) {
1957 char *args;
1958 59 ret = av_dict_get_string(ofp->swr_opts, &args, '=', ':');
1959
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if (ret < 0)
1960 goto fail;
1961 59 av_opt_set(fgt->graph, "aresample_swr_opts", args, 0);
1962 59 av_free(args);
1963 }
1964 } else {
1965 1205 fgt->graph->nb_threads = filter_complex_nbthreads;
1966 }
1967
1968
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8043 times.
8044 if (filter_buffered_frames) {
1969 1 ret = av_opt_set_int(fgt->graph, "max_buffered_frames", filter_buffered_frames, 0);
1970
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
1971 return ret;
1972 }
1973
1974 8044 hw_device = hw_device_for_filter();
1975
1976 8044 ret = graph_parse(fg, fgt->graph, graph_desc, &inputs, &outputs, hw_device);
1977
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8044 times.
8044 if (ret < 0)
1978 goto fail;
1979
1980
2/2
✓ Branch 0 taken 6991 times.
✓ Branch 1 taken 8044 times.
15035 for (cur = inputs, i = 0; cur; cur = cur->next, i++)
1981
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6991 times.
6991 if ((ret = configure_input_filter(fg, fgt->graph, fg->inputs[i], cur)) < 0) {
1982 avfilter_inout_free(&inputs);
1983 avfilter_inout_free(&outputs);
1984 goto fail;
1985 }
1986 8044 avfilter_inout_free(&inputs);
1987
1988
2/2
✓ Branch 0 taken 8176 times.
✓ Branch 1 taken 8044 times.
16220 for (cur = outputs, i = 0; cur; cur = cur->next, i++) {
1989 8176 ret = configure_output_filter(fgp, fgt->graph, fg->outputs[i], cur);
1990
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8176 times.
8176 if (ret < 0) {
1991 avfilter_inout_free(&outputs);
1992 goto fail;
1993 }
1994 }
1995 8044 avfilter_inout_free(&outputs);
1996
1997
2/2
✓ Branch 0 taken 6229 times.
✓ Branch 1 taken 1815 times.
8044 if (fgp->disable_conversions)
1998 6229 avfilter_graph_set_auto_convert(fgt->graph, AVFILTER_AUTO_CONVERT_NONE);
1999
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8044 times.
8044 if ((ret = avfilter_graph_config(fgt->graph, NULL)) < 0)
2000 goto fail;
2001
2002 8044 fgp->is_meta = graph_is_meta(fgt->graph);
2003
2004 /* limit the lists of allowed formats to the ones selected, to
2005 * make sure they stay the same if the filtergraph is reconfigured later */
2006
2/2
✓ Branch 0 taken 8176 times.
✓ Branch 1 taken 8044 times.
16220 for (int i = 0; i < fg->nb_outputs; i++) {
2007 const AVFrameSideData *const *sd;
2008 int nb_sd;
2009 8176 OutputFilter *ofilter = fg->outputs[i];
2010 8176 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
2011 8176 AVFilterContext *sink = ofilter->filter;
2012
2013 8176 ofp->format = av_buffersink_get_format(sink);
2014
2015 8176 ofp->width = av_buffersink_get_w(sink);
2016 8176 ofp->height = av_buffersink_get_h(sink);
2017 8176 ofp->color_space = av_buffersink_get_colorspace(sink);
2018 8176 ofp->color_range = av_buffersink_get_color_range(sink);
2019 8176 ofp->alpha_mode = av_buffersink_get_alpha_mode(sink);
2020
2021 // If the timing parameters are not locked yet, get the tentative values
2022 // here but don't lock them. They will only be used if no output frames
2023 // are ever produced.
2024
2/2
✓ Branch 0 taken 8130 times.
✓ Branch 1 taken 46 times.
8176 if (!ofp->tb_out_locked) {
2025 8130 AVRational fr = av_buffersink_get_frame_rate(sink);
2026
3/4
✓ Branch 0 taken 8109 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 8109 times.
✗ Branch 3 not taken.
8130 if (ofp->fps.framerate.num <= 0 && ofp->fps.framerate.den <= 0 &&
2027
4/4
✓ Branch 0 taken 6770 times.
✓ Branch 1 taken 1339 times.
✓ Branch 2 taken 6756 times.
✓ Branch 3 taken 14 times.
8109 fr.num > 0 && fr.den > 0)
2028 6756 ofp->fps.framerate = fr;
2029 8130 ofp->tb_out = av_buffersink_get_time_base(sink);
2030 }
2031 8176 ofp->sample_aspect_ratio = av_buffersink_get_sample_aspect_ratio(sink);
2032
2033 8176 ofp->sample_rate = av_buffersink_get_sample_rate(sink);
2034 8176 av_channel_layout_uninit(&ofp->ch_layout);
2035 8176 ret = av_buffersink_get_ch_layout(sink, &ofp->ch_layout);
2036
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8176 times.
8176 if (ret < 0)
2037 goto fail;
2038 8176 av_frame_side_data_free(&ofp->side_data, &ofp->nb_side_data);
2039 8176 sd = av_buffersink_get_side_data(sink, &nb_sd);
2040
2/2
✓ Branch 0 taken 244 times.
✓ Branch 1 taken 7932 times.
8176 if (nb_sd)
2041
2/2
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 244 times.
508 for (int j = 0; j < nb_sd; j++) {
2042 264 ret = av_frame_side_data_clone(&ofp->side_data, &ofp->nb_side_data,
2043 264 sd[j], 0);
2044
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 264 times.
264 if (ret < 0) {
2045 av_frame_side_data_free(&ofp->side_data, &ofp->nb_side_data);
2046 goto fail;
2047 }
2048 }
2049 }
2050
2051
2/2
✓ Branch 0 taken 6991 times.
✓ Branch 1 taken 8044 times.
15035 for (int i = 0; i < fg->nb_inputs; i++) {
2052 6991 InputFilter *ifilter = fg->inputs[i];
2053 6991 InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[i]);
2054 AVFrame *tmp;
2055
2/2
✓ Branch 1 taken 155 times.
✓ Branch 2 taken 6991 times.
7146 while (av_fifo_read(ifp->frame_queue, &tmp, 1) >= 0) {
2056
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 117 times.
155 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
2057 38 sub2video_frame(&ifp->ifilter, tmp, !fgt->graph);
2058 } else {
2059
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 81 times.
117 if (ifp->type_src == AVMEDIA_TYPE_VIDEO) {
2060
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 if (ifp->displaymatrix_applied)
2061 36 av_frame_remove_side_data(tmp, AV_FRAME_DATA_DISPLAYMATRIX);
2062 }
2063 117 ret = av_buffersrc_add_frame(ifilter->filter, tmp);
2064 }
2065 155 av_frame_free(&tmp);
2066
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 155 times.
155 if (ret < 0)
2067 goto fail;
2068 }
2069 }
2070
2071 /* send the EOFs for the finished inputs */
2072
2/2
✓ Branch 0 taken 6991 times.
✓ Branch 1 taken 8044 times.
15035 for (int i = 0; i < fg->nb_inputs; i++) {
2073 6991 InputFilter *ifilter = fg->inputs[i];
2074
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6983 times.
6991 if (fgt->eof_in[i]) {
2075 8 ret = av_buffersrc_add_frame(ifilter->filter, NULL);
2076
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (ret < 0)
2077 goto fail;
2078 8 have_input_eof = 1;
2079 }
2080 }
2081
2082
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8036 times.
8044 if (have_input_eof) {
2083 // make sure the EOF propagates to the end of the graph
2084 8 ret = avfilter_graph_request_oldest(fgt->graph);
2085
4/6
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
8 if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
2086 goto fail;
2087 }
2088
2089 8044 return 0;
2090 fail:
2091 cleanup_filtergraph(fg, fgt);
2092 return ret;
2093 }
2094
2095 6985 static int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
2096 {
2097 6985 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2098 AVFrameSideData *sd;
2099 int ret;
2100
2101 6985 ret = av_buffer_replace(&ifp->hw_frames_ctx, frame->hw_frames_ctx);
2102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6985 times.
6985 if (ret < 0)
2103 return ret;
2104
2105
2/2
✓ Branch 0 taken 1267 times.
✓ Branch 1 taken 5718 times.
12671 ifp->time_base = (ifilter->type == AVMEDIA_TYPE_AUDIO) ? (AVRational){ 1, frame->sample_rate } :
2106
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 5686 times.
5718 (ifp->opts.flags & IFILTER_FLAG_CFR) ? av_inv_q(ifp->opts.framerate) :
2107 frame->time_base;
2108
2109 6985 ifp->format = frame->format;
2110
2111 6985 ifp->width = frame->width;
2112 6985 ifp->height = frame->height;
2113 6985 ifp->sample_aspect_ratio = frame->sample_aspect_ratio;
2114 6985 ifp->color_space = frame->colorspace;
2115 6985 ifp->color_range = frame->color_range;
2116 6985 ifp->alpha_mode = frame->alpha_mode;
2117
2118 6985 ifp->sample_rate = frame->sample_rate;
2119 6985 ret = av_channel_layout_copy(&ifp->ch_layout, &frame->ch_layout);
2120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6985 times.
6985 if (ret < 0)
2121 return ret;
2122
2123 6985 av_frame_side_data_free(&ifp->side_data, &ifp->nb_side_data);
2124
2/2
✓ Branch 0 taken 530 times.
✓ Branch 1 taken 6985 times.
7515 for (int i = 0; i < frame->nb_side_data; i++) {
2125 530 const AVSideDataDescriptor *desc = av_frame_side_data_desc(frame->side_data[i]->type);
2126
2127
2/2
✓ Branch 0 taken 266 times.
✓ Branch 1 taken 264 times.
530 if (!(desc->props & AV_SIDE_DATA_PROP_GLOBAL))
2128 266 continue;
2129
2130 264 ret = av_frame_side_data_clone(&ifp->side_data,
2131 &ifp->nb_side_data,
2132 264 frame->side_data[i], 0);
2133
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 264 times.
264 if (ret < 0)
2134 return ret;
2135 }
2136
2137 6985 sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX);
2138
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 6968 times.
6985 if (sd)
2139 17 memcpy(ifp->displaymatrix, sd->data, sizeof(ifp->displaymatrix));
2140 6985 ifp->displaymatrix_present = !!sd;
2141
2142 /* Copy downmix related side data to InputFilterPriv so it may be propagated
2143 * to the filter chain even though it's not "global", as filters like aresample
2144 * require this information during init and not when remixing a frame */
2145 6985 sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DOWNMIX_INFO);
2146
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6980 times.
6985 if (sd) {
2147 5 ret = av_frame_side_data_clone(&ifp->side_data,
2148 &ifp->nb_side_data, sd, 0);
2149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (ret < 0)
2150 return ret;
2151 5 memcpy(&ifp->downmixinfo, sd->data, sizeof(ifp->downmixinfo));
2152 }
2153 6985 ifp->downmixinfo_present = !!sd;
2154
2155 6985 return 0;
2156 }
2157
2158 38060 int filtergraph_is_simple(const FilterGraph *fg)
2159 {
2160 38060 const FilterGraphPriv *fgp = cfgp_from_cfg(fg);
2161 38060 return fgp->is_simple;
2162 }
2163
2164 static void send_command(FilterGraph *fg, AVFilterGraph *graph,
2165 double time, const char *target,
2166 const char *command, const char *arg, int all_filters)
2167 {
2168 int ret;
2169
2170 if (!graph)
2171 return;
2172
2173 if (time < 0) {
2174 char response[4096];
2175 ret = avfilter_graph_send_command(graph, target, command, arg,
2176 response, sizeof(response),
2177 all_filters ? 0 : AVFILTER_CMD_FLAG_ONE);
2178 fprintf(stderr, "Command reply for stream %d: ret:%d res:\n%s",
2179 fg->index, ret, response);
2180 } else if (!all_filters) {
2181 fprintf(stderr, "Queuing commands only on filters supporting the specific command is unsupported\n");
2182 } else {
2183 ret = avfilter_graph_queue_command(graph, target, command, arg, 0, time);
2184 if (ret < 0)
2185 fprintf(stderr, "Queuing command failed with error %s\n", av_err2str(ret));
2186 }
2187 }
2188
2189 374457 static int choose_input(const FilterGraph *fg, const FilterGraphThread *fgt)
2190 {
2191 374457 int nb_requests, nb_requests_max = -1;
2192 374457 int best_input = -1;
2193
2194
2/2
✓ Branch 0 taken 387368 times.
✓ Branch 1 taken 374457 times.
761825 for (int i = 0; i < fg->nb_inputs; i++) {
2195 387368 InputFilter *ifilter = fg->inputs[i];
2196
2197
2/2
✓ Branch 0 taken 1233 times.
✓ Branch 1 taken 386135 times.
387368 if (fgt->eof_in[i])
2198 1233 continue;
2199
2200 386135 nb_requests = av_buffersrc_get_nb_failed_requests(ifilter->filter);
2201
2/2
✓ Branch 0 taken 376587 times.
✓ Branch 1 taken 9548 times.
386135 if (nb_requests > nb_requests_max) {
2202 376587 nb_requests_max = nb_requests;
2203 376587 best_input = i;
2204 }
2205 }
2206
2207
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 374457 times.
374457 av_assert0(best_input >= 0);
2208
2209 374457 return best_input;
2210 }
2211
2212 8127 static int choose_out_timebase(OutputFilterPriv *ofp, AVFrame *frame)
2213 {
2214 8127 OutputFilter *ofilter = &ofp->ofilter;
2215 8127 FPSConvContext *fps = &ofp->fps;
2216 8127 AVRational tb = (AVRational){ 0, 0 };
2217 AVRational fr;
2218 const FrameData *fd;
2219
2220 8127 fd = frame_data_c(frame);
2221
2222 // apply -enc_time_base
2223
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8126 times.
8127 if (ofp->enc_timebase.num == ENC_TIME_BASE_DEMUX &&
2224
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 (fd->dec.tb.num <= 0 || fd->dec.tb.den <= 0)) {
2225 av_log(ofp, AV_LOG_ERROR,
2226 "Demuxing timebase not available - cannot use it for encoding\n");
2227 return AVERROR(EINVAL);
2228 }
2229
2230
2/4
✓ Branch 0 taken 8126 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8127 switch (ofp->enc_timebase.num) {
2231 8126 case 0: break;
2232 1 case ENC_TIME_BASE_DEMUX: tb = fd->dec.tb; break;
2233 case ENC_TIME_BASE_FILTER: tb = frame->time_base; break;
2234 default: tb = ofp->enc_timebase; break;
2235 }
2236
2237
2/2
✓ Branch 0 taken 1334 times.
✓ Branch 1 taken 6793 times.
8127 if (ofilter->type == AVMEDIA_TYPE_AUDIO) {
2238
1/2
✓ Branch 0 taken 1334 times.
✗ Branch 1 not taken.
1334 tb = tb.num ? tb : (AVRational){ 1, frame->sample_rate };
2239 1334 goto finish;
2240 }
2241
2242 6793 fr = fps->framerate;
2243
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6777 times.
6793 if (!fr.num) {
2244 16 AVRational fr_sink = av_buffersink_get_frame_rate(ofilter->filter);
2245
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
16 if (fr_sink.num > 0 && fr_sink.den > 0)
2246 fr = fr_sink;
2247 }
2248
2249
4/4
✓ Branch 0 taken 5681 times.
✓ Branch 1 taken 1112 times.
✓ Branch 2 taken 342 times.
✓ Branch 3 taken 5339 times.
6793 if (fps->vsync_method == VSYNC_CFR || fps->vsync_method == VSYNC_VSCFR) {
2250
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1454 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1454 if (!fr.num && !fps->framerate_max.num) {
2251 fr = (AVRational){25, 1};
2252 av_log(ofp, AV_LOG_WARNING,
2253 "No information "
2254 "about the input framerate is available. Falling "
2255 "back to a default value of 25fps. Use the -r option "
2256 "if you want a different framerate.\n");
2257 }
2258
2259
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1454 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1454 if (fps->framerate_max.num &&
2260 (av_q2d(fr) > av_q2d(fps->framerate_max) ||
2261 !fr.den))
2262 fr = fps->framerate_max;
2263 }
2264
2265
2/2
✓ Branch 0 taken 6777 times.
✓ Branch 1 taken 16 times.
6793 if (fr.num > 0) {
2266
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 6721 times.
6777 if (fps->framerate_supported) {
2267 56 int idx = av_find_nearest_q_idx(fr, fps->framerate_supported);
2268 56 fr = fps->framerate_supported[idx];
2269 }
2270
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 6714 times.
6777 if (fps->framerate_clip) {
2271 63 av_reduce(&fr.num, &fr.den,
2272 63 fr.num, fr.den, fps->framerate_clip);
2273 }
2274 }
2275
2276
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6792 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
6793 if (!(tb.num > 0 && tb.den > 0))
2277 6792 tb = av_inv_q(fr);
2278
3/4
✓ Branch 0 taken 6777 times.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6777 times.
6793 if (!(tb.num > 0 && tb.den > 0))
2279 16 tb = frame->time_base;
2280
2281 6793 fps->framerate = fr;
2282 8127 finish:
2283 8127 ofp->tb_out = tb;
2284 8127 ofp->tb_out_locked = 1;
2285
2286 8127 return 0;
2287 }
2288
2289 141385 static double adjust_frame_pts_to_encoder_tb(void *logctx, AVFrame *frame,
2290 AVRational tb_dst, int64_t start_time)
2291 {
2292 141385 double float_pts = AV_NOPTS_VALUE; // this is identical to frame.pts but with higher precision
2293
2294 141385 AVRational tb = tb_dst;
2295 141385 AVRational filter_tb = frame->time_base;
2296 141385 const int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16);
2297
2298
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141385 times.
141385 if (frame->pts == AV_NOPTS_VALUE)
2299 goto early_exit;
2300
2301 141385 tb.den <<= extra_bits;
2302 141385 float_pts = av_rescale_q(frame->pts, filter_tb, tb) -
2303 141385 av_rescale_q(start_time, AV_TIME_BASE_Q, tb);
2304 141385 float_pts /= 1 << extra_bits;
2305 // when float_pts is not exactly an integer,
2306 // avoid exact midpoints to reduce the chance of rounding differences, this
2307 // can be removed in case the fps code is changed to work with integers
2308
2/2
✓ Branch 0 taken 6074 times.
✓ Branch 1 taken 135311 times.
141385 if (float_pts != llrint(float_pts))
2309
1/2
✓ Branch 0 taken 6074 times.
✗ Branch 1 not taken.
6074 float_pts += FFSIGN(float_pts) * 1.0 / (1<<17);
2310
2311 141385 frame->pts = av_rescale_q(frame->pts, filter_tb, tb_dst) -
2312 141385 av_rescale_q(start_time, AV_TIME_BASE_Q, tb_dst);
2313 141385 frame->time_base = tb_dst;
2314
2315 141385 early_exit:
2316
2317
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141385 times.
141385 if (debug_ts) {
2318 av_log(logctx, AV_LOG_INFO,
2319 "filter -> pts:%s pts_time:%s exact:%f time_base:%d/%d\n",
2320 frame ? av_ts2str(frame->pts) : "NULL",
2321 av_ts2timestr(frame->pts, &tb_dst),
2322 float_pts, tb_dst.num, tb_dst.den);
2323 }
2324
2325 141385 return float_pts;
2326 }
2327
2328 /* Convert frame timestamps to the encoder timebase and decide how many times
2329 * should this (and possibly previous) frame be repeated in order to conform to
2330 * desired target framerate (if any).
2331 */
2332 145148 static void video_sync_process(OutputFilterPriv *ofp, AVFrame *frame,
2333 int64_t *nb_frames, int64_t *nb_frames_prev)
2334 {
2335 145148 OutputFilter *ofilter = &ofp->ofilter;
2336 145148 FPSConvContext *fps = &ofp->fps;
2337 double delta0, delta, sync_ipts, duration;
2338
2339
2/2
✓ Branch 0 taken 3763 times.
✓ Branch 1 taken 141385 times.
145148 if (!frame) {
2340 3763 *nb_frames_prev = *nb_frames = mid_pred(fps->frames_prev_hist[0],
2341 3763 fps->frames_prev_hist[1],
2342 3763 fps->frames_prev_hist[2]);
2343
2344
4/4
✓ Branch 0 taken 3762 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 3760 times.
3763 if (!*nb_frames && fps->last_dropped) {
2345 2 atomic_fetch_add(&ofilter->nb_frames_drop, 1);
2346 2 fps->last_dropped++;
2347 }
2348
2349 3763 goto finish;
2350 }
2351
2352 141385 duration = frame->duration * av_q2d(frame->time_base) / av_q2d(ofp->tb_out);
2353
2354 141385 sync_ipts = adjust_frame_pts_to_encoder_tb(ofilter->graph, frame,
2355 ofp->tb_out, ofp->ts_offset);
2356 /* delta0 is the "drift" between the input frame and
2357 * where it would fall in the output. */
2358 141385 delta0 = sync_ipts - ofp->next_pts;
2359 141385 delta = delta0 + duration;
2360
2361 // tracks the number of times the PREVIOUS frame should be duplicated,
2362 // mostly for variable framerate (VFR)
2363 141385 *nb_frames_prev = 0;
2364 /* by default, we output a single frame */
2365 141385 *nb_frames = 1;
2366
2367
4/4
✓ Branch 0 taken 5040 times.
✓ Branch 1 taken 136345 times.
✓ Branch 2 taken 3855 times.
✓ Branch 3 taken 1185 times.
141385 if (delta0 < 0 &&
2368 3855 delta > 0 &&
2369
1/2
✓ Branch 0 taken 3855 times.
✗ Branch 1 not taken.
3855 fps->vsync_method != VSYNC_PASSTHROUGH
2370 #if FFMPEG_OPT_VSYNC_DROP
2371
1/2
✓ Branch 0 taken 3855 times.
✗ Branch 1 not taken.
3855 && fps->vsync_method != VSYNC_DROP
2372 #endif
2373 ) {
2374
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 3810 times.
3855 if (delta0 < -0.6) {
2375 45 av_log(ofp, AV_LOG_VERBOSE, "Past duration %f too large\n", -delta0);
2376 } else
2377 3810 av_log(ofp, AV_LOG_DEBUG, "Clipping frame in rate conversion by %f\n", -delta0);
2378 3855 sync_ipts = ofp->next_pts;
2379 3855 duration += delta0;
2380 3855 delta0 = 0;
2381 }
2382
2383
4/5
✓ Branch 0 taken 7537 times.
✓ Branch 1 taken 27914 times.
✓ Branch 2 taken 83036 times.
✓ Branch 3 taken 22898 times.
✗ Branch 4 not taken.
141385 switch (fps->vsync_method) {
2384 7537 case VSYNC_VSCFR:
2385
3/4
✓ Branch 0 taken 342 times.
✓ Branch 1 taken 7195 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 342 times.
7537 if (fps->frame_number == 0 && delta0 >= 0.5) {
2386 av_log(ofp, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta0));
2387 delta = duration;
2388 delta0 = 0;
2389 ofp->next_pts = llrint(sync_ipts);
2390 }
2391 case VSYNC_CFR:
2392 // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
2393
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 35451 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
35451 if (frame_drop_threshold && delta < frame_drop_threshold && fps->frame_number) {
2394 *nb_frames = 0;
2395
2/2
✓ Branch 0 taken 375 times.
✓ Branch 1 taken 35076 times.
35451 } else if (delta < -1.1)
2396 375 *nb_frames = 0;
2397
2/2
✓ Branch 0 taken 727 times.
✓ Branch 1 taken 34349 times.
35076 else if (delta > 1.1) {
2398 727 *nb_frames = llrintf(delta);
2399
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 725 times.
727 if (delta0 > 1.1)
2400 2 *nb_frames_prev = llrintf(delta0 - 0.6);
2401 }
2402 35451 frame->duration = 1;
2403 35451 break;
2404 83036 case VSYNC_VFR:
2405
2/2
✓ Branch 0 taken 99 times.
✓ Branch 1 taken 82937 times.
83036 if (delta <= -0.6)
2406 99 *nb_frames = 0;
2407
2/2
✓ Branch 0 taken 65585 times.
✓ Branch 1 taken 17352 times.
82937 else if (delta > 0.6)
2408 65585 ofp->next_pts = llrint(sync_ipts);
2409 83036 frame->duration = llrint(duration);
2410 83036 break;
2411 #if FFMPEG_OPT_VSYNC_DROP
2412 22898 case VSYNC_DROP:
2413 #endif
2414 case VSYNC_PASSTHROUGH:
2415 22898 ofp->next_pts = llrint(sync_ipts);
2416 22898 frame->duration = llrint(duration);
2417 22898 break;
2418 default:
2419 av_assert0(0);
2420 }
2421
2422 145148 finish:
2423 145148 memmove(fps->frames_prev_hist + 1,
2424 145148 fps->frames_prev_hist,
2425 sizeof(fps->frames_prev_hist[0]) * (FF_ARRAY_ELEMS(fps->frames_prev_hist) - 1));
2426 145148 fps->frames_prev_hist[0] = *nb_frames_prev;
2427
2428
4/4
✓ Branch 0 taken 145145 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 474 times.
✓ Branch 3 taken 144671 times.
145148 if (*nb_frames_prev == 0 && fps->last_dropped) {
2429 474 atomic_fetch_add(&ofilter->nb_frames_drop, 1);
2430 474 av_log(ofp, AV_LOG_VERBOSE,
2431 "*** dropping frame %"PRId64" at ts %"PRId64"\n",
2432 474 fps->frame_number, fps->last_frame->pts);
2433 }
2434
5/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 145145 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 269 times.
✓ Branch 5 taken 144879 times.
145148 if (*nb_frames > (*nb_frames_prev && fps->last_dropped) + (*nb_frames > *nb_frames_prev)) {
2435 uint64_t nb_frames_dup;
2436
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 269 times.
269 if (*nb_frames > dts_error_threshold * 30) {
2437 av_log(ofp, AV_LOG_ERROR, "%"PRId64" frame duplication too large, skipping\n", *nb_frames - 1);
2438 atomic_fetch_add(&ofilter->nb_frames_drop, 1);
2439 *nb_frames = 0;
2440 return;
2441 }
2442
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 266 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
269 nb_frames_dup = atomic_fetch_add(&ofilter->nb_frames_dup,
2443 *nb_frames - (*nb_frames_prev && fps->last_dropped) - (*nb_frames > *nb_frames_prev));
2444 269 av_log(ofp, AV_LOG_VERBOSE, "*** %"PRId64" dup!\n", *nb_frames - 1);
2445
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 269 times.
269 if (nb_frames_dup > fps->dup_warning) {
2446 av_log(ofp, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", fps->dup_warning);
2447 fps->dup_warning *= 10;
2448 }
2449 }
2450
2451
4/4
✓ Branch 0 taken 4237 times.
✓ Branch 1 taken 140911 times.
✓ Branch 2 taken 474 times.
✓ Branch 3 taken 3763 times.
145148 fps->last_dropped = *nb_frames == *nb_frames_prev && frame;
2452
4/4
✓ Branch 0 taken 474 times.
✓ Branch 1 taken 144674 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 467 times.
145148 fps->dropped_keyframe |= fps->last_dropped && (frame->flags & AV_FRAME_FLAG_KEY);
2453 }
2454
2455 5069 static int close_output(OutputFilterPriv *ofp, FilterGraphThread *fgt)
2456 {
2457 5069 FilterGraphPriv *fgp = fgp_from_fg(ofp->ofilter.graph);
2458 int ret;
2459
2460 // we are finished and no frames were ever seen at this output,
2461 // at least initialize the encoder with a dummy frame
2462
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5066 times.
5069 if (!fgt->got_frame) {
2463 3 AVFrame *frame = fgt->frame;
2464 FrameData *fd;
2465
2466 3 frame->time_base = ofp->tb_out;
2467 3 frame->format = ofp->format;
2468
2469 3 frame->width = ofp->width;
2470 3 frame->height = ofp->height;
2471 3 frame->sample_aspect_ratio = ofp->sample_aspect_ratio;
2472
2473 3 frame->sample_rate = ofp->sample_rate;
2474
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (ofp->ch_layout.nb_channels) {
2475 3 ret = av_channel_layout_copy(&frame->ch_layout, &ofp->ch_layout);
2476
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0)
2477 return ret;
2478 }
2479 3 av_frame_side_data_free(&frame->side_data, &frame->nb_side_data);
2480 3 ret = clone_side_data(&frame->side_data, &frame->nb_side_data,
2481 3 ofp->side_data, ofp->nb_side_data, 0);
2482
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0)
2483 return ret;
2484
2485 3 fd = frame_data(frame);
2486
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!fd)
2487 return AVERROR(ENOMEM);
2488
2489 3 fd->frame_rate_filter = ofp->fps.framerate;
2490
2491
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 av_assert0(!frame->buf[0]);
2492
2493 3 av_log(ofp, AV_LOG_WARNING,
2494 "No filtered frames for output stream, trying to "
2495 "initialize anyway.\n");
2496
2497 3 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, frame);
2498
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0) {
2499 av_frame_unref(frame);
2500 return ret;
2501 }
2502 }
2503
2504 5069 fgt->eof_out[ofp->ofilter.index] = 1;
2505
2506 5069 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, NULL);
2507
2/2
✓ Branch 0 taken 4941 times.
✓ Branch 1 taken 128 times.
5069 return (ret == AVERROR_EOF) ? 0 : ret;
2508 }
2509
2510 407472 static int fg_output_frame(OutputFilterPriv *ofp, FilterGraphThread *fgt,
2511 AVFrame *frame)
2512 {
2513 407472 FilterGraphPriv *fgp = fgp_from_fg(ofp->ofilter.graph);
2514 407472 AVFrame *frame_prev = ofp->fps.last_frame;
2515 407472 enum AVMediaType type = ofp->ofilter.type;
2516
2517 407472 int64_t nb_frames = !!frame, nb_frames_prev = 0;
2518
2519
5/6
✓ Branch 0 taken 145148 times.
✓ Branch 1 taken 262324 times.
✓ Branch 2 taken 3763 times.
✓ Branch 3 taken 141385 times.
✓ Branch 4 taken 3763 times.
✗ Branch 5 not taken.
407472 if (type == AVMEDIA_TYPE_VIDEO && (frame || fgt->got_frame))
2520 145148 video_sync_process(ofp, frame, &nb_frames, &nb_frames_prev);
2521
2522
2/2
✓ Branch 0 taken 402361 times.
✓ Branch 1 taken 404411 times.
806772 for (int64_t i = 0; i < nb_frames; i++) {
2523 AVFrame *frame_out;
2524 int ret;
2525
2526
2/2
✓ Branch 0 taken 141343 times.
✓ Branch 1 taken 261018 times.
402361 if (type == AVMEDIA_TYPE_VIDEO) {
2527
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 AVFrame *frame_in = (i < nb_frames_prev && frame_prev->buf[0]) ?
2528
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 141274 times.
141412 frame_prev : frame;
2529
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141343 times.
141343 if (!frame_in)
2530 break;
2531
2532 141343 frame_out = fgp->frame_enc;
2533 141343 ret = av_frame_ref(frame_out, frame_in);
2534
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141343 times.
141343 if (ret < 0)
2535 return ret;
2536
2537 141343 frame_out->pts = ofp->next_pts;
2538
2539
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 141336 times.
141343 if (ofp->fps.dropped_keyframe) {
2540 7 frame_out->flags |= AV_FRAME_FLAG_KEY;
2541 7 ofp->fps.dropped_keyframe = 0;
2542 }
2543 } else {
2544
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 261018 times.
261018 frame->pts = (frame->pts == AV_NOPTS_VALUE) ? ofp->next_pts :
2545 261018 av_rescale_q(frame->pts, frame->time_base, ofp->tb_out) -
2546 261018 av_rescale_q(ofp->ts_offset, AV_TIME_BASE_Q, ofp->tb_out);
2547
2548 261018 frame->time_base = ofp->tb_out;
2549 261018 frame->duration = av_rescale_q(frame->nb_samples,
2550 261018 (AVRational){ 1, frame->sample_rate },
2551 ofp->tb_out);
2552
2553 261018 ofp->next_pts = frame->pts + frame->duration;
2554
2555 261018 frame_out = frame;
2556 }
2557
2558 // send the frame to consumers
2559 402361 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, frame_out);
2560
2/2
✓ Branch 0 taken 3061 times.
✓ Branch 1 taken 399300 times.
402361 if (ret < 0) {
2561 3061 av_frame_unref(frame_out);
2562
2563
1/2
✓ Branch 0 taken 3061 times.
✗ Branch 1 not taken.
3061 if (!fgt->eof_out[ofp->ofilter.index]) {
2564 3061 fgt->eof_out[ofp->ofilter.index] = 1;
2565 3061 fgp->nb_outputs_done++;
2566 }
2567
2568
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3061 times.
3061 return ret == AVERROR_EOF ? 0 : ret;
2569 }
2570
2571
2/2
✓ Branch 0 taken 138313 times.
✓ Branch 1 taken 260987 times.
399300 if (type == AVMEDIA_TYPE_VIDEO) {
2572 138313 ofp->fps.frame_number++;
2573 138313 ofp->next_pts++;
2574
2575
3/4
✓ Branch 0 taken 137881 times.
✓ Branch 1 taken 432 times.
✓ Branch 2 taken 137881 times.
✗ Branch 3 not taken.
138313 if (i == nb_frames_prev && frame)
2576 137881 frame->flags &= ~AV_FRAME_FLAG_KEY;
2577 }
2578
2579 399300 fgt->got_frame = 1;
2580 }
2581
2582
4/4
✓ Branch 0 taken 399342 times.
✓ Branch 1 taken 5069 times.
✓ Branch 2 taken 138355 times.
✓ Branch 3 taken 260987 times.
404411 if (frame && frame_prev) {
2583 138355 av_frame_unref(frame_prev);
2584 138355 av_frame_move_ref(frame_prev, frame);
2585 }
2586
2587
2/2
✓ Branch 0 taken 5069 times.
✓ Branch 1 taken 399342 times.
404411 if (!frame)
2588 5069 return close_output(ofp, fgt);
2589
2590 399342 return 0;
2591 }
2592
2593 852641 static int fg_output_step(OutputFilterPriv *ofp, FilterGraphThread *fgt,
2594 AVFrame *frame)
2595 {
2596 852641 FilterGraphPriv *fgp = fgp_from_fg(ofp->ofilter.graph);
2597 852641 AVFilterContext *filter = ofp->ofilter.filter;
2598 FrameData *fd;
2599 int ret;
2600
2601 852641 ret = av_buffersink_get_frame_flags(filter, frame,
2602 AV_BUFFERSINK_FLAG_NO_REQUEST);
2603
4/4
✓ Branch 0 taken 4157 times.
✓ Branch 1 taken 848484 times.
✓ Branch 2 taken 3517 times.
✓ Branch 3 taken 640 times.
852641 if (ret == AVERROR_EOF && !fgt->eof_out[ofp->ofilter.index]) {
2604 3517 ret = fg_output_frame(ofp, fgt, NULL);
2605
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3517 times.
3517 return (ret < 0) ? ret : 1;
2606
4/4
✓ Branch 0 taken 403045 times.
✓ Branch 1 taken 446079 times.
✓ Branch 2 taken 640 times.
✓ Branch 3 taken 402405 times.
849124 } else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2607 446719 return 1;
2608
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 402405 times.
402405 } else if (ret < 0) {
2609 av_log(ofp, AV_LOG_WARNING,
2610 "Error in retrieving a frame from the filtergraph: %s\n",
2611 av_err2str(ret));
2612 return ret;
2613 }
2614
2615
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 402403 times.
402405 if (fgt->eof_out[ofp->ofilter.index]) {
2616 2 av_frame_unref(frame);
2617 2 return 0;
2618 }
2619
2620 402403 frame->time_base = av_buffersink_get_time_base(filter);
2621
2622
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 402403 times.
402403 if (debug_ts)
2623 av_log(ofp, AV_LOG_INFO, "filter_raw -> pts:%s pts_time:%s time_base:%d/%d\n",
2624 av_ts2str(frame->pts), av_ts2timestr(frame->pts, &frame->time_base),
2625 frame->time_base.num, frame->time_base.den);
2626
2627 // Choose the output timebase the first time we get a frame.
2628
2/2
✓ Branch 0 taken 8127 times.
✓ Branch 1 taken 394276 times.
402403 if (!ofp->tb_out_locked) {
2629 8127 ret = choose_out_timebase(ofp, frame);
2630
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8127 times.
8127 if (ret < 0) {
2631 av_log(ofp, AV_LOG_ERROR, "Could not choose an output time base\n");
2632 av_frame_unref(frame);
2633 return ret;
2634 }
2635 }
2636
2637 402403 fd = frame_data(frame);
2638
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 402403 times.
402403 if (!fd) {
2639 av_frame_unref(frame);
2640 return AVERROR(ENOMEM);
2641 }
2642
2643 402403 fd->wallclock[LATENCY_PROBE_FILTER_POST] = av_gettime_relative();
2644
2645 // only use bits_per_raw_sample passed through from the decoder
2646 // if the filtergraph did not touch the frame data
2647
2/2
✓ Branch 0 taken 289885 times.
✓ Branch 1 taken 112518 times.
402403 if (!fgp->is_meta)
2648 289885 fd->bits_per_raw_sample = 0;
2649
2650
2/2
✓ Branch 0 taken 141385 times.
✓ Branch 1 taken 261018 times.
402403 if (ofp->ofilter.type == AVMEDIA_TYPE_VIDEO) {
2651
2/2
✓ Branch 0 taken 2417 times.
✓ Branch 1 taken 138968 times.
141385 if (!frame->duration) {
2652 2417 AVRational fr = av_buffersink_get_frame_rate(filter);
2653
4/4
✓ Branch 0 taken 2324 times.
✓ Branch 1 taken 93 times.
✓ Branch 2 taken 1783 times.
✓ Branch 3 taken 541 times.
2417 if (fr.num > 0 && fr.den > 0)
2654 1783 frame->duration = av_rescale_q(1, av_inv_q(fr), frame->time_base);
2655 }
2656
2657 141385 fd->frame_rate_filter = ofp->fps.framerate;
2658 }
2659
2660 402403 ret = fg_output_frame(ofp, fgt, frame);
2661 402403 av_frame_unref(frame);
2662
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 402403 times.
402403 if (ret < 0)
2663 return ret;
2664
2665 402403 return 0;
2666 }
2667
2668 /* retrieve all frames available at filtergraph outputs
2669 * and send them to consumers */
2670 411011 static int read_frames(FilterGraph *fg, FilterGraphThread *fgt,
2671 AVFrame *frame)
2672 {
2673 411011 FilterGraphPriv *fgp = fgp_from_fg(fg);
2674 411011 int did_step = 0;
2675
2676 // graph not configured, just select the input to request
2677
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 410851 times.
411011 if (!fgt->graph) {
2678
1/2
✓ Branch 0 taken 421 times.
✗ Branch 1 not taken.
421 for (int i = 0; i < fg->nb_inputs; i++) {
2679 421 InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[i]);
2680
3/4
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 261 times.
✓ Branch 2 taken 160 times.
✗ Branch 3 not taken.
421 if (ifp->format < 0 && !fgt->eof_in[i]) {
2681 160 fgt->next_in = i;
2682 160 return 0;
2683 }
2684 }
2685
2686 // This state - graph is not configured, but all inputs are either
2687 // initialized or EOF - should be unreachable because sending EOF to a
2688 // filter without even a fallback format should fail
2689 av_assert0(0);
2690 return AVERROR_BUG;
2691 }
2692
2693
2/2
✓ Branch 0 taken 438169 times.
✓ Branch 1 taken 3061 times.
441230 while (fgp->nb_outputs_done < fg->nb_outputs) {
2694 int ret;
2695
2696 /* Reap all buffers present in the buffer sinks */
2697
2/2
✓ Branch 0 taken 450236 times.
✓ Branch 1 taken 438169 times.
888405 for (int i = 0; i < fg->nb_outputs; i++) {
2698 450236 OutputFilterPriv *ofp = ofp_from_ofilter(fg->outputs[i]);
2699
2700 450236 ret = 0;
2701
2/2
✓ Branch 0 taken 852641 times.
✓ Branch 1 taken 450236 times.
1302877 while (!ret) {
2702 852641 ret = fg_output_step(ofp, fgt, frame);
2703
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 852641 times.
852641 if (ret < 0)
2704 return ret;
2705 }
2706 }
2707
2708 // return after one iteration, so that scheduler can rate-control us
2709
4/4
✓ Branch 0 taken 30377 times.
✓ Branch 1 taken 407792 times.
✓ Branch 2 taken 28402 times.
✓ Branch 3 taken 1975 times.
438169 if (did_step && fgp->have_sources)
2710 28402 return 0;
2711
2712 409767 ret = avfilter_graph_request_oldest(fgt->graph);
2713
2/2
✓ Branch 0 taken 374457 times.
✓ Branch 1 taken 35310 times.
409767 if (ret == AVERROR(EAGAIN)) {
2714 374457 fgt->next_in = choose_input(fg, fgt);
2715 374457 return 0;
2716
2/2
✓ Branch 0 taken 4931 times.
✓ Branch 1 taken 30379 times.
35310 } else if (ret < 0) {
2717
1/2
✓ Branch 0 taken 4931 times.
✗ Branch 1 not taken.
4931 if (ret == AVERROR_EOF)
2718 4931 av_log(fg, AV_LOG_VERBOSE, "Filtergraph returned EOF, finishing\n");
2719 else
2720 av_log(fg, AV_LOG_ERROR,
2721 "Error requesting a frame from the filtergraph: %s\n",
2722 av_err2str(ret));
2723 4931 return ret;
2724 }
2725 30379 fgt->next_in = fg->nb_inputs;
2726
2727 30379 did_step = 1;
2728 }
2729
2730 3061 return AVERROR_EOF;
2731 }
2732
2733 948 static void sub2video_heartbeat(InputFilter *ifilter, int64_t pts, AVRational tb)
2734 {
2735 948 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2736 int64_t pts2;
2737
2738 /* subtitles seem to be usually muxed ahead of other streams;
2739 if not, subtracting a larger time here is necessary */
2740 948 pts2 = av_rescale_q(pts, tb, ifp->time_base) - 1;
2741
2742 /* do not send the heartbeat frame if the subtitle is already ahead */
2743
2/2
✓ Branch 0 taken 769 times.
✓ Branch 1 taken 179 times.
948 if (pts2 <= ifp->sub2video.last_pts)
2744 769 return;
2745
2746
3/4
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 91 times.
179 if (pts2 >= ifp->sub2video.end_pts || ifp->sub2video.initialize)
2747 /* if we have hit the end of the current displayed subpicture,
2748 or if we need to initialize the system, update the
2749 overlaid subpicture and its start/end times */
2750 88 sub2video_update(ifp, pts2 + 1, NULL);
2751 else
2752 91 sub2video_push_ref(ifp, pts2);
2753 }
2754
2755 1078 static int sub2video_frame(InputFilter *ifilter, AVFrame *frame, int buffer)
2756 {
2757 1078 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2758 int ret;
2759
2760
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 1040 times.
1078 if (buffer) {
2761 AVFrame *tmp;
2762
2763
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (!frame)
2764 return 0;
2765
2766 38 tmp = av_frame_alloc();
2767
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (!tmp)
2768 return AVERROR(ENOMEM);
2769
2770 38 av_frame_move_ref(tmp, frame);
2771
2772 38 ret = av_fifo_write(ifp->frame_queue, &tmp, 1);
2773
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (ret < 0) {
2774 av_frame_free(&tmp);
2775 return ret;
2776 }
2777
2778 38 return 0;
2779 }
2780
2781 // heartbeat frame
2782
4/4
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 88 times.
1040 if (frame && !frame->buf[0]) {
2783 948 sub2video_heartbeat(ifilter, frame->pts, frame->time_base);
2784 948 return 0;
2785 }
2786
2787
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 88 times.
92 if (!frame) {
2788
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (ifp->sub2video.end_pts < INT64_MAX)
2789 4 sub2video_update(ifp, INT64_MAX, NULL);
2790
2791 4 return av_buffersrc_add_frame(ifilter->filter, NULL);
2792 }
2793
2794
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 ifp->width = frame->width ? frame->width : ifp->width;
2795
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 ifp->height = frame->height ? frame->height : ifp->height;
2796
2797 88 sub2video_update(ifp, INT64_MIN, (const AVSubtitle*)frame->buf[0]->data);
2798
2799 88 return 0;
2800 }
2801
2802 3318 static int send_eof(FilterGraphThread *fgt, InputFilter *ifilter,
2803 int64_t pts, AVRational tb)
2804 {
2805 3318 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2806 int ret;
2807
2808
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3318 times.
3318 if (fgt->eof_in[ifilter->index])
2809 return 0;
2810
2811 3318 fgt->eof_in[ifilter->index] = 1;
2812
2813
2/2
✓ Branch 0 taken 3310 times.
✓ Branch 1 taken 8 times.
3318 if (ifilter->filter) {
2814 3310 pts = av_rescale_q_rnd(pts, tb, ifp->time_base,
2815 AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
2816
2817 3310 ret = av_buffersrc_close(ifilter->filter, pts, AV_BUFFERSRC_FLAG_PUSH);
2818
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3310 times.
3310 if (ret < 0)
2819 return ret;
2820 } else {
2821
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5 times.
8 if (ifp->format < 0) {
2822 // the filtergraph was never configured, use the fallback parameters
2823 3 ifp->format = ifp->opts.fallback->format;
2824 3 ifp->sample_rate = ifp->opts.fallback->sample_rate;
2825 3 ifp->width = ifp->opts.fallback->width;
2826 3 ifp->height = ifp->opts.fallback->height;
2827 3 ifp->sample_aspect_ratio = ifp->opts.fallback->sample_aspect_ratio;
2828 3 ifp->color_space = ifp->opts.fallback->colorspace;
2829 3 ifp->color_range = ifp->opts.fallback->color_range;
2830 3 ifp->alpha_mode = ifp->opts.fallback->alpha_mode;
2831 3 ifp->time_base = ifp->opts.fallback->time_base;
2832
2833 3 ret = av_channel_layout_copy(&ifp->ch_layout,
2834 3 &ifp->opts.fallback->ch_layout);
2835
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0)
2836 return ret;
2837
2838 3 av_frame_side_data_free(&ifp->side_data, &ifp->nb_side_data);
2839 3 ret = clone_side_data(&ifp->side_data, &ifp->nb_side_data,
2840 3 ifp->opts.fallback->side_data,
2841 3 ifp->opts.fallback->nb_side_data, 0);
2842
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0)
2843 return ret;
2844
2845
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if (ifilter_has_all_input_formats(ifilter->graph)) {
2846 3 ret = configure_filtergraph(ifilter->graph, fgt);
2847
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0) {
2848 av_log(ifilter->graph, AV_LOG_ERROR, "Error initializing filters!\n");
2849 return ret;
2850 }
2851 }
2852 }
2853
2854
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (ifp->format < 0) {
2855 av_log(ifilter->graph, AV_LOG_ERROR,
2856 "Cannot determine format of input %s after EOF\n",
2857 ifp->opts.name);
2858 return AVERROR_INVALIDDATA;
2859 }
2860 }
2861
2862 3318 return 0;
2863 }
2864
2865 enum ReinitReason {
2866 VIDEO_CHANGED = (1 << 0),
2867 AUDIO_CHANGED = (1 << 1),
2868 MATRIX_CHANGED = (1 << 2),
2869 DOWNMIX_CHANGED = (1 << 3),
2870 HWACCEL_CHANGED = (1 << 4)
2871 };
2872
2873 181 static const char *unknown_if_null(const char *str)
2874 {
2875
1/2
✓ Branch 0 taken 181 times.
✗ Branch 1 not taken.
181 return str ? str : "unknown";
2876 }
2877
2878 377066 static int send_frame(FilterGraph *fg, FilterGraphThread *fgt,
2879 InputFilter *ifilter, AVFrame *frame)
2880 {
2881 377066 FilterGraphPriv *fgp = fgp_from_fg(fg);
2882 377066 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2883 FrameData *fd;
2884 AVFrameSideData *sd;
2885 377066 int need_reinit = 0, ret;
2886
2887 /* determine if the parameters for this input changed */
2888
2/3
✓ Branch 0 taken 260286 times.
✓ Branch 1 taken 116780 times.
✗ Branch 2 not taken.
377066 switch (ifilter->type) {
2889 260286 case AVMEDIA_TYPE_AUDIO:
2890
2/2
✓ Branch 0 taken 259020 times.
✓ Branch 1 taken 1266 times.
260286 if (ifp->format != frame->format ||
2891
3/4
✓ Branch 0 taken 259020 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 259019 times.
518040 ifp->sample_rate != frame->sample_rate ||
2892 259020 av_channel_layout_compare(&ifp->ch_layout, &frame->ch_layout))
2893 1267 need_reinit |= AUDIO_CHANGED;
2894 260286 break;
2895 116780 case AVMEDIA_TYPE_VIDEO:
2896
2/2
✓ Branch 0 taken 111096 times.
✓ Branch 1 taken 5684 times.
116780 if (ifp->format != frame->format ||
2897
2/2
✓ Branch 0 taken 111068 times.
✓ Branch 1 taken 28 times.
111096 ifp->width != frame->width ||
2898
2/2
✓ Branch 0 taken 111062 times.
✓ Branch 1 taken 6 times.
111068 ifp->height != frame->height ||
2899
1/2
✓ Branch 0 taken 111062 times.
✗ Branch 1 not taken.
111062 ifp->color_space != frame->colorspace ||
2900
1/2
✓ Branch 0 taken 111062 times.
✗ Branch 1 not taken.
111062 ifp->color_range != frame->color_range ||
2901
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 111062 times.
111062 ifp->alpha_mode != frame->alpha_mode)
2902 5718 need_reinit |= VIDEO_CHANGED;
2903 116780 break;
2904 }
2905
2906
2/2
✓ Branch 1 taken 121 times.
✓ Branch 2 taken 376945 times.
377066 if (sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX)) {
2907
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 17 times.
121 if (!ifp->displaymatrix_present ||
2908
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 104 times.
104 memcmp(sd->data, ifp->displaymatrix, sizeof(ifp->displaymatrix)))
2909 17 need_reinit |= MATRIX_CHANGED;
2910
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 376945 times.
376945 } else if (ifp->displaymatrix_present)
2911 need_reinit |= MATRIX_CHANGED;
2912
2913
2/2
✓ Branch 1 taken 419 times.
✓ Branch 2 taken 376647 times.
377066 if (sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DOWNMIX_INFO)) {
2914
2/2
✓ Branch 0 taken 414 times.
✓ Branch 1 taken 5 times.
419 if (!ifp->downmixinfo_present ||
2915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 414 times.
414 memcmp(sd->data, &ifp->downmixinfo, sizeof(ifp->downmixinfo)))
2916 5 need_reinit |= DOWNMIX_CHANGED;
2917
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 376647 times.
376647 } else if (ifp->downmixinfo_present)
2918 need_reinit |= DOWNMIX_CHANGED;
2919
2920
5/6
✓ Branch 0 taken 6985 times.
✓ Branch 1 taken 370081 times.
✓ Branch 2 taken 47 times.
✓ Branch 3 taken 6938 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 47 times.
377066 if (need_reinit && fgt->graph && (ifp->opts.flags & IFILTER_FLAG_DROPCHANGED)) {
2921 ifp->nb_dropped++;
2922 av_log_once(fg, AV_LOG_WARNING, AV_LOG_DEBUG, &ifp->drop_warned, "Avoiding reinit; dropping frame pts: %s bound for %s\n", av_ts2str(frame->pts), ifilter->name);
2923 av_frame_unref(frame);
2924 return 0;
2925 }
2926
2927
4/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 377016 times.
✓ Branch 2 taken 49 times.
✓ Branch 3 taken 1 times.
377066 if (!(ifp->opts.flags & IFILTER_FLAG_REINIT) && fgt->graph)
2928 49 need_reinit = 0;
2929
2930
1/2
✓ Branch 0 taken 377066 times.
✗ Branch 1 not taken.
377066 if (!!ifp->hw_frames_ctx != !!frame->hw_frames_ctx ||
2931
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 377066 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
377066 (ifp->hw_frames_ctx && ifp->hw_frames_ctx->data != frame->hw_frames_ctx->data))
2932 need_reinit |= HWACCEL_CHANGED;
2933
2934
2/2
✓ Branch 0 taken 6985 times.
✓ Branch 1 taken 370081 times.
377066 if (need_reinit) {
2935 6985 ret = ifilter_parameters_from_frame(ifilter, frame);
2936
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6985 times.
6985 if (ret < 0)
2937 return ret;
2938 }
2939
2940 /* (re)init the graph if possible, otherwise buffer the frame and return */
2941
4/4
✓ Branch 0 taken 370081 times.
✓ Branch 1 taken 6985 times.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 370048 times.
377066 if (need_reinit || !fgt->graph) {
2942 7018 AVFrame *tmp = av_frame_alloc();
2943
2944
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7018 times.
7018 if (!tmp)
2945 118 return AVERROR(ENOMEM);
2946
2947
2/2
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 6901 times.
7018 if (!ifilter_has_all_input_formats(fg)) {
2948 117 av_frame_move_ref(tmp, frame);
2949
2950 117 ret = av_fifo_write(ifp->frame_queue, &tmp, 1);
2951
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
117 if (ret < 0)
2952 av_frame_free(&tmp);
2953
2954 117 return ret;
2955 }
2956
2957
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 6854 times.
6901 ret = fgt->graph ? read_frames(fg, fgt, tmp) : 0;
2958 6901 av_frame_free(&tmp);
2959
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6900 times.
6901 if (ret < 0)
2960 1 return ret;
2961
2962
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 6854 times.
6900 if (fgt->graph) {
2963 AVBPrint reason;
2964 46 av_bprint_init(&reason, 0, AV_BPRINT_SIZE_AUTOMATIC);
2965
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 45 times.
46 if (need_reinit & AUDIO_CHANGED) {
2966 1 const char *sample_format_name = av_get_sample_fmt_name(frame->format);
2967 1 av_bprintf(&reason, "audio parameters changed to %d Hz, ", frame->sample_rate);
2968 1 av_channel_layout_describe_bprint(&frame->ch_layout, &reason);
2969 1 av_bprintf(&reason, ", %s, ", unknown_if_null(sample_format_name));
2970 }
2971
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 1 times.
46 if (need_reinit & VIDEO_CHANGED) {
2972 45 const char *pixel_format_name = av_get_pix_fmt_name(frame->format);
2973 45 const char *color_space_name = av_color_space_name(frame->colorspace);
2974 45 const char *color_range_name = av_color_range_name(frame->color_range);
2975 45 const char *alpha_mode = av_alpha_mode_name(frame->alpha_mode);
2976 45 av_bprintf(&reason, "video parameters changed to %s(%s, %s), %dx%d, %s alpha,",
2977 unknown_if_null(pixel_format_name), unknown_if_null(color_range_name),
2978 unknown_if_null(color_space_name), frame->width, frame->height,
2979 unknown_if_null(alpha_mode));
2980 }
2981
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (need_reinit & MATRIX_CHANGED)
2982 av_bprintf(&reason, "display matrix changed, ");
2983
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (need_reinit & DOWNMIX_CHANGED)
2984 av_bprintf(&reason, "downmix medatata changed, ");
2985
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (need_reinit & HWACCEL_CHANGED)
2986 av_bprintf(&reason, "hwaccel changed, ");
2987
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 if (reason.len > 1)
2988 46 reason.str[reason.len - 2] = '\0'; // remove last comma
2989
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 av_log(fg, AV_LOG_INFO, "Reconfiguring filter graph%s%s\n", reason.len ? " because " : "", reason.str);
2990 } else {
2991 /* Choke all input to avoid buffering excessive frames while the
2992 * initial filter graph is being configured, and before we have a
2993 * preferred input */
2994 6854 sch_filter_choke_inputs(fgp->sch, fgp->sch_idx);
2995 }
2996
2997 6900 ret = configure_filtergraph(fg, fgt);
2998
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6900 times.
6900 if (ret < 0) {
2999 av_log(fg, AV_LOG_ERROR, "Error reinitializing filters!\n");
3000 return ret;
3001 }
3002 }
3003
3004 376948 frame->pts = av_rescale_q(frame->pts, frame->time_base, ifp->time_base);
3005 376948 frame->duration = av_rescale_q(frame->duration, frame->time_base, ifp->time_base);
3006 376948 frame->time_base = ifp->time_base;
3007
3008
2/2
✓ Branch 0 taken 116690 times.
✓ Branch 1 taken 260258 times.
376948 if (ifp->displaymatrix_applied)
3009 116690 av_frame_remove_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX);
3010
3011 376948 fd = frame_data(frame);
3012
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 376948 times.
376948 if (!fd)
3013 return AVERROR(ENOMEM);
3014 376948 fd->wallclock[LATENCY_PROBE_FILTER_PRE] = av_gettime_relative();
3015
3016 376948 ret = av_buffersrc_add_frame_flags(ifilter->filter, frame,
3017 AV_BUFFERSRC_FLAG_PUSH);
3018
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 376948 times.
376948 if (ret < 0) {
3019 av_frame_unref(frame);
3020 if (ret != AVERROR_EOF)
3021 av_log(fg, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret));
3022 return ret;
3023 }
3024
3025 376948 return 0;
3026 }
3027
3028 7998 static void fg_thread_set_name(const FilterGraph *fg)
3029 {
3030 char name[16];
3031
2/2
✓ Branch 1 taken 6793 times.
✓ Branch 2 taken 1205 times.
7998 if (filtergraph_is_simple(fg)) {
3032 6793 OutputFilterPriv *ofp = ofp_from_ofilter(fg->outputs[0]);
3033 13586 snprintf(name, sizeof(name), "%cf%s",
3034 6793 av_get_media_type_string(ofp->ofilter.type)[0],
3035 ofp->ofilter.output_name);
3036 } else {
3037 1205 snprintf(name, sizeof(name), "fc%d", fg->index);
3038 }
3039
3040 7998 ff_thread_setname(name);
3041 7998 }
3042
3043 7998 static void fg_thread_uninit(FilterGraphThread *fgt)
3044 {
3045
1/2
✓ Branch 0 taken 7998 times.
✗ Branch 1 not taken.
7998 if (fgt->frame_queue_out) {
3046 AVFrame *frame;
3047
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7998 times.
7998 while (av_fifo_read(fgt->frame_queue_out, &frame, 1) >= 0)
3048 av_frame_free(&frame);
3049 7998 av_fifo_freep2(&fgt->frame_queue_out);
3050 }
3051
3052 7998 av_frame_free(&fgt->frame);
3053 7998 av_freep(&fgt->eof_in);
3054 7998 av_freep(&fgt->eof_out);
3055
3056 7998 avfilter_graph_free(&fgt->graph);
3057
3058 7998 memset(fgt, 0, sizeof(*fgt));
3059 7998 }
3060
3061 7998 static int fg_thread_init(FilterGraphThread *fgt, const FilterGraph *fg)
3062 {
3063 7998 memset(fgt, 0, sizeof(*fgt));
3064
3065 7998 fgt->frame = av_frame_alloc();
3066
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7998 times.
7998 if (!fgt->frame)
3067 goto fail;
3068
3069 7998 fgt->eof_in = av_calloc(fg->nb_inputs, sizeof(*fgt->eof_in));
3070
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7998 times.
7998 if (!fgt->eof_in)
3071 goto fail;
3072
3073 7998 fgt->eof_out = av_calloc(fg->nb_outputs, sizeof(*fgt->eof_out));
3074
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7998 times.
7998 if (!fgt->eof_out)
3075 goto fail;
3076
3077 7998 fgt->frame_queue_out = av_fifo_alloc2(1, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
3078
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7998 times.
7998 if (!fgt->frame_queue_out)
3079 goto fail;
3080
3081 7998 return 0;
3082
3083 fail:
3084 fg_thread_uninit(fgt);
3085 return AVERROR(ENOMEM);
3086 }
3087
3088 7998 static int filter_thread(void *arg)
3089 {
3090 7998 FilterGraphPriv *fgp = arg;
3091 7998 FilterGraph *fg = &fgp->fg;
3092
3093 FilterGraphThread fgt;
3094 7998 int ret = 0, input_status = 0;
3095
3096 7998 ret = fg_thread_init(&fgt, fg);
3097
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7998 times.
7998 if (ret < 0)
3098 goto finish;
3099
3100 7998 fg_thread_set_name(fg);
3101
3102 // if we have all input parameters the graph can now be configured
3103
2/2
✓ Branch 1 taken 6857 times.
✓ Branch 2 taken 1141 times.
7998 if (ifilter_has_all_input_formats(fg)) {
3104 1141 ret = configure_filtergraph(fg, &fgt);
3105
1/2
✓ Branch 0 taken 1141 times.
✗ Branch 1 not taken.
1141 if (ret < 0) {
3106 av_log(fg, AV_LOG_ERROR, "Error configuring filter graph: %s\n",
3107 av_err2str(ret));
3108 goto finish;
3109 }
3110 }
3111
3112 402974 while (1) {
3113 InputFilter *ifilter;
3114 410972 InputFilterPriv *ifp = NULL;
3115 enum FrameOpaque o;
3116 410972 unsigned input_idx = fgt.next_in;
3117
3118 410972 input_status = sch_filter_receive(fgp->sch, fgp->sch_idx,
3119 410972 &input_idx, fgt.frame);
3120
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 410965 times.
410972 if (input_status == AVERROR_EOF) {
3121 7 av_log(fg, AV_LOG_VERBOSE, "Filtering thread received EOF\n");
3122 7 break;
3123
2/2
✓ Branch 0 taken 29541 times.
✓ Branch 1 taken 381424 times.
410965 } else if (input_status == AVERROR(EAGAIN)) {
3124 // should only happen when we didn't request any input
3125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29541 times.
29541 av_assert0(input_idx == fg->nb_inputs);
3126 29541 goto read_frames;
3127 }
3128
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 381424 times.
381424 av_assert0(input_status >= 0);
3129
3130 381424 o = (intptr_t)fgt.frame->opaque;
3131
3132 381424 o = (intptr_t)fgt.frame->opaque;
3133
3134 // message on the control stream
3135
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 381424 times.
381424 if (input_idx == fg->nb_inputs) {
3136 FilterCommand *fc;
3137
3138 av_assert0(o == FRAME_OPAQUE_SEND_COMMAND && fgt.frame->buf[0]);
3139
3140 fc = (FilterCommand*)fgt.frame->buf[0]->data;
3141 send_command(fg, fgt.graph, fc->time, fc->target, fc->command, fc->arg,
3142 fc->all_filters);
3143 av_frame_unref(fgt.frame);
3144 1 continue;
3145 }
3146
3147 // we received an input frame or EOF
3148 381424 ifilter = fg->inputs[input_idx];
3149 381424 ifp = ifp_from_ifilter(ifilter);
3150
3151
2/2
✓ Branch 0 taken 1040 times.
✓ Branch 1 taken 380384 times.
381424 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
3152
3/4
✓ Branch 0 taken 1040 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 92 times.
1040 int hb_frame = input_status >= 0 && o == FRAME_OPAQUE_SUB_HEARTBEAT;
3153
2/2
✓ Branch 0 taken 948 times.
✓ Branch 1 taken 4 times.
1040 ret = sub2video_frame(ifilter, (fgt.frame->buf[0] || hb_frame) ? fgt.frame : NULL,
3154
2/2
✓ Branch 0 taken 952 times.
✓ Branch 1 taken 88 times.
1040 !fgt.graph);
3155
2/2
✓ Branch 0 taken 377066 times.
✓ Branch 1 taken 3318 times.
380384 } else if (fgt.frame->buf[0]) {
3156 377066 ret = send_frame(fg, &fgt, ifilter, fgt.frame);
3157 } else {
3158 av_assert1(o == FRAME_OPAQUE_EOF);
3159 3318 ret = send_eof(&fgt, ifilter, fgt.frame->pts, fgt.frame->time_base);
3160 }
3161 381424 av_frame_unref(fgt.frame);
3162
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 381423 times.
381424 if (ret == AVERROR_EOF) {
3163 1 av_log(fg, AV_LOG_VERBOSE, "Input %u no longer accepts new data\n",
3164 input_idx);
3165 1 sch_filter_receive_finish(fgp->sch, fgp->sch_idx, input_idx);
3166 1 continue;
3167 }
3168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 381423 times.
381423 if (ret < 0)
3169 goto finish;
3170
3171 381423 read_frames:
3172 // retrieve all newly available frames
3173 410964 ret = read_frames(fg, &fgt, fgt.frame);
3174
2/2
✓ Branch 0 taken 7991 times.
✓ Branch 1 taken 402973 times.
410964 if (ret == AVERROR_EOF) {
3175 7991 av_log(fg, AV_LOG_VERBOSE, "All consumers returned EOF\n");
3176
3/4
✓ Branch 0 taken 6852 times.
✓ Branch 1 taken 1139 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6852 times.
7991 if (ifp && ifp->opts.flags & IFILTER_FLAG_DROPCHANGED)
3177 av_log(fg, AV_LOG_INFO, "Total changed input frames dropped : %"PRId64"\n", ifp->nb_dropped);
3178 7991 break;
3179
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 402973 times.
402973 } else if (ret < 0) {
3180 av_log(fg, AV_LOG_ERROR, "Error sending frames to consumers: %s\n",
3181 av_err2str(ret));
3182 goto finish;
3183 }
3184 }
3185
3186
2/2
✓ Branch 0 taken 8130 times.
✓ Branch 1 taken 7998 times.
16128 for (unsigned i = 0; i < fg->nb_outputs; i++) {
3187 8130 OutputFilterPriv *ofp = ofp_from_ofilter(fg->outputs[i]);
3188
3189
3/4
✓ Branch 0 taken 1552 times.
✓ Branch 1 taken 6578 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1552 times.
8130 if (fgt.eof_out[i] || !fgt.graph)
3190 6578 continue;
3191
3192 1552 ret = fg_output_frame(ofp, &fgt, NULL);
3193
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1552 times.
1552 if (ret < 0)
3194 goto finish;
3195 }
3196
3197 7998 finish:
3198
3199
2/4
✓ Branch 0 taken 7998 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7998 times.
7998 if (print_graphs || print_graphs_file)
3200 print_filtergraph(fg, fgt.graph);
3201
3202 // EOF is normal termination
3203
2/2
✓ Branch 0 taken 6512 times.
✓ Branch 1 taken 1486 times.
7998 if (ret == AVERROR_EOF)
3204 6512 ret = 0;
3205
3206 7998 fg_thread_uninit(&fgt);
3207
3208 7998 return ret;
3209 }
3210
3211 void fg_send_command(FilterGraph *fg, double time, const char *target,
3212 const char *command, const char *arg, int all_filters)
3213 {
3214 FilterGraphPriv *fgp = fgp_from_fg(fg);
3215 AVBufferRef *buf;
3216 FilterCommand *fc;
3217
3218 fc = av_mallocz(sizeof(*fc));
3219 if (!fc)
3220 return;
3221
3222 buf = av_buffer_create((uint8_t*)fc, sizeof(*fc), filter_command_free, NULL, 0);
3223 if (!buf) {
3224 av_freep(&fc);
3225 return;
3226 }
3227
3228 fc->target = av_strdup(target);
3229 fc->command = av_strdup(command);
3230 fc->arg = av_strdup(arg);
3231 if (!fc->target || !fc->command || !fc->arg) {
3232 av_buffer_unref(&buf);
3233 return;
3234 }
3235
3236 fc->time = time;
3237 fc->all_filters = all_filters;
3238
3239 fgp->frame->buf[0] = buf;
3240 fgp->frame->opaque = (void*)(intptr_t)FRAME_OPAQUE_SEND_COMMAND;
3241
3242 sch_filter_command(fgp->sch, fgp->sch_idx, fgp->frame);
3243 }
3244