FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_filter.c
Date: 2025-04-25 22:50:00
Exec Total Coverage
Lines: 1285 1714 75.0%
Functions: 65 71 91.5%
Branches: 751 1151 65.2%

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