FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_filter.c
Date: 2026-10-19 01:23:10
Exec Total Coverage
Lines: 1468 1971 74.5%
Functions: 73 78 93.6%
Branches: 876 1353 64.7%

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