FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_filter.c
Date: 2026-04-11 18:33:02
Exec Total Coverage
Lines: 1421 1860 76.4%
Functions: 71 75 94.7%
Branches: 840 1271 66.1%

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