FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_filter.c
Date: 2026-05-03 03:13:14
Exec Total Coverage
Lines: 1430 1862 76.8%
Functions: 71 75 94.7%
Branches: 846 1275 66.4%

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