FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_filter.c
Date: 2026-04-19 20:43:40
Exec Total Coverage
Lines: 1423 1862 76.4%
Functions: 71 75 94.7%
Branches: 843 1275 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 2284846 static FilterGraphPriv *fgp_from_fg(FilterGraph *fg)
71 {
72 2284846 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 1314985 static InputFilterPriv *ifp_from_ifilter(InputFilter *ifilter)
161 {
162 1314985 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 554622 static OutputFilterPriv *ofp_from_ofilter(OutputFilter *ofilter)
250 {
251 554622 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 15234 static int ifilter_has_all_input_formats(FilterGraph *fg)
618 {
619
2/2
✓ Branch 0 taken 14471 times.
✓ Branch 1 taken 8161 times.
22632 for (int i = 0; i < fg->nb_inputs; i++) {
620 14471 InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[i]);
621
2/2
✓ Branch 0 taken 7073 times.
✓ Branch 1 taken 7398 times.
14471 if (ifp->format < 0)
622 7073 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 // skip add scale for hardware format
1686
2/2
✓ Branch 0 taken 1370 times.
✓ Branch 1 taken 25 times.
1395 !(ofp->format != AV_PIX_FMT_NONE &&
1687
1/2
✓ Branch 1 taken 1370 times.
✗ Branch 2 not taken.
1370 av_pix_fmt_desc_get(ofp->format)->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
1688 char args[255];
1689 AVFilterContext *filter;
1690 1395 const AVDictionaryEntry *e = NULL;
1691
1692 1395 snprintf(args, sizeof(args), "%d:%d",
1693 ofp->width, ofp->height);
1694
1695
2/2
✓ Branch 1 taken 1381 times.
✓ Branch 2 taken 1395 times.
2776 while ((e = av_dict_iterate(ofp->sws_opts, e))) {
1696 1381 av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
1697 }
1698
1699 1395 snprintf(name, sizeof(name), "scaler_out_%s", ofilter->output_name);
1700
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1395 times.
1395 if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
1701 name, args, NULL, graph)) < 0)
1702 return ret;
1703
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1395 times.
1395 if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
1704 return ret;
1705
1706 1395 last_filter = filter;
1707 1395 pad_idx = 0;
1708 }
1709
1710
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) ||
1711 ofp->format != AV_PIX_FMT_NONE || !ofp->pix_fmts);
1712 6923 av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
1713 6923 choose_pix_fmts(ofp, &bprint);
1714 6923 choose_color_spaces(ofp, &bprint);
1715 6923 choose_color_ranges(ofp, &bprint);
1716 6923 choose_alpha_modes(ofp, &bprint);
1717
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6923 times.
6923 if (!av_bprint_is_complete(&bprint))
1718 return AVERROR(ENOMEM);
1719
1720
2/2
✓ Branch 0 taken 5761 times.
✓ Branch 1 taken 1162 times.
6923 if (bprint.len) {
1721 AVFilterContext *filter;
1722
1723 5761 ret = avfilter_graph_create_filter(&filter,
1724 avfilter_get_by_name("format"),
1725 5761 "format", bprint.str, NULL, graph);
1726 5761 av_bprint_finalize(&bprint, NULL);
1727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5761 times.
5761 if (ret < 0)
1728 return ret;
1729
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5761 times.
5761 if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
1730 return ret;
1731
1732 5761 last_filter = filter;
1733 5761 pad_idx = 0;
1734 }
1735
1736 6923 snprintf(name, sizeof(name), "trim_out_%s", ofilter->output_name);
1737 6923 ret = insert_trim(fgp, ofp->trim_start_us, ofp->trim_duration_us,
1738 &last_filter, &pad_idx, name);
1739
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6923 times.
6923 if (ret < 0)
1740 return ret;
1741
1742
1743
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6923 times.
6923 if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
1744 return ret;
1745
1746 6923 return 0;
1747 }
1748
1749 1372 static int configure_output_audio_filter(FilterGraphPriv *fgp, AVFilterGraph *graph,
1750 OutputFilter *ofilter, AVFilterInOut *out)
1751 {
1752 1372 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1753 1372 AVFilterContext *last_filter = out->filter_ctx;
1754 1372 int pad_idx = out->pad_idx;
1755 AVBPrint args;
1756 char name[255];
1757 int ret;
1758
1759 1372 snprintf(name, sizeof(name), "out_%s", ofilter->output_name);
1760 1372 ret = avfilter_graph_create_filter(&ofilter->filter,
1761 avfilter_get_by_name("abuffersink"),
1762 name, NULL, NULL, graph);
1763
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1372 times.
1372 if (ret < 0)
1764 return ret;
1765
1766 #define AUTO_INSERT_FILTER(opt_name, filter_name, arg) do { \
1767 AVFilterContext *filt_ctx; \
1768 \
1769 av_log(ofilter, AV_LOG_INFO, opt_name " is forwarded to lavfi " \
1770 "similarly to -af " filter_name "=%s.\n", arg); \
1771 \
1772 ret = avfilter_graph_create_filter(&filt_ctx, \
1773 avfilter_get_by_name(filter_name), \
1774 filter_name, arg, NULL, graph); \
1775 if (ret < 0) \
1776 goto fail; \
1777 \
1778 ret = avfilter_link(last_filter, pad_idx, filt_ctx, 0); \
1779 if (ret < 0) \
1780 goto fail; \
1781 \
1782 last_filter = filt_ctx; \
1783 pad_idx = 0; \
1784 } while (0)
1785 1372 av_bprint_init(&args, 0, AV_BPRINT_SIZE_UNLIMITED);
1786
1787 1372 choose_sample_fmts(ofp, &args);
1788 1372 choose_sample_rates(ofp, &args);
1789 1372 choose_channel_layouts(ofp, &args);
1790
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1372 times.
1372 if (!av_bprint_is_complete(&args)) {
1791 ret = AVERROR(ENOMEM);
1792 goto fail;
1793 }
1794
1/2
✓ Branch 0 taken 1372 times.
✗ Branch 1 not taken.
1372 if (args.len) {
1795 AVFilterContext *format;
1796
1797 1372 snprintf(name, sizeof(name), "format_out_%s", ofilter->output_name);
1798 1372 ret = avfilter_graph_create_filter(&format,
1799 avfilter_get_by_name("aformat"),
1800 1372 name, args.str, NULL, graph);
1801
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1372 times.
1372 if (ret < 0)
1802 goto fail;
1803
1804 1372 ret = avfilter_link(last_filter, pad_idx, format, 0);
1805
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1372 times.
1372 if (ret < 0)
1806 goto fail;
1807
1808 1372 last_filter = format;
1809 1372 pad_idx = 0;
1810 }
1811
1812
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1372 times.
1372 if (ofilter->apad) {
1813 AUTO_INSERT_FILTER("-apad", "apad", ofilter->apad);
1814 fgp->have_sources = 1;
1815 }
1816
1817 1372 snprintf(name, sizeof(name), "trim for output %s", ofilter->output_name);
1818 1372 ret = insert_trim(fgp, ofp->trim_start_us, ofp->trim_duration_us,
1819 &last_filter, &pad_idx, name);
1820
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1372 times.
1372 if (ret < 0)
1821 goto fail;
1822
1823
1/2
✓ Branch 1 taken 1372 times.
✗ Branch 2 not taken.
1372 if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
1824 goto fail;
1825 1372 fail:
1826 1372 av_bprint_finalize(&args, NULL);
1827
1828 1372 return ret;
1829 }
1830
1831 8295 static int configure_output_filter(FilterGraphPriv *fgp, AVFilterGraph *graph,
1832 OutputFilter *ofilter, AVFilterInOut *out)
1833 {
1834
2/3
✓ Branch 0 taken 6923 times.
✓ Branch 1 taken 1372 times.
✗ Branch 2 not taken.
8295 switch (ofilter->type) {
1835 6923 case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fgp, graph, ofilter, out);
1836 1372 case AVMEDIA_TYPE_AUDIO: return configure_output_audio_filter(fgp, graph, ofilter, out);
1837 default: av_assert0(0); return 0;
1838 }
1839 }
1840
1841 4 static void sub2video_prepare(InputFilterPriv *ifp)
1842 {
1843 4 ifp->sub2video.last_pts = INT64_MIN;
1844 4 ifp->sub2video.end_pts = INT64_MIN;
1845
1846 /* sub2video structure has been (re-)initialized.
1847 Mark it as such so that the system will be
1848 initialized with the first received heartbeat. */
1849 4 ifp->sub2video.initialize = 1;
1850 4 }
1851
1852 5766 static int configure_input_video_filter(FilterGraph *fg, AVFilterGraph *graph,
1853 InputFilter *ifilter, AVFilterInOut *in)
1854 {
1855 5766 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1856
1857 AVFilterContext *last_filter;
1858 5766 const AVFilter *buffer_filt = avfilter_get_by_name("buffer");
1859 const AVPixFmtDescriptor *desc;
1860 char name[255];
1861 5766 int ret, pad_idx = 0;
1862 5766 AVBufferSrcParameters *par = av_buffersrc_parameters_alloc();
1863
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5766 times.
5766 if (!par)
1864 return AVERROR(ENOMEM);
1865
1866
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5762 times.
5766 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE)
1867 4 sub2video_prepare(ifp);
1868
1869 5766 snprintf(name, sizeof(name), "graph %d input from stream %s", fg->index,
1870 ifp->opts.name);
1871
1872 5766 ifilter->filter = avfilter_graph_alloc_filter(graph, buffer_filt, name);
1873
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5766 times.
5766 if (!ifilter->filter) {
1874 ret = AVERROR(ENOMEM);
1875 goto fail;
1876 }
1877
1878 5766 par->format = ifp->format;
1879 5766 par->time_base = ifp->time_base;
1880 5766 par->frame_rate = ifp->opts.framerate;
1881 5766 par->width = ifp->width;
1882 5766 par->height = ifp->height;
1883 5766 par->sample_aspect_ratio = ifp->sample_aspect_ratio.den > 0 ?
1884
2/2
✓ Branch 0 taken 5762 times.
✓ Branch 1 taken 4 times.
5766 ifp->sample_aspect_ratio : (AVRational){ 0, 1 };
1885 5766 par->color_space = ifp->color_space;
1886 5766 par->color_range = ifp->color_range;
1887 5766 par->alpha_mode = ifp->alpha_mode;
1888 5766 par->hw_frames_ctx = ifp->hw_frames_ctx;
1889 5766 par->side_data = ifp->side_data;
1890 5766 par->nb_side_data = ifp->nb_side_data;
1891
1892 5766 ret = av_buffersrc_parameters_set(ifilter->filter, par);
1893
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5766 times.
5766 if (ret < 0)
1894 goto fail;
1895 5766 av_freep(&par);
1896
1897 5766 ret = avfilter_init_dict(ifilter->filter, NULL);
1898
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5766 times.
5766 if (ret < 0)
1899 goto fail;
1900
1901 5766 last_filter = ifilter->filter;
1902
1903 5766 desc = av_pix_fmt_desc_get(ifp->format);
1904
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5766 times.
5766 av_assert0(desc);
1905
1906
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 5760 times.
5766 if ((ifp->opts.flags & IFILTER_FLAG_CROP)) {
1907 char crop_buf[64];
1908 6 snprintf(crop_buf, sizeof(crop_buf), "w=iw-%u-%u:h=ih-%u-%u:x=%u:y=%u",
1909 ifp->opts.crop_left, ifp->opts.crop_right,
1910 ifp->opts.crop_top, ifp->opts.crop_bottom,
1911 ifp->opts.crop_left, ifp->opts.crop_top);
1912 6 ret = insert_filter(&last_filter, &pad_idx, "crop", crop_buf);
1913
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ret < 0)
1914 return ret;
1915 }
1916
1917 // TODO: insert hwaccel enabled filters like transpose_vaapi into the graph
1918 5766 ifp->displaymatrix_applied = 0;
1919
2/2
✓ Branch 0 taken 5761 times.
✓ Branch 1 taken 5 times.
5766 if ((ifp->opts.flags & IFILTER_FLAG_AUTOROTATE) &&
1920
1/2
✓ Branch 0 taken 5761 times.
✗ Branch 1 not taken.
5761 !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
1921 5761 int32_t *displaymatrix = ifp->displaymatrix;
1922 double theta;
1923
1924 5761 theta = get_rotation(displaymatrix);
1925
1926
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5756 times.
5761 if (fabs(theta - 90) < 1.0) {
1927 5 ret = insert_filter(&last_filter, &pad_idx, "transpose",
1928
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 displaymatrix[3] > 0 ? "cclock_flip" : "clock");
1929
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5756 times.
5756 } else if (fabs(theta - 180) < 1.0) {
1930 if (displaymatrix[0] < 0) {
1931 ret = insert_filter(&last_filter, &pad_idx, "hflip", NULL);
1932 if (ret < 0)
1933 return ret;
1934 }
1935 if (displaymatrix[4] < 0) {
1936 ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
1937 }
1938
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5756 times.
5756 } else if (fabs(theta - 270) < 1.0) {
1939 ret = insert_filter(&last_filter, &pad_idx, "transpose",
1940 displaymatrix[3] < 0 ? "clock_flip" : "cclock");
1941
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5756 times.
5756 } else if (fabs(theta) > 1.0) {
1942 char rotate_buf[64];
1943 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1944 ret = insert_filter(&last_filter, &pad_idx, "rotate", rotate_buf);
1945
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 5747 times.
5756 } else if (fabs(theta) < 1.0) {
1946
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) {
1947 ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
1948 }
1949 }
1950
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5761 times.
5761 if (ret < 0)
1951 return ret;
1952
1953 5761 ifp->displaymatrix_applied = 1;
1954 }
1955
1956 5766 snprintf(name, sizeof(name), "trim_in_%s", ifp->opts.name);
1957 5766 ret = insert_trim(fg, ifp->opts.trim_start_us, ifp->opts.trim_end_us,
1958 &last_filter, &pad_idx, name);
1959
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5766 times.
5766 if (ret < 0)
1960 return ret;
1961
1962
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)
1963 return ret;
1964 5766 return 0;
1965 fail:
1966 av_freep(&par);
1967
1968 return ret;
1969 }
1970
1971 1309 static int configure_input_audio_filter(FilterGraph *fg, AVFilterGraph *graph,
1972 InputFilter *ifilter, AVFilterInOut *in)
1973 {
1974 1309 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1975 AVFilterContext *last_filter;
1976 AVBufferSrcParameters *par;
1977 1309 const AVFilter *abuffer_filt = avfilter_get_by_name("abuffer");
1978 AVBPrint args;
1979 char name[255];
1980 1309 int ret, pad_idx = 0;
1981
1982 1309 av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);
1983 1309 av_bprintf(&args, "time_base=%d/%d:sample_rate=%d:sample_fmt=%s",
1984 ifp->time_base.num, ifp->time_base.den,
1985 ifp->sample_rate,
1986 1309 av_get_sample_fmt_name(ifp->format));
1987
1/2
✓ Branch 1 taken 1309 times.
✗ Branch 2 not taken.
1309 if (av_channel_layout_check(&ifp->ch_layout) &&
1988
2/2
✓ Branch 0 taken 1289 times.
✓ Branch 1 taken 20 times.
1309 ifp->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
1989 1289 av_bprintf(&args, ":channel_layout=");
1990 1289 av_channel_layout_describe_bprint(&ifp->ch_layout, &args);
1991 } else
1992 20 av_bprintf(&args, ":channels=%d", ifp->ch_layout.nb_channels);
1993 1309 snprintf(name, sizeof(name), "graph_%d_in_%s", fg->index, ifp->opts.name);
1994
1995
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1309 times.
1309 if ((ret = avfilter_graph_create_filter(&ifilter->filter, abuffer_filt,
1996 1309 name, args.str, NULL,
1997 graph)) < 0)
1998 return ret;
1999 1309 par = av_buffersrc_parameters_alloc();
2000
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1309 times.
1309 if (!par)
2001 return AVERROR(ENOMEM);
2002 1309 par->side_data = ifp->side_data;
2003 1309 par->nb_side_data = ifp->nb_side_data;
2004 1309 ret = av_buffersrc_parameters_set(ifilter->filter, par);
2005 1309 av_free(par);
2006
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1309 times.
1309 if (ret < 0)
2007 return ret;
2008 1309 last_filter = ifilter->filter;
2009
2010 1309 snprintf(name, sizeof(name), "trim for input stream %s", ifp->opts.name);
2011 1309 ret = insert_trim(fg, ifp->opts.trim_start_us, ifp->opts.trim_end_us,
2012 &last_filter, &pad_idx, name);
2013
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1309 times.
1309 if (ret < 0)
2014 return ret;
2015
2016
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)
2017 return ret;
2018
2019 1309 return 0;
2020 }
2021
2022 7075 static int configure_input_filter(FilterGraph *fg, AVFilterGraph *graph,
2023 InputFilter *ifilter, AVFilterInOut *in)
2024 {
2025
2/3
✓ Branch 0 taken 5766 times.
✓ Branch 1 taken 1309 times.
✗ Branch 2 not taken.
7075 switch (ifilter->type) {
2026 5766 case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, graph, ifilter, in);
2027 1309 case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, graph, ifilter, in);
2028 default: av_assert0(0); return 0;
2029 }
2030 }
2031
2032 8160 static void cleanup_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
2033 {
2034
2/2
✓ Branch 0 taken 8295 times.
✓ Branch 1 taken 8160 times.
16455 for (int i = 0; i < fg->nb_outputs; i++)
2035 8295 fg->outputs[i]->filter = NULL;
2036
2/2
✓ Branch 0 taken 7075 times.
✓ Branch 1 taken 8160 times.
15235 for (int i = 0; i < fg->nb_inputs; i++)
2037 7075 fg->inputs[i]->filter = NULL;
2038 8160 avfilter_graph_free(&fgt->graph);
2039 8160 }
2040
2041 9375 static int filter_is_buffersrc(const AVFilterContext *f)
2042 {
2043
2/2
✓ Branch 0 taken 4208 times.
✓ Branch 1 taken 5167 times.
13583 return f->nb_inputs == 0 &&
2044
2/2
✓ Branch 0 taken 1827 times.
✓ Branch 1 taken 2381 times.
4208 (!strcmp(f->filter->name, "buffer") ||
2045
2/2
✓ Branch 0 taken 637 times.
✓ Branch 1 taken 1190 times.
1827 !strcmp(f->filter->name, "abuffer"));
2046 }
2047
2048 8160 static int graph_is_meta(AVFilterGraph *graph)
2049 {
2050
2/2
✓ Branch 0 taken 17856 times.
✓ Branch 1 taken 1803 times.
19659 for (unsigned i = 0; i < graph->nb_filters; i++) {
2051 17856 const AVFilterContext *f = graph->filters[i];
2052
2053 /* in addition to filters flagged as meta, also
2054 * disregard sinks and buffersources (but not other sources,
2055 * since they introduce data we are not aware of)
2056 */
2057
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) ||
2058
2/2
✓ Branch 0 taken 9375 times.
✓ Branch 1 taken 3018 times.
12393 f->nb_outputs == 0 ||
2059 9375 filter_is_buffersrc(f)))
2060 6357 return 0;
2061 }
2062 1803 return 1;
2063 }
2064
2065 static int sub2video_frame(InputFilter *ifilter, AVFrame *frame, int buffer);
2066
2067 8160 static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
2068 {
2069 8160 FilterGraphPriv *fgp = fgp_from_fg(fg);
2070 AVBufferRef *hw_device;
2071 AVFilterInOut *inputs, *outputs, *cur;
2072 8160 int ret = AVERROR_BUG, i, simple = filtergraph_is_simple(fg);
2073 8160 int have_input_eof = 0;
2074 8160 const char *graph_desc = fg->graph_desc;
2075
2076 8160 cleanup_filtergraph(fg, fgt);
2077 8160 fgt->graph = avfilter_graph_alloc();
2078
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8160 times.
8160 if (!fgt->graph)
2079 return AVERROR(ENOMEM);
2080
2081
2/2
✓ Branch 0 taken 6900 times.
✓ Branch 1 taken 1260 times.
8160 if (simple) {
2082 6900 OutputFilterPriv *ofp = ofp_from_ofilter(fg->outputs[0]);
2083
2084
2/2
✓ Branch 0 taken 389 times.
✓ Branch 1 taken 6511 times.
6900 if (filter_nbthreads) {
2085 389 ret = av_opt_set(fgt->graph, "threads", filter_nbthreads, 0);
2086
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 389 times.
389 if (ret < 0)
2087 goto fail;
2088
2/2
✓ Branch 0 taken 4075 times.
✓ Branch 1 taken 2436 times.
6511 } else if (fgp->nb_threads >= 0) {
2089 4075 ret = av_opt_set_int(fgt->graph, "threads", fgp->nb_threads, 0);
2090
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4075 times.
4075 if (ret < 0)
2091 return ret;
2092 }
2093
2094
2/2
✓ Branch 1 taken 4435 times.
✓ Branch 2 taken 2465 times.
6900 if (av_dict_count(ofp->sws_opts)) {
2095 4435 ret = av_dict_get_string(ofp->sws_opts,
2096 4435 &fgt->graph->scale_sws_opts,
2097 '=', ':');
2098
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4435 times.
4435 if (ret < 0)
2099 goto fail;
2100 }
2101
2102
2/2
✓ Branch 1 taken 60 times.
✓ Branch 2 taken 6840 times.
6900 if (av_dict_count(ofp->swr_opts)) {
2103 char *args;
2104 60 ret = av_dict_get_string(ofp->swr_opts, &args, '=', ':');
2105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 if (ret < 0)
2106 goto fail;
2107 60 av_opt_set(fgt->graph, "aresample_swr_opts", args, 0);
2108 60 av_free(args);
2109 }
2110 } else {
2111 1260 fgt->graph->nb_threads = filter_complex_nbthreads;
2112 }
2113
2114
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8159 times.
8160 if (filter_buffered_frames) {
2115 1 ret = av_opt_set_int(fgt->graph, "max_buffered_frames", filter_buffered_frames, 0);
2116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
2117 return ret;
2118 }
2119
2120 8160 hw_device = hw_device_for_filter();
2121
2122 8160 ret = graph_parse(fg, fgt->graph, graph_desc, &inputs, &outputs, hw_device);
2123
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8160 times.
8160 if (ret < 0)
2124 goto fail;
2125
2126
2/2
✓ Branch 0 taken 7075 times.
✓ Branch 1 taken 8160 times.
15235 for (cur = inputs, i = 0; cur; cur = cur->next, i++)
2127
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) {
2128 avfilter_inout_free(&inputs);
2129 avfilter_inout_free(&outputs);
2130 goto fail;
2131 }
2132 8160 avfilter_inout_free(&inputs);
2133
2134
2/2
✓ Branch 0 taken 8295 times.
✓ Branch 1 taken 8160 times.
16455 for (cur = outputs, i = 0; cur; cur = cur->next, i++) {
2135 8295 ret = configure_output_filter(fgp, fgt->graph, fg->outputs[i], cur);
2136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8295 times.
8295 if (ret < 0) {
2137 avfilter_inout_free(&outputs);
2138 goto fail;
2139 }
2140 }
2141 8160 avfilter_inout_free(&outputs);
2142
2143
2/2
✓ Branch 0 taken 6298 times.
✓ Branch 1 taken 1862 times.
8160 if (fgp->disable_conversions)
2144 6298 avfilter_graph_set_auto_convert(fgt->graph, AVFILTER_AUTO_CONVERT_NONE);
2145
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8160 times.
8160 if ((ret = avfilter_graph_config(fgt->graph, NULL)) < 0)
2146 goto fail;
2147
2148 8160 fgp->is_meta = graph_is_meta(fgt->graph);
2149
2150 /* limit the lists of allowed formats to the ones selected, to
2151 * make sure they stay the same if the filtergraph is reconfigured later */
2152
2/2
✓ Branch 0 taken 8295 times.
✓ Branch 1 taken 8160 times.
16455 for (int i = 0; i < fg->nb_outputs; i++) {
2153 const AVFrameSideData *const *sd;
2154 int nb_sd;
2155 8295 OutputFilter *ofilter = fg->outputs[i];
2156 8295 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
2157 8295 AVFilterContext *sink = ofilter->filter;
2158
2159 8295 ofp->format = av_buffersink_get_format(sink);
2160
2161 8295 ofp->width = av_buffersink_get_w(sink);
2162 8295 ofp->height = av_buffersink_get_h(sink);
2163 8295 ofp->color_space = av_buffersink_get_colorspace(sink);
2164 8295 ofp->color_range = av_buffersink_get_color_range(sink);
2165 8295 ofp->alpha_mode = av_buffersink_get_alpha_mode(sink);
2166
2167 // If the timing parameters are not locked yet, get the tentative values
2168 // here but don't lock them. They will only be used if no output frames
2169 // are ever produced.
2170
2/2
✓ Branch 0 taken 8249 times.
✓ Branch 1 taken 46 times.
8295 if (!ofp->tb_out_locked) {
2171 8249 AVRational fr = av_buffersink_get_frame_rate(sink);
2172
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 &&
2173
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)
2174 6841 ofp->fps.framerate = fr;
2175 8249 ofp->tb_out = av_buffersink_get_time_base(sink);
2176 }
2177 8295 ofp->sample_aspect_ratio = av_buffersink_get_sample_aspect_ratio(sink);
2178
2179 8295 ofp->sample_rate = av_buffersink_get_sample_rate(sink);
2180 8295 av_channel_layout_uninit(&ofp->ch_layout);
2181 8295 ret = av_buffersink_get_ch_layout(sink, &ofp->ch_layout);
2182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8295 times.
8295 if (ret < 0)
2183 goto fail;
2184 8295 sd = av_buffersink_get_side_data(sink, &nb_sd);
2185
2/2
✓ Branch 0 taken 240 times.
✓ Branch 1 taken 8055 times.
8295 if (nb_sd)
2186
2/2
✓ Branch 0 taken 247 times.
✓ Branch 1 taken 240 times.
487 for (int j = 0; j < nb_sd; j++) {
2187 247 ret = av_frame_side_data_clone(&ofp->side_data, &ofp->nb_side_data,
2188 247 sd[j], AV_FRAME_SIDE_DATA_FLAG_REPLACE);
2189
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 247 times.
247 if (ret < 0) {
2190 av_frame_side_data_free(&ofp->side_data, &ofp->nb_side_data);
2191 goto fail;
2192 }
2193 }
2194 }
2195
2196
2/2
✓ Branch 0 taken 7075 times.
✓ Branch 1 taken 8160 times.
15235 for (int i = 0; i < fg->nb_inputs; i++) {
2197 7075 InputFilter *ifilter = fg->inputs[i];
2198 7075 InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[i]);
2199 AVFrame *tmp;
2200
2/2
✓ Branch 1 taken 187 times.
✓ Branch 2 taken 7075 times.
7262 while (av_fifo_read(ifp->frame_queue, &tmp, 1) >= 0) {
2201
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 149 times.
187 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
2202 38 sub2video_frame(&ifp->ifilter, tmp, !fgt->graph);
2203 } else {
2204
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 99 times.
149 if (ifp->type_src == AVMEDIA_TYPE_VIDEO) {
2205
1/2
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
50 if (ifp->displaymatrix_applied)
2206 50 av_frame_remove_side_data(tmp, AV_FRAME_DATA_DISPLAYMATRIX);
2207 }
2208 149 ret = av_buffersrc_add_frame(ifilter->filter, tmp);
2209 }
2210 187 av_frame_free(&tmp);
2211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 187 times.
187 if (ret < 0)
2212 goto fail;
2213 }
2214 }
2215
2216 /* send the EOFs for the finished inputs */
2217
2/2
✓ Branch 0 taken 7075 times.
✓ Branch 1 taken 8160 times.
15235 for (int i = 0; i < fg->nb_inputs; i++) {
2218 7075 InputFilter *ifilter = fg->inputs[i];
2219
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 7058 times.
7075 if (fgt->eof_in[i]) {
2220 17 ret = av_buffersrc_add_frame(ifilter->filter, NULL);
2221
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (ret < 0)
2222 goto fail;
2223 17 have_input_eof = 1;
2224 }
2225 }
2226
2227
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 8149 times.
8160 if (have_input_eof) {
2228 // make sure the EOF propagates to the end of the graph
2229 11 ret = avfilter_graph_request_oldest(fgt->graph);
2230
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)
2231 goto fail;
2232 }
2233
2234 8160 return 0;
2235 fail:
2236 cleanup_filtergraph(fg, fgt);
2237 return ret;
2238 }
2239
2240 7069 static int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
2241 {
2242 7069 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2243 AVFrameSideData *sd;
2244 int ret;
2245
2246 7069 ret = av_buffer_replace(&ifp->hw_frames_ctx, frame->hw_frames_ctx);
2247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7069 times.
7069 if (ret < 0)
2248 return ret;
2249
2250
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 } :
2251
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) :
2252 frame->time_base;
2253
2254 7069 ifp->format = frame->format;
2255
2256 7069 ifp->width = frame->width;
2257 7069 ifp->height = frame->height;
2258 7069 ifp->sample_aspect_ratio = frame->sample_aspect_ratio;
2259 7069 ifp->color_space = frame->colorspace;
2260 7069 ifp->color_range = frame->color_range;
2261 7069 ifp->alpha_mode = frame->alpha_mode;
2262
2263 7069 ifp->sample_rate = frame->sample_rate;
2264 7069 ret = av_channel_layout_copy(&ifp->ch_layout, &frame->ch_layout);
2265
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7069 times.
7069 if (ret < 0)
2266 return ret;
2267
2268 7069 av_frame_side_data_free(&ifp->side_data, &ifp->nb_side_data);
2269
2/2
✓ Branch 0 taken 574 times.
✓ Branch 1 taken 7069 times.
7643 for (int i = 0; i < frame->nb_side_data; i++) {
2270 574 const AVSideDataDescriptor *desc = av_frame_side_data_desc(frame->side_data[i]->type);
2271
2272
2/2
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 310 times.
574 if (!(desc->props & AV_SIDE_DATA_PROP_GLOBAL) ||
2273
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 247 times.
264 frame->side_data[i]->type == AV_FRAME_DATA_DISPLAYMATRIX)
2274 327 continue;
2275
2276 247 ret = av_frame_side_data_clone(&ifp->side_data,
2277 &ifp->nb_side_data,
2278 247 frame->side_data[i], 0);
2279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 247 times.
247 if (ret < 0)
2280 return ret;
2281 }
2282
2283 7069 sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX);
2284
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 7052 times.
7069 if (sd)
2285 17 memcpy(ifp->displaymatrix, sd->data, sizeof(ifp->displaymatrix));
2286 7069 ifp->displaymatrix_present = !!sd;
2287
2288 /* Copy downmix related side data to InputFilterPriv so it may be propagated
2289 * to the filter chain even though it's not "global", as filters like aresample
2290 * require this information during init and not when remixing a frame */
2291 7069 sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DOWNMIX_INFO);
2292
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 7064 times.
7069 if (sd) {
2293 5 ret = av_frame_side_data_clone(&ifp->side_data,
2294 &ifp->nb_side_data, sd, 0);
2295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (ret < 0)
2296 return ret;
2297 5 memcpy(&ifp->downmixinfo, sd->data, sizeof(ifp->downmixinfo));
2298 }
2299 7069 ifp->downmixinfo_present = !!sd;
2300
2301 7069 return 0;
2302 }
2303
2304 1 static int ifilter_parameters_from_ofilter(InputFilter *ifilter, OutputFilter *ofilter)
2305 {
2306 1 const OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
2307 1 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2308
2309
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!ifp->opts.framerate.num) {
2310 1 ifp->opts.framerate = ofp->fps.framerate;
2311
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)
2312 1 ifp->opts.flags |= IFILTER_FLAG_CFR;
2313 }
2314
2315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 for (int i = 0; i < ofp->nb_side_data; i++) {
2316 int ret = av_frame_side_data_clone(&ifp->side_data, &ifp->nb_side_data,
2317 ofp->side_data[i], AV_FRAME_SIDE_DATA_FLAG_REPLACE);
2318 if (ret < 0)
2319 return ret;
2320 }
2321
2322 1 return 0;
2323 }
2324
2325 38576 int filtergraph_is_simple(const FilterGraph *fg)
2326 {
2327 38576 const FilterGraphPriv *fgp = cfgp_from_cfg(fg);
2328 38576 return fgp->is_simple;
2329 }
2330
2331 static void send_command(FilterGraph *fg, AVFilterGraph *graph,
2332 double time, const char *target,
2333 const char *command, const char *arg, int all_filters)
2334 {
2335 int ret;
2336
2337 if (!graph)
2338 return;
2339
2340 if (time < 0) {
2341 char response[4096];
2342 ret = avfilter_graph_send_command(graph, target, command, arg,
2343 response, sizeof(response),
2344 all_filters ? 0 : AVFILTER_CMD_FLAG_ONE);
2345 fprintf(stderr, "Command reply for stream %d: ret:%d res:\n%s",
2346 fg->index, ret, response);
2347 } else if (!all_filters) {
2348 fprintf(stderr, "Queuing commands only on filters supporting the specific command is unsupported\n");
2349 } else {
2350 ret = avfilter_graph_queue_command(graph, target, command, arg, 0, time);
2351 if (ret < 0)
2352 fprintf(stderr, "Queuing command failed with error %s\n", av_err2str(ret));
2353 }
2354 }
2355
2356 411329 static int choose_input(const FilterGraph *fg, const FilterGraphThread *fgt)
2357 {
2358 411329 int nb_requests, nb_requests_max = -1;
2359 411329 int best_input = -1;
2360
2361
2/2
✓ Branch 0 taken 426233 times.
✓ Branch 1 taken 411329 times.
837562 for (int i = 0; i < fg->nb_inputs; i++) {
2362 426233 InputFilter *ifilter = fg->inputs[i];
2363
2364
2/2
✓ Branch 0 taken 1245 times.
✓ Branch 1 taken 424988 times.
426233 if (fgt->eof_in[i])
2365 1245 continue;
2366
2367 424988 nb_requests = av_buffersrc_get_nb_failed_requests(ifilter->filter);
2368
2/2
✓ Branch 0 taken 413810 times.
✓ Branch 1 taken 11178 times.
424988 if (nb_requests > nb_requests_max) {
2369 413810 nb_requests_max = nb_requests;
2370 413810 best_input = i;
2371 }
2372 }
2373
2374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 411329 times.
411329 av_assert0(best_input >= 0);
2375
2376 411329 return best_input;
2377 }
2378
2379 8246 static int choose_out_timebase(OutputFilterPriv *ofp, AVFrame *frame)
2380 {
2381 8246 OutputFilter *ofilter = &ofp->ofilter;
2382 8246 FPSConvContext *fps = &ofp->fps;
2383 8246 AVRational tb = (AVRational){ 0, 0 };
2384 AVRational fr;
2385 const FrameData *fd;
2386
2387 8246 fd = frame_data_c(frame);
2388
2389 // apply -enc_time_base
2390
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8245 times.
8246 if (ofp->enc_timebase.num == ENC_TIME_BASE_DEMUX &&
2391
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)) {
2392 av_log(ofp, AV_LOG_ERROR,
2393 "Demuxing timebase not available - cannot use it for encoding\n");
2394 return AVERROR(EINVAL);
2395 }
2396
2397
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) {
2398 8245 case 0: break;
2399 1 case ENC_TIME_BASE_DEMUX: tb = fd->dec.tb; break;
2400 case ENC_TIME_BASE_FILTER: tb = frame->time_base; break;
2401 default: tb = ofp->enc_timebase; break;
2402 }
2403
2404
2/2
✓ Branch 0 taken 1368 times.
✓ Branch 1 taken 6878 times.
8246 if (ofilter->type == AVMEDIA_TYPE_AUDIO) {
2405
1/2
✓ Branch 0 taken 1368 times.
✗ Branch 1 not taken.
1368 tb = tb.num ? tb : (AVRational){ 1, frame->sample_rate };
2406 1368 goto finish;
2407 }
2408
2409 6878 fr = fps->framerate;
2410
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6862 times.
6878 if (!fr.num) {
2411 16 AVRational fr_sink = av_buffersink_get_frame_rate(ofilter->filter);
2412
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)
2413 fr = fr_sink;
2414 }
2415
2416
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) {
2417
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) {
2418 fr = (AVRational){25, 1};
2419 av_log(ofp, AV_LOG_WARNING,
2420 "No information "
2421 "about the input framerate is available. Falling "
2422 "back to a default value of 25fps. Use the -r option "
2423 "if you want a different framerate.\n");
2424 }
2425
2426
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 &&
2427 (av_q2d(fr) > av_q2d(fps->framerate_max) ||
2428 !fr.den))
2429 fr = fps->framerate_max;
2430 }
2431
2432
2/2
✓ Branch 0 taken 6862 times.
✓ Branch 1 taken 16 times.
6878 if (fr.num > 0) {
2433
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 6799 times.
6862 if (fps->framerate_supported) {
2434 63 int idx = av_find_nearest_q_idx(fr, fps->framerate_supported);
2435 63 fr = fps->framerate_supported[idx];
2436 }
2437
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 6799 times.
6862 if (fps->framerate_clip) {
2438 63 av_reduce(&fr.num, &fr.den,
2439 63 fr.num, fr.den, fps->framerate_clip);
2440 }
2441 }
2442
2443
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))
2444 6877 tb = av_inv_q(fr);
2445
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))
2446 16 tb = frame->time_base;
2447
2448 6878 fps->framerate = fr;
2449 8246 finish:
2450 8246 ofp->tb_out = tb;
2451 8246 ofp->tb_out_locked = 1;
2452
2453 8246 return 0;
2454 }
2455
2456 143482 static double adjust_frame_pts_to_encoder_tb(void *logctx, AVFrame *frame,
2457 AVRational tb_dst, int64_t start_time)
2458 {
2459 143482 double float_pts = AV_NOPTS_VALUE; // this is identical to frame.pts but with higher precision
2460
2461 143482 AVRational tb = tb_dst;
2462 143482 AVRational filter_tb = frame->time_base;
2463 143482 const int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16);
2464
2465
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143482 times.
143482 if (frame->pts == AV_NOPTS_VALUE)
2466 goto early_exit;
2467
2468 143482 tb.den <<= extra_bits;
2469 143482 float_pts = av_rescale_q(frame->pts, filter_tb, tb) -
2470 143482 av_rescale_q(start_time, AV_TIME_BASE_Q, tb);
2471 143482 float_pts /= 1 << extra_bits;
2472 // when float_pts is not exactly an integer,
2473 // avoid exact midpoints to reduce the chance of rounding differences, this
2474 // can be removed in case the fps code is changed to work with integers
2475
2/2
✓ Branch 0 taken 6023 times.
✓ Branch 1 taken 137459 times.
143482 if (float_pts != llrint(float_pts))
2476
1/2
✓ Branch 0 taken 6023 times.
✗ Branch 1 not taken.
6023 float_pts += FFSIGN(float_pts) * 1.0 / (1<<17);
2477
2478 143482 frame->pts = av_rescale_q(frame->pts, filter_tb, tb_dst) -
2479 143482 av_rescale_q(start_time, AV_TIME_BASE_Q, tb_dst);
2480 143482 frame->time_base = tb_dst;
2481
2482 143482 early_exit:
2483
2484
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143482 times.
143482 if (debug_ts) {
2485 av_log(logctx, AV_LOG_INFO,
2486 "filter -> pts:%s pts_time:%s exact:%f time_base:%d/%d\n",
2487 frame ? av_ts2str(frame->pts) : "NULL",
2488 av_ts2timestr(frame->pts, &tb_dst),
2489 float_pts, tb_dst.num, tb_dst.den);
2490 }
2491
2492 143482 return float_pts;
2493 }
2494
2495 3843 static int64_t median3(int64_t a, int64_t b, int64_t c)
2496 {
2497 int64_t max2, min2, m;
2498
2499
1/2
✓ Branch 0 taken 3843 times.
✗ Branch 1 not taken.
3843 if (a >= b) {
2500 3843 max2 = a;
2501 3843 min2 = b;
2502 } else {
2503 max2 = b;
2504 min2 = a;
2505 }
2506 3843 m = (c >= max2) ? max2 : c;
2507
2508 3843 return (m >= min2) ? m : min2;
2509 }
2510
2511
2512 /* Convert frame timestamps to the encoder timebase and decide how many times
2513 * should this (and possibly previous) frame be repeated in order to conform to
2514 * desired target framerate (if any).
2515 */
2516 147325 static void video_sync_process(OutputFilterPriv *ofp, AVFrame *frame,
2517 int64_t *nb_frames, int64_t *nb_frames_prev)
2518 {
2519 147325 OutputFilter *ofilter = &ofp->ofilter;
2520 147325 FPSConvContext *fps = &ofp->fps;
2521 double delta0, delta, sync_ipts, duration;
2522
2523
2/2
✓ Branch 0 taken 3843 times.
✓ Branch 1 taken 143482 times.
147325 if (!frame) {
2524 3843 *nb_frames_prev = *nb_frames = median3(fps->frames_prev_hist[0],
2525 fps->frames_prev_hist[1],
2526 fps->frames_prev_hist[2]);
2527
2528
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) {
2529 2 atomic_fetch_add(&ofilter->nb_frames_drop, 1);
2530 2 fps->last_dropped++;
2531 }
2532
2533 3843 goto finish;
2534 }
2535
2536 143482 duration = frame->duration * av_q2d(frame->time_base) / av_q2d(ofp->tb_out);
2537
2538 143482 sync_ipts = adjust_frame_pts_to_encoder_tb(ofilter->graph, frame,
2539 ofp->tb_out, ofp->ts_offset);
2540 /* delta0 is the "drift" between the input frame and
2541 * where it would fall in the output. */
2542 143482 delta0 = sync_ipts - ofp->next_pts;
2543 143482 delta = delta0 + duration;
2544
2545 // tracks the number of times the PREVIOUS frame should be duplicated,
2546 // mostly for variable framerate (VFR)
2547 143482 *nb_frames_prev = 0;
2548 /* by default, we output a single frame */
2549 143482 *nb_frames = 1;
2550
2551
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 &&
2552 3854 delta > 0 &&
2553
1/2
✓ Branch 0 taken 3854 times.
✗ Branch 1 not taken.
3854 fps->vsync_method != VSYNC_PASSTHROUGH
2554 #if FFMPEG_OPT_VSYNC_DROP
2555
1/2
✓ Branch 0 taken 3854 times.
✗ Branch 1 not taken.
3854 && fps->vsync_method != VSYNC_DROP
2556 #endif
2557 ) {
2558
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 3809 times.
3854 if (delta0 < -0.6) {
2559 45 av_log(ofp, AV_LOG_VERBOSE, "Past duration %f too large\n", -delta0);
2560 } else
2561 3809 av_log(ofp, AV_LOG_DEBUG, "Clipping frame in rate conversion by %f\n", -delta0);
2562 3854 sync_ipts = ofp->next_pts;
2563 3854 duration += delta0;
2564 3854 delta0 = 0;
2565 }
2566
2567
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) {
2568 7767 case VSYNC_VSCFR:
2569
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) {
2570 av_log(ofp, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta0));
2571 delta = duration;
2572 delta0 = 0;
2573 ofp->next_pts = llrint(sync_ipts);
2574 }
2575 case VSYNC_CFR:
2576 // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
2577
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) {
2578 *nb_frames = 0;
2579
2/2
✓ Branch 0 taken 375 times.
✓ Branch 1 taken 36406 times.
36781 } else if (delta < -1.1)
2580 375 *nb_frames = 0;
2581
2/2
✓ Branch 0 taken 677 times.
✓ Branch 1 taken 35729 times.
36406 else if (delta > 1.1) {
2582 677 *nb_frames = llrintf(delta);
2583
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 675 times.
677 if (delta0 > 1.1)
2584 2 *nb_frames_prev = llrintf(delta0 - 0.6);
2585 }
2586 36781 frame->duration = 1;
2587 36781 break;
2588 83802 case VSYNC_VFR:
2589
2/2
✓ Branch 0 taken 99 times.
✓ Branch 1 taken 83703 times.
83802 if (delta <= -0.6)
2590 99 *nb_frames = 0;
2591
2/2
✓ Branch 0 taken 66351 times.
✓ Branch 1 taken 17352 times.
83703 else if (delta > 0.6)
2592 66351 ofp->next_pts = llrint(sync_ipts);
2593 83802 frame->duration = llrint(duration);
2594 83802 break;
2595 #if FFMPEG_OPT_VSYNC_DROP
2596 22899 case VSYNC_DROP:
2597 #endif
2598 case VSYNC_PASSTHROUGH:
2599 22899 ofp->next_pts = llrint(sync_ipts);
2600 22899 frame->duration = llrint(duration);
2601 22899 break;
2602 default:
2603 av_assert0(0);
2604 }
2605
2606 147325 finish:
2607 147325 memmove(fps->frames_prev_hist + 1,
2608 147325 fps->frames_prev_hist,
2609 sizeof(fps->frames_prev_hist[0]) * (FF_ARRAY_ELEMS(fps->frames_prev_hist) - 1));
2610 147325 fps->frames_prev_hist[0] = *nb_frames_prev;
2611
2612
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) {
2613 474 atomic_fetch_add(&ofilter->nb_frames_drop, 1);
2614 474 av_log(ofp, AV_LOG_VERBOSE,
2615 "*** dropping frame %"PRId64" at ts %"PRId64"\n",
2616 474 fps->frame_number, fps->last_frame->pts);
2617 }
2618
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)) {
2619 uint64_t nb_frames_dup;
2620
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 269 times.
269 if (*nb_frames > dts_error_threshold * 30) {
2621 av_log(ofp, AV_LOG_ERROR, "%"PRId64" frame duplication too large, skipping\n", *nb_frames - 1);
2622 atomic_fetch_add(&ofilter->nb_frames_drop, 1);
2623 *nb_frames = 0;
2624 return;
2625 }
2626
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,
2627 *nb_frames - (*nb_frames_prev && fps->last_dropped) - (*nb_frames > *nb_frames_prev));
2628 269 av_log(ofp, AV_LOG_VERBOSE, "*** %"PRId64" dup!\n", *nb_frames - 1);
2629
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 269 times.
269 if (nb_frames_dup > fps->dup_warning) {
2630 av_log(ofp, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", fps->dup_warning);
2631 fps->dup_warning *= 10;
2632 }
2633 }
2634
2635
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;
2636
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);
2637 }
2638
2639 1437 static void close_input(InputFilterPriv *ifp)
2640 {
2641 1437 FilterGraphPriv *fgp = fgp_from_fg(ifp->ifilter.graph);
2642
2643
2/2
✓ Branch 0 taken 95 times.
✓ Branch 1 taken 1342 times.
1437 if (!ifp->eof) {
2644 95 sch_filter_receive_finish(fgp->sch, fgp->sch_idx, ifp->ifilter.index);
2645 95 ifp->eof = 1;
2646 }
2647 1437 }
2648
2649 5183 static int close_output(OutputFilterPriv *ofp, FilterGraphThread *fgt)
2650 {
2651 5183 FilterGraphPriv *fgp = fgp_from_fg(ofp->ofilter.graph);
2652 int ret;
2653
2654 // we are finished and no frames were ever seen at this output,
2655 // at least initialize the encoder with a dummy frame
2656
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5180 times.
5183 if (!fgt->got_frame) {
2657 3 AVFrame *frame = fgt->frame;
2658 FrameData *fd;
2659
2660 3 frame->time_base = ofp->tb_out;
2661 3 frame->format = ofp->format;
2662
2663 3 frame->width = ofp->width;
2664 3 frame->height = ofp->height;
2665 3 frame->sample_aspect_ratio = ofp->sample_aspect_ratio;
2666
2667 3 frame->sample_rate = ofp->sample_rate;
2668
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (ofp->ch_layout.nb_channels) {
2669 3 ret = av_channel_layout_copy(&frame->ch_layout, &ofp->ch_layout);
2670
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0)
2671 return ret;
2672 }
2673
2674 3 fd = frame_data(frame);
2675
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!fd)
2676 return AVERROR(ENOMEM);
2677
2678 3 av_frame_side_data_free(&fd->side_data, &fd->nb_side_data);
2679 3 ret = clone_side_data(&fd->side_data, &fd->nb_side_data,
2680 3 ofp->side_data, ofp->nb_side_data, 0);
2681
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0)
2682 return ret;
2683
2684 3 fd->frame_rate_filter = ofp->fps.framerate;
2685
2686
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 av_assert0(!frame->buf[0]);
2687
2688 3 av_log(ofp, AV_LOG_WARNING,
2689 "No filtered frames for output stream, trying to "
2690 "initialize anyway.\n");
2691
2692 3 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, frame);
2693
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0) {
2694 av_frame_unref(frame);
2695 return ret;
2696 }
2697 }
2698
2699 5183 fgt->eof_out[ofp->ofilter.index] = 1;
2700
2701 5183 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, NULL);
2702
2/2
✓ Branch 0 taken 5040 times.
✓ Branch 1 taken 143 times.
5183 return (ret == AVERROR_EOF) ? 0 : ret;
2703 }
2704
2705 445318 static int fg_output_frame(OutputFilterPriv *ofp, FilterGraphThread *fgt,
2706 AVFrame *frame)
2707 {
2708 445318 FilterGraphPriv *fgp = fgp_from_fg(ofp->ofilter.graph);
2709 445318 AVFrame *frame_prev = ofp->fps.last_frame;
2710 445318 enum AVMediaType type = ofp->ofilter.type;
2711
2712 445318 int64_t nb_frames = !!frame, nb_frames_prev = 0;
2713
2714
5/6
✓ Branch 0 taken 147325 times.
✓ Branch 1 taken 297993 times.
✓ Branch 2 taken 3843 times.
✓ Branch 3 taken 143482 times.
✓ Branch 4 taken 3843 times.
✗ Branch 5 not taken.
445318 if (type == AVMEDIA_TYPE_VIDEO && (frame || fgt->got_frame))
2715 147325 video_sync_process(ofp, frame, &nb_frames, &nb_frames_prev);
2716
2717
2/2
✓ Branch 0 taken 440093 times.
✓ Branch 1 taken 442252 times.
882345 for (int64_t i = 0; i < nb_frames; i++) {
2718 AVFrame *frame_out;
2719 int ret;
2720
2721
2/2
✓ Branch 0 taken 143440 times.
✓ Branch 1 taken 296653 times.
440093 if (type == AVMEDIA_TYPE_VIDEO) {
2722
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 AVFrame *frame_in = (i < nb_frames_prev && frame_prev->buf[0]) ?
2723
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 143371 times.
143509 frame_prev : frame;
2724
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143440 times.
143440 if (!frame_in)
2725 break;
2726
2727 143440 frame_out = fgp->frame_enc;
2728 143440 ret = av_frame_ref(frame_out, frame_in);
2729
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143440 times.
143440 if (ret < 0)
2730 return ret;
2731
2732 143440 frame_out->pts = ofp->next_pts;
2733
2734
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 143433 times.
143440 if (ofp->fps.dropped_keyframe) {
2735 7 frame_out->flags |= AV_FRAME_FLAG_KEY;
2736 7 ofp->fps.dropped_keyframe = 0;
2737 }
2738 } else {
2739
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 296653 times.
296653 frame->pts = (frame->pts == AV_NOPTS_VALUE) ? ofp->next_pts :
2740 296653 av_rescale_q(frame->pts, frame->time_base, ofp->tb_out) -
2741 296653 av_rescale_q(ofp->ts_offset, AV_TIME_BASE_Q, ofp->tb_out);
2742
2743 296653 frame->time_base = ofp->tb_out;
2744 296653 frame->duration = av_rescale_q(frame->nb_samples,
2745 296653 (AVRational){ 1, frame->sample_rate },
2746 ofp->tb_out);
2747
2748 296653 ofp->next_pts = frame->pts + frame->duration;
2749
2750 296653 frame_out = frame;
2751 }
2752
2753 // send the frame to consumers
2754 440093 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, frame_out);
2755
2/2
✓ Branch 0 taken 3066 times.
✓ Branch 1 taken 437027 times.
440093 if (ret < 0) {
2756 3066 av_frame_unref(frame_out);
2757
2758
1/2
✓ Branch 0 taken 3066 times.
✗ Branch 1 not taken.
3066 if (!fgt->eof_out[ofp->ofilter.index]) {
2759 3066 fgt->eof_out[ofp->ofilter.index] = 1;
2760 3066 fgp->nb_outputs_done++;
2761 }
2762
2763
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3066 times.
3066 return ret == AVERROR_EOF ? 0 : ret;
2764 }
2765
2766
2/2
✓ Branch 0 taken 140405 times.
✓ Branch 1 taken 296622 times.
437027 if (type == AVMEDIA_TYPE_VIDEO) {
2767 140405 ofp->fps.frame_number++;
2768 140405 ofp->next_pts++;
2769
2770
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)
2771 139973 frame->flags &= ~AV_FRAME_FLAG_KEY;
2772 }
2773
2774 437027 fgt->got_frame = 1;
2775 }
2776
2777
4/4
✓ Branch 0 taken 437069 times.
✓ Branch 1 taken 5183 times.
✓ Branch 2 taken 140446 times.
✓ Branch 3 taken 296623 times.
442252 if (frame && frame_prev) {
2778 140446 av_frame_unref(frame_prev);
2779 140446 av_frame_move_ref(frame_prev, frame);
2780 }
2781
2782
2/2
✓ Branch 0 taken 5183 times.
✓ Branch 1 taken 437069 times.
442252 if (!frame)
2783 5183 return close_output(ofp, fgt);
2784
2785 437069 return 0;
2786 }
2787
2788 930013 static int fg_output_step(OutputFilterPriv *ofp, FilterGraphThread *fgt,
2789 AVFrame *frame)
2790 {
2791 930013 FilterGraphPriv *fgp = fgp_from_fg(ofp->ofilter.graph);
2792 930013 AVFilterContext *filter = ofp->ofilter.filter;
2793 FrameData *fd;
2794 int ret;
2795
2796 930013 ret = av_buffersink_get_frame_flags(filter, frame,
2797 AV_BUFFERSINK_FLAG_NO_REQUEST);
2798
4/4
✓ Branch 0 taken 4231 times.
✓ Branch 1 taken 925782 times.
✓ Branch 2 taken 3582 times.
✓ Branch 3 taken 649 times.
930013 if (ret == AVERROR_EOF && !fgt->eof_out[ofp->ofilter.index]) {
2799 3582 ret = fg_output_frame(ofp, fgt, NULL);
2800
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3582 times.
3582 return (ret < 0) ? ret : 1;
2801
4/4
✓ Branch 0 taken 440786 times.
✓ Branch 1 taken 485645 times.
✓ Branch 2 taken 649 times.
✓ Branch 3 taken 440137 times.
926431 } else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2802 486294 return 1;
2803
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 440137 times.
440137 } else if (ret < 0) {
2804 av_log(ofp, AV_LOG_WARNING,
2805 "Error in retrieving a frame from the filtergraph: %s\n",
2806 av_err2str(ret));
2807 return ret;
2808 }
2809
2810
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 440135 times.
440137 if (fgt->eof_out[ofp->ofilter.index]) {
2811 2 av_frame_unref(frame);
2812 2 return 0;
2813 }
2814
2815 440135 frame->time_base = av_buffersink_get_time_base(filter);
2816
2817
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 440135 times.
440135 if (debug_ts)
2818 av_log(ofp, AV_LOG_INFO, "filter_raw -> pts:%s pts_time:%s time_base:%d/%d\n",
2819 av_ts2str(frame->pts), av_ts2timestr(frame->pts, &frame->time_base),
2820 frame->time_base.num, frame->time_base.den);
2821
2822 // Choose the output timebase the first time we get a frame.
2823
2/2
✓ Branch 0 taken 8246 times.
✓ Branch 1 taken 431889 times.
440135 if (!ofp->tb_out_locked) {
2824 8246 ret = choose_out_timebase(ofp, frame);
2825
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8246 times.
8246 if (ret < 0) {
2826 av_log(ofp, AV_LOG_ERROR, "Could not choose an output time base\n");
2827 av_frame_unref(frame);
2828 return ret;
2829 }
2830 }
2831
2832 440135 fd = frame_data(frame);
2833
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 440135 times.
440135 if (!fd) {
2834 av_frame_unref(frame);
2835 return AVERROR(ENOMEM);
2836 }
2837
2838 440135 av_frame_side_data_free(&fd->side_data, &fd->nb_side_data);
2839
2/2
✓ Branch 0 taken 8112 times.
✓ Branch 1 taken 432023 times.
440135 if (!fgt->got_frame) {
2840 8112 ret = clone_side_data(&fd->side_data, &fd->nb_side_data,
2841 8112 ofp->side_data, ofp->nb_side_data, 0);
2842
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8112 times.
8112 if (ret < 0)
2843 return ret;
2844 }
2845
2846 440135 fd->wallclock[LATENCY_PROBE_FILTER_POST] = av_gettime_relative();
2847
2848 // only use bits_per_raw_sample passed through from the decoder
2849 // if the filtergraph did not touch the frame data
2850
2/2
✓ Branch 0 taken 325998 times.
✓ Branch 1 taken 114137 times.
440135 if (!fgp->is_meta)
2851 325998 fd->bits_per_raw_sample = 0;
2852
2853
2/2
✓ Branch 0 taken 143482 times.
✓ Branch 1 taken 296653 times.
440135 if (ofp->ofilter.type == AVMEDIA_TYPE_VIDEO) {
2854
2/2
✓ Branch 0 taken 2420 times.
✓ Branch 1 taken 141062 times.
143482 if (!frame->duration) {
2855 2420 AVRational fr = av_buffersink_get_frame_rate(filter);
2856
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)
2857 1786 frame->duration = av_rescale_q(1, av_inv_q(fr), frame->time_base);
2858 }
2859
2860 143482 fd->frame_rate_filter = ofp->fps.framerate;
2861 }
2862
2863 440135 ret = fg_output_frame(ofp, fgt, frame);
2864 440135 av_frame_unref(frame);
2865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 440135 times.
440135 if (ret < 0)
2866 return ret;
2867
2868 440135 return 0;
2869 }
2870
2871 /* retrieve all frames available at filtergraph outputs
2872 * and send them to consumers */
2873 449238 static int read_frames(FilterGraph *fg, FilterGraphThread *fgt,
2874 AVFrame *frame)
2875 {
2876 449238 FilterGraphPriv *fgp = fgp_from_fg(fg);
2877 449238 int did_step = 0;
2878
2879 // graph not configured, just select the input to request
2880
2/2
✓ Branch 0 taken 201 times.
✓ Branch 1 taken 449037 times.
449238 if (!fgt->graph) {
2881
1/2
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
536 for (int i = 0; i < fg->nb_inputs; i++) {
2882 536 InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[i]);
2883
3/4
✓ Branch 0 taken 201 times.
✓ Branch 1 taken 335 times.
✓ Branch 2 taken 201 times.
✗ Branch 3 not taken.
536 if (ifp->format < 0 && !fgt->eof_in[i]) {
2884 201 fgt->next_in = i;
2885 201 return 0;
2886 }
2887 }
2888
2889 // This state - graph is not configured, but all inputs are either
2890 // initialized or EOF - should be unreachable because sending EOF to a
2891 // filter without even a fallback format should fail
2892 av_assert0(0);
2893 return AVERROR_BUG;
2894 }
2895
2896
2/2
✓ Branch 0 taken 477554 times.
✓ Branch 1 taken 3065 times.
480619 while (fgp->nb_outputs_done < fg->nb_outputs) {
2897 int ret;
2898
2899 /* Reap all buffers present in the buffer sinks */
2900
2/2
✓ Branch 0 taken 489876 times.
✓ Branch 1 taken 477554 times.
967430 for (int i = 0; i < fg->nb_outputs; i++) {
2901 489876 OutputFilterPriv *ofp = ofp_from_ofilter(fg->outputs[i]);
2902
2903 489876 ret = 0;
2904
2/2
✓ Branch 0 taken 930013 times.
✓ Branch 1 taken 489876 times.
1419889 while (!ret) {
2905 930013 ret = fg_output_step(ofp, fgt, frame);
2906
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 930013 times.
930013 if (ret < 0)
2907 return ret;
2908 }
2909 }
2910
2911 // return after one iteration, so that scheduler can rate-control us
2912
4/4
✓ Branch 0 taken 31580 times.
✓ Branch 1 taken 445974 times.
✓ Branch 2 taken 29602 times.
✓ Branch 3 taken 1978 times.
477554 if (did_step && fgp->have_sources)
2913 29602 return 0;
2914
2915 447952 ret = avfilter_graph_request_oldest(fgt->graph);
2916
2/2
✓ Branch 0 taken 411329 times.
✓ Branch 1 taken 36623 times.
447952 if (ret == AVERROR(EAGAIN)) {
2917 411329 fgt->next_in = choose_input(fg, fgt);
2918 411329 return 0;
2919
2/2
✓ Branch 0 taken 5041 times.
✓ Branch 1 taken 31582 times.
36623 } else if (ret < 0) {
2920
1/2
✓ Branch 0 taken 5041 times.
✗ Branch 1 not taken.
5041 if (ret == AVERROR_EOF)
2921 5041 av_log(fg, AV_LOG_VERBOSE, "Filtergraph returned EOF, finishing\n");
2922 else
2923 av_log(fg, AV_LOG_ERROR,
2924 "Error requesting a frame from the filtergraph: %s\n",
2925 av_err2str(ret));
2926 5041 return ret;
2927 }
2928 31582 fgt->next_in = fg->nb_inputs;
2929
2930 31582 did_step = 1;
2931 }
2932
2933 3065 return AVERROR_EOF;
2934 }
2935
2936 948 static void sub2video_heartbeat(InputFilter *ifilter, int64_t pts, AVRational tb)
2937 {
2938 948 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2939 int64_t pts2;
2940
2941 /* subtitles seem to be usually muxed ahead of other streams;
2942 if not, subtracting a larger time here is necessary */
2943 948 pts2 = av_rescale_q(pts, tb, ifp->time_base) - 1;
2944
2945 /* do not send the heartbeat frame if the subtitle is already ahead */
2946
2/2
✓ Branch 0 taken 769 times.
✓ Branch 1 taken 179 times.
948 if (pts2 <= ifp->sub2video.last_pts)
2947 769 return;
2948
2949
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)
2950 /* if we have hit the end of the current displayed subpicture,
2951 or if we need to initialize the system, update the
2952 overlaid subpicture and its start/end times */
2953 88 sub2video_update(ifp, pts2 + 1, NULL);
2954 else
2955 91 sub2video_push_ref(ifp, pts2);
2956 }
2957
2958 1078 static int sub2video_frame(InputFilter *ifilter, AVFrame *frame, int buffer)
2959 {
2960 1078 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2961 int ret;
2962
2963
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 1040 times.
1078 if (buffer) {
2964 AVFrame *tmp;
2965
2966
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (!frame)
2967 return 0;
2968
2969 38 tmp = av_frame_alloc();
2970
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (!tmp)
2971 return AVERROR(ENOMEM);
2972
2973 38 av_frame_move_ref(tmp, frame);
2974
2975 38 ret = av_fifo_write(ifp->frame_queue, &tmp, 1);
2976
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (ret < 0) {
2977 av_frame_free(&tmp);
2978 return ret;
2979 }
2980
2981 38 return 0;
2982 }
2983
2984 // heartbeat frame
2985
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]) {
2986 948 sub2video_heartbeat(ifilter, frame->pts, frame->time_base);
2987 948 return 0;
2988 }
2989
2990
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 88 times.
92 if (!frame) {
2991
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (ifp->sub2video.end_pts < INT64_MAX)
2992 4 sub2video_update(ifp, INT64_MAX, NULL);
2993
2994 4 return av_buffersrc_add_frame(ifilter->filter, NULL);
2995 }
2996
2997
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 ifp->width = frame->width ? frame->width : ifp->width;
2998
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 ifp->height = frame->height ? frame->height : ifp->height;
2999
3000 88 sub2video_update(ifp, INT64_MIN, (const AVSubtitle*)frame->buf[0]->data);
3001
3002 88 return 0;
3003 }
3004
3005 3377 static int send_eof(FilterGraphThread *fgt, InputFilter *ifilter,
3006 int64_t pts, AVRational tb)
3007 {
3008 3377 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
3009 int ret;
3010
3011
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3377 times.
3377 if (fgt->eof_in[ifilter->index])
3012 return 0;
3013
3014 3377 fgt->eof_in[ifilter->index] = 1;
3015
3016
2/2
✓ Branch 0 taken 3360 times.
✓ Branch 1 taken 17 times.
3377 if (ifilter->filter) {
3017 3360 pts = av_rescale_q_rnd(pts, tb, ifp->time_base,
3018 AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
3019
3020 3360 ret = av_buffersrc_close(ifilter->filter, pts, AV_BUFFERSRC_FLAG_PUSH);
3021
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3360 times.
3360 if (ret < 0)
3022 return ret;
3023 } else {
3024
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 14 times.
17 if (ifp->format < 0) {
3025 // the filtergraph was never configured, use the fallback parameters
3026 3 ifp->format = ifp->opts.fallback->format;
3027 3 ifp->sample_rate = ifp->opts.fallback->sample_rate;
3028 3 ifp->width = ifp->opts.fallback->width;
3029 3 ifp->height = ifp->opts.fallback->height;
3030 3 ifp->sample_aspect_ratio = ifp->opts.fallback->sample_aspect_ratio;
3031 3 ifp->color_space = ifp->opts.fallback->colorspace;
3032 3 ifp->color_range = ifp->opts.fallback->color_range;
3033 3 ifp->alpha_mode = ifp->opts.fallback->alpha_mode;
3034 3 ifp->time_base = ifp->opts.fallback->time_base;
3035
3036 3 ret = av_channel_layout_copy(&ifp->ch_layout,
3037 3 &ifp->opts.fallback->ch_layout);
3038
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0)
3039 return ret;
3040
3041 3 av_frame_side_data_free(&ifp->side_data, &ifp->nb_side_data);
3042 3 ret = clone_side_data(&ifp->side_data, &ifp->nb_side_data,
3043 3 ifp->opts.fallback->side_data,
3044 3 ifp->opts.fallback->nb_side_data, 0);
3045
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0)
3046 return ret;
3047
3048
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if (ifilter_has_all_input_formats(ifilter->graph)) {
3049 3 ret = configure_filtergraph(ifilter->graph, fgt);
3050
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0) {
3051 av_log(ifilter->graph, AV_LOG_ERROR, "Error initializing filters!\n");
3052 return ret;
3053 }
3054 }
3055 }
3056
3057
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (ifp->format < 0) {
3058 av_log(ifilter->graph, AV_LOG_ERROR,
3059 "Cannot determine format of input %s after EOF\n",
3060 ifp->opts.name);
3061 return AVERROR_INVALIDDATA;
3062 }
3063 }
3064
3065 3377 return 0;
3066 }
3067
3068 enum ReinitReason {
3069 VIDEO_CHANGED = (1 << 0),
3070 AUDIO_CHANGED = (1 << 1),
3071 MATRIX_CHANGED = (1 << 2),
3072 DOWNMIX_CHANGED = (1 << 3),
3073 HWACCEL_CHANGED = (1 << 4)
3074 };
3075
3076 181 static const char *unknown_if_null(const char *str)
3077 {
3078
1/2
✓ Branch 0 taken 181 times.
✗ Branch 1 not taken.
181 return str ? str : "unknown";
3079 }
3080
3081 413986 static int send_frame(FilterGraph *fg, FilterGraphThread *fgt,
3082 InputFilter *ifilter, AVFrame *frame)
3083 {
3084 413986 FilterGraphPriv *fgp = fgp_from_fg(fg);
3085 413986 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
3086 FrameData *fd;
3087 AVFrameSideData *sd;
3088 413986 int need_reinit = 0, ret;
3089
3090 /* determine if the parameters for this input changed */
3091
2/3
✓ Branch 0 taken 296292 times.
✓ Branch 1 taken 117694 times.
✗ Branch 2 not taken.
413986 switch (ifilter->type) {
3092 296292 case AVMEDIA_TYPE_AUDIO:
3093
2/2
✓ Branch 0 taken 294987 times.
✓ Branch 1 taken 1305 times.
296292 if (ifp->format != frame->format ||
3094
3/4
✓ Branch 0 taken 294987 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 294986 times.
589974 ifp->sample_rate != frame->sample_rate ||
3095 294987 av_channel_layout_compare(&ifp->ch_layout, &frame->ch_layout))
3096 1306 need_reinit |= AUDIO_CHANGED;
3097 296292 break;
3098 117694 case AVMEDIA_TYPE_VIDEO:
3099
2/2
✓ Branch 0 taken 111965 times.
✓ Branch 1 taken 5729 times.
117694 if (ifp->format != frame->format ||
3100
2/2
✓ Branch 0 taken 111937 times.
✓ Branch 1 taken 28 times.
111965 ifp->width != frame->width ||
3101
2/2
✓ Branch 0 taken 111931 times.
✓ Branch 1 taken 6 times.
111937 ifp->height != frame->height ||
3102
1/2
✓ Branch 0 taken 111931 times.
✗ Branch 1 not taken.
111931 ifp->color_space != frame->colorspace ||
3103
1/2
✓ Branch 0 taken 111931 times.
✗ Branch 1 not taken.
111931 ifp->color_range != frame->color_range ||
3104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 111931 times.
111931 ifp->alpha_mode != frame->alpha_mode)
3105 5763 need_reinit |= VIDEO_CHANGED;
3106 117694 break;
3107 }
3108
3109
2/2
✓ Branch 1 taken 121 times.
✓ Branch 2 taken 413865 times.
413986 if (sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX)) {
3110
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 17 times.
121 if (!ifp->displaymatrix_present ||
3111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 104 times.
104 memcmp(sd->data, ifp->displaymatrix, sizeof(ifp->displaymatrix)))
3112 17 need_reinit |= MATRIX_CHANGED;
3113
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 413865 times.
413865 } else if (ifp->displaymatrix_present)
3114 need_reinit |= MATRIX_CHANGED;
3115
3116
2/2
✓ Branch 1 taken 419 times.
✓ Branch 2 taken 413567 times.
413986 if (sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DOWNMIX_INFO)) {
3117
2/2
✓ Branch 0 taken 414 times.
✓ Branch 1 taken 5 times.
419 if (!ifp->downmixinfo_present ||
3118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 414 times.
414 memcmp(sd->data, &ifp->downmixinfo, sizeof(ifp->downmixinfo)))
3119 5 need_reinit |= DOWNMIX_CHANGED;
3120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 413567 times.
413567 } else if (ifp->downmixinfo_present)
3121 need_reinit |= DOWNMIX_CHANGED;
3122
3123
5/6
✓ Branch 0 taken 7069 times.
✓ Branch 1 taken 406917 times.
✓ Branch 2 taken 47 times.
✓ Branch 3 taken 7022 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 47 times.
413986 if (need_reinit && fgt->graph && (ifp->opts.flags & IFILTER_FLAG_DROPCHANGED)) {
3124 ifp->nb_dropped++;
3125 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);
3126 av_frame_unref(frame);
3127 return 0;
3128 }
3129
3130
4/4
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 413935 times.
✓ Branch 2 taken 49 times.
✓ Branch 3 taken 2 times.
413986 if (!(ifp->opts.flags & IFILTER_FLAG_REINIT) && fgt->graph)
3131 49 need_reinit = 0;
3132
3133
1/2
✓ Branch 0 taken 413986 times.
✗ Branch 1 not taken.
413986 if (!!ifp->hw_frames_ctx != !!frame->hw_frames_ctx ||
3134
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 413986 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
413986 (ifp->hw_frames_ctx && ifp->hw_frames_ctx->data != frame->hw_frames_ctx->data))
3135 need_reinit |= HWACCEL_CHANGED;
3136
3137
2/2
✓ Branch 0 taken 7069 times.
✓ Branch 1 taken 406917 times.
413986 if (need_reinit) {
3138 7069 ret = ifilter_parameters_from_frame(ifilter, frame);
3139
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7069 times.
7069 if (ret < 0)
3140 return ret;
3141
3142 /* Inputs bound to a filtergraph output will have some fields unset.
3143 * Handle them here */
3144
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7068 times.
7069 if (ifp->ofilter_src) {
3145 1 ret = ifilter_parameters_from_ofilter(ifilter, ifp->ofilter_src);
3146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
3147 return ret;
3148 }
3149 }
3150
3151 /* (re)init the graph if possible, otherwise buffer the frame and return */
3152
4/4
✓ Branch 0 taken 406917 times.
✓ Branch 1 taken 7069 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 406869 times.
413986 if (need_reinit || !fgt->graph) {
3153 7117 AVFrame *tmp = av_frame_alloc();
3154
3155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7117 times.
7117 if (!tmp)
3156 150 return AVERROR(ENOMEM);
3157
3158
2/2
✓ Branch 1 taken 149 times.
✓ Branch 2 taken 6968 times.
7117 if (!ifilter_has_all_input_formats(fg)) {
3159 149 av_frame_move_ref(tmp, frame);
3160
3161 149 ret = av_fifo_write(ifp->frame_queue, &tmp, 1);
3162
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 149 times.
149 if (ret < 0)
3163 av_frame_free(&tmp);
3164
3165 149 return ret;
3166 }
3167
3168
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 6921 times.
6968 ret = fgt->graph ? read_frames(fg, fgt, tmp) : 0;
3169 6968 av_frame_free(&tmp);
3170
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6967 times.
6968 if (ret < 0)
3171 1 return ret;
3172
3173
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 6921 times.
6967 if (fgt->graph) {
3174 AVBPrint reason;
3175 46 av_bprint_init(&reason, 0, AV_BPRINT_SIZE_AUTOMATIC);
3176
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 45 times.
46 if (need_reinit & AUDIO_CHANGED) {
3177 1 const char *sample_format_name = av_get_sample_fmt_name(frame->format);
3178 1 av_bprintf(&reason, "audio parameters changed to %d Hz, ", frame->sample_rate);
3179 1 av_channel_layout_describe_bprint(&frame->ch_layout, &reason);
3180 1 av_bprintf(&reason, ", %s, ", unknown_if_null(sample_format_name));
3181 }
3182
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 1 times.
46 if (need_reinit & VIDEO_CHANGED) {
3183 45 const char *pixel_format_name = av_get_pix_fmt_name(frame->format);
3184 45 const char *color_space_name = av_color_space_name(frame->colorspace);
3185 45 const char *color_range_name = av_color_range_name(frame->color_range);
3186 45 const char *alpha_mode = av_alpha_mode_name(frame->alpha_mode);
3187 45 av_bprintf(&reason, "video parameters changed to %s(%s, %s), %dx%d, %s alpha, ",
3188 unknown_if_null(pixel_format_name), unknown_if_null(color_range_name),
3189 unknown_if_null(color_space_name), frame->width, frame->height,
3190 unknown_if_null(alpha_mode));
3191 }
3192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (need_reinit & MATRIX_CHANGED)
3193 av_bprintf(&reason, "display matrix changed, ");
3194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (need_reinit & DOWNMIX_CHANGED)
3195 av_bprintf(&reason, "downmix medatata changed, ");
3196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (need_reinit & HWACCEL_CHANGED)
3197 av_bprintf(&reason, "hwaccel changed, ");
3198
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 if (reason.len > 1)
3199 46 reason.str[reason.len - 2] = '\0'; // remove last comma
3200
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);
3201 } else {
3202 /* Choke all input to avoid buffering excessive frames while the
3203 * initial filter graph is being configured, and before we have a
3204 * preferred input */
3205 6921 sch_filter_choke_inputs(fgp->sch, fgp->sch_idx);
3206 }
3207
3208 6967 ret = configure_filtergraph(fg, fgt);
3209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6967 times.
6967 if (ret < 0) {
3210 av_log(fg, AV_LOG_ERROR, "Error reinitializing filters!\n");
3211 return ret;
3212 }
3213 }
3214
3215 413836 frame->pts = av_rescale_q(frame->pts, frame->time_base, ifp->time_base);
3216 413836 frame->duration = av_rescale_q(frame->duration, frame->time_base, ifp->time_base);
3217 413836 frame->time_base = ifp->time_base;
3218
3219
2/2
✓ Branch 0 taken 117589 times.
✓ Branch 1 taken 296247 times.
413836 if (ifp->displaymatrix_applied)
3220 117589 av_frame_remove_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX);
3221
3222 413836 fd = frame_data(frame);
3223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 413836 times.
413836 if (!fd)
3224 return AVERROR(ENOMEM);
3225 413836 fd->wallclock[LATENCY_PROBE_FILTER_PRE] = av_gettime_relative();
3226
3227 413836 ret = av_buffersrc_add_frame_flags(ifilter->filter, frame,
3228 AV_BUFFERSRC_FLAG_PUSH);
3229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 413836 times.
413836 if (ret < 0) {
3230 av_frame_unref(frame);
3231 if (ret != AVERROR_EOF)
3232 av_log(fg, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret));
3233 return ret;
3234 }
3235
3236 413836 return 0;
3237 }
3238
3239 8114 static void fg_thread_set_name(const FilterGraph *fg)
3240 {
3241 char name[16];
3242
2/2
✓ Branch 1 taken 6854 times.
✓ Branch 2 taken 1260 times.
8114 if (filtergraph_is_simple(fg)) {
3243 6854 OutputFilterPriv *ofp = ofp_from_ofilter(fg->outputs[0]);
3244 13708 snprintf(name, sizeof(name), "%cf%s",
3245 6854 av_get_media_type_string(ofp->ofilter.type)[0],
3246 ofp->ofilter.output_name);
3247 } else {
3248 1260 snprintf(name, sizeof(name), "fc%d", fg->index);
3249 }
3250
3251 8114 ff_thread_setname(name);
3252 8114 }
3253
3254 8114 static void fg_thread_uninit(FilterGraphThread *fgt)
3255 {
3256
1/2
✓ Branch 0 taken 8114 times.
✗ Branch 1 not taken.
8114 if (fgt->frame_queue_out) {
3257 AVFrame *frame;
3258
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8114 times.
8114 while (av_fifo_read(fgt->frame_queue_out, &frame, 1) >= 0)
3259 av_frame_free(&frame);
3260 8114 av_fifo_freep2(&fgt->frame_queue_out);
3261 }
3262
3263 8114 av_frame_free(&fgt->frame);
3264 8114 av_freep(&fgt->eof_in);
3265 8114 av_freep(&fgt->eof_out);
3266
3267 8114 avfilter_graph_free(&fgt->graph);
3268
3269 8114 memset(fgt, 0, sizeof(*fgt));
3270 8114 }
3271
3272 8114 static int fg_thread_init(FilterGraphThread *fgt, const FilterGraph *fg)
3273 {
3274 8114 memset(fgt, 0, sizeof(*fgt));
3275
3276 8114 fgt->frame = av_frame_alloc();
3277
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8114 times.
8114 if (!fgt->frame)
3278 goto fail;
3279
3280 8114 fgt->eof_in = av_calloc(fg->nb_inputs, sizeof(*fgt->eof_in));
3281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8114 times.
8114 if (!fgt->eof_in)
3282 goto fail;
3283
3284 8114 fgt->eof_out = av_calloc(fg->nb_outputs, sizeof(*fgt->eof_out));
3285
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8114 times.
8114 if (!fgt->eof_out)
3286 goto fail;
3287
3288 8114 fgt->frame_queue_out = av_fifo_alloc2(1, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
3289
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8114 times.
8114 if (!fgt->frame_queue_out)
3290 goto fail;
3291
3292 8114 return 0;
3293
3294 fail:
3295 fg_thread_uninit(fgt);
3296 return AVERROR(ENOMEM);
3297 }
3298
3299 8114 static int filter_thread(void *arg)
3300 {
3301 8114 FilterGraphPriv *fgp = arg;
3302 8114 FilterGraph *fg = &fgp->fg;
3303
3304 FilterGraphThread fgt;
3305 8114 int ret = 0, input_status = 0;
3306
3307 8114 ret = fg_thread_init(&fgt, fg);
3308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8114 times.
8114 if (ret < 0)
3309 goto finish;
3310
3311 8114 fg_thread_set_name(fg);
3312
3313 // if we have all input parameters the graph can now be configured
3314
2/2
✓ Branch 1 taken 6924 times.
✓ Branch 2 taken 1190 times.
8114 if (ifilter_has_all_input_formats(fg)) {
3315 1190 ret = configure_filtergraph(fg, &fgt);
3316
1/2
✓ Branch 0 taken 1190 times.
✗ Branch 1 not taken.
1190 if (ret < 0) {
3317 av_log(fg, AV_LOG_ERROR, "Error configuring filter graph: %s\n",
3318 av_err2str(ret));
3319 goto finish;
3320 }
3321 }
3322
3323 441087 while (1) {
3324 InputFilter *ifilter;
3325 449201 InputFilterPriv *ifp = NULL;
3326 enum FrameOpaque o;
3327 449201 unsigned input_idx = fgt.next_in;
3328
3329 449201 input_status = sch_filter_receive(fgp->sch, fgp->sch_idx,
3330 449201 &input_idx, fgt.frame);
3331
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 449192 times.
449201 if (input_status == AVERROR_EOF) {
3332 9 av_log(fg, AV_LOG_VERBOSE, "Filtering thread received EOF\n");
3333 9 break;
3334
2/2
✓ Branch 0 taken 30789 times.
✓ Branch 1 taken 418403 times.
449192 } else if (input_status == AVERROR(EAGAIN)) {
3335 // should only happen when we didn't request any input
3336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30789 times.
30789 av_assert0(input_idx == fg->nb_inputs);
3337 30789 goto read_frames;
3338 }
3339
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 418403 times.
418403 av_assert0(input_status >= 0);
3340
3341 418403 o = (intptr_t)fgt.frame->opaque;
3342
3343 // message on the control stream
3344
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 418403 times.
418403 if (input_idx == fg->nb_inputs) {
3345 FilterCommand *fc;
3346
3347 av_assert0(o == FRAME_OPAQUE_SEND_COMMAND && fgt.frame->buf[0]);
3348
3349 fc = (FilterCommand*)fgt.frame->buf[0]->data;
3350 send_command(fg, fgt.graph, fc->time, fc->target, fc->command, fc->arg,
3351 fc->all_filters);
3352 av_frame_unref(fgt.frame);
3353 1 continue;
3354 }
3355
3356 // we received an input frame or EOF
3357 418403 ifilter = fg->inputs[input_idx];
3358 418403 ifp = ifp_from_ifilter(ifilter);
3359
3360
2/2
✓ Branch 0 taken 1040 times.
✓ Branch 1 taken 417363 times.
418403 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
3361
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;
3362
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,
3363
2/2
✓ Branch 0 taken 952 times.
✓ Branch 1 taken 88 times.
1040 !fgt.graph);
3364
2/2
✓ Branch 0 taken 413986 times.
✓ Branch 1 taken 3377 times.
417363 } else if (fgt.frame->buf[0]) {
3365 413986 ret = send_frame(fg, &fgt, ifilter, fgt.frame);
3366 } else {
3367 av_assert1(o == FRAME_OPAQUE_EOF);
3368 3377 ret = send_eof(&fgt, ifilter, fgt.frame->pts, fgt.frame->time_base);
3369 }
3370 418403 av_frame_unref(fgt.frame);
3371
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 418402 times.
418403 if (ret == AVERROR_EOF) {
3372 1 av_log(fg, AV_LOG_VERBOSE, "Input %u no longer accepts new data\n",
3373 input_idx);
3374 1 close_input(ifp);
3375 1 continue;
3376 }
3377
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 418402 times.
418402 if (ret < 0)
3378 goto finish;
3379
3380 418402 read_frames:
3381 // retrieve all newly available frames
3382 449191 ret = read_frames(fg, &fgt, fgt.frame);
3383
2/2
✓ Branch 0 taken 8105 times.
✓ Branch 1 taken 441086 times.
449191 if (ret == AVERROR_EOF) {
3384 8105 av_log(fg, AV_LOG_VERBOSE, "All consumers returned EOF\n");
3385
3/4
✓ Branch 0 taken 6918 times.
✓ Branch 1 taken 1187 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6918 times.
8105 if (ifp && ifp->opts.flags & IFILTER_FLAG_DROPCHANGED)
3386 av_log(fg, AV_LOG_INFO, "Total changed input frames dropped : %"PRId64"\n", ifp->nb_dropped);
3387 8105 break;
3388
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 441086 times.
441086 } else if (ret < 0) {
3389 av_log(fg, AV_LOG_ERROR, "Error sending frames to consumers: %s\n",
3390 av_err2str(ret));
3391 goto finish;
3392 }
3393
3394 // ensure all inputs no longer accepting data are closed
3395
4/4
✓ Branch 0 taken 867072 times.
✓ Branch 1 taken 201 times.
✓ Branch 2 taken 426187 times.
✓ Branch 3 taken 440885 times.
867273 for (int i = 0; fgt.graph && i < fg->nb_inputs; i++) {
3396 426187 InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[i]);
3397
2/2
✓ Branch 1 taken 1436 times.
✓ Branch 2 taken 424751 times.
426187 if (av_buffersrc_get_status(ifp->ifilter.filter))
3398 1436 close_input(ifp);
3399 }
3400 }
3401
3402
2/2
✓ Branch 0 taken 8249 times.
✓ Branch 1 taken 8114 times.
16363 for (unsigned i = 0; i < fg->nb_outputs; i++) {
3403 8249 OutputFilterPriv *ofp = ofp_from_ofilter(fg->outputs[i]);
3404
3405
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)
3406 6648 continue;
3407
3408 1601 ret = fg_output_frame(ofp, &fgt, NULL);
3409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1601 times.
1601 if (ret < 0)
3410 goto finish;
3411 }
3412
3413 8114 finish:
3414
3415
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)
3416 print_filtergraph(fg, fgt.graph);
3417
3418 // EOF is normal termination
3419
2/2
✓ Branch 0 taken 6578 times.
✓ Branch 1 taken 1536 times.
8114 if (ret == AVERROR_EOF)
3420 6578 ret = 0;
3421
3422 8114 fg_thread_uninit(&fgt);
3423
3424 8114 return ret;
3425 }
3426
3427 void fg_send_command(FilterGraph *fg, double time, const char *target,
3428 const char *command, const char *arg, int all_filters)
3429 {
3430 FilterGraphPriv *fgp = fgp_from_fg(fg);
3431 AVBufferRef *buf;
3432 FilterCommand *fc;
3433
3434 fc = av_mallocz(sizeof(*fc));
3435 if (!fc)
3436 return;
3437
3438 buf = av_buffer_create((uint8_t*)fc, sizeof(*fc), filter_command_free, NULL, 0);
3439 if (!buf) {
3440 av_freep(&fc);
3441 return;
3442 }
3443
3444 fc->target = av_strdup(target);
3445 fc->command = av_strdup(command);
3446 fc->arg = av_strdup(arg);
3447 if (!fc->target || !fc->command || !fc->arg) {
3448 av_buffer_unref(&buf);
3449 return;
3450 }
3451
3452 fc->time = time;
3453 fc->all_filters = all_filters;
3454
3455 fgp->frame->buf[0] = buf;
3456 fgp->frame->opaque = (void*)(intptr_t)FRAME_OPAQUE_SEND_COMMAND;
3457
3458 sch_filter_command(fgp->sch, fgp->sch_idx, fgp->frame);
3459 }
3460