FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_filter.c
Date: 2026-01-23 19:11:46
Exec Total Coverage
Lines: 1421 1861 76.4%
Functions: 71 75 94.7%
Branches: 839 1271 66.0%

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