FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_filter.c
Date: 2024-10-17 22:24:08
Exec Total Coverage
Lines: 1234 1649 74.8%
Functions: 65 71 91.5%
Branches: 717 1105 64.9%

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