FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_filter.c
Date: 2025-06-23 20:06:14
Exec Total Coverage
Lines: 1289 1721 74.9%
Functions: 65 71 91.5%
Branches: 754 1157 65.2%

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