FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_filter.c
Date: 2025-03-08 20:38:41
Exec Total Coverage
Lines: 1282 1706 75.1%
Functions: 65 71 91.5%
Branches: 743 1141 65.1%

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