FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_filter.c
Date: 2025-07-12 02:25:37
Exec Total Coverage
Lines: 1290 1721 75.0%
Functions: 65 71 91.5%
Branches: 755 1157 65.3%

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 1672375 static FilterGraphPriv *fgp_from_fg(FilterGraph *fg)
74 {
75 1672375 return (FilterGraphPriv*)fg;
76 }
77
78 37956 static const FilterGraphPriv *cfgp_from_cfg(const FilterGraph *fg)
79 {
80 37956 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 793691 static InputFilterPriv *ifp_from_ifilter(InputFilter *ifilter)
160 {
161 793691 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 493198 static OutputFilterPriv *ofp_from_ofilter(OutputFilter *ofilter)
235 {
236 493198 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 1476 times.
✓ Branch 1 taken 5344 times.
✓ Branch 2 taken 1135 times.
✓ Branch 3 taken 341 times.
✓ Branch 5 taken 5344 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.
9079 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 1333 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1333 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1333 times.
✓ Branch 11 taken 1435 times.
✓ Branch 12 taken 1333 times.
✓ Branch 13 taken 1333 times.
✗ Branch 14 not taken.
2769 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 1319 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 1266 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.
1645 DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
396 "%d", )
397
398
4/10
✓ Branch 0 taken 6800 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 6800 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.
6820 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 5183 times.
✓ Branch 1 taken 1637 times.
✓ Branch 2 taken 4686 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.
7354 DEF_CHOOSE_FORMAT(color_ranges, enum AVColorRange, color_range, color_ranges,
402 AVCOL_RANGE_UNSPECIFIED, "%s", av_color_range_name);
403
404 1334 static void choose_channel_layouts(OutputFilterPriv *ofp, AVBPrint *bprint)
405 {
406
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 1322 times.
1334 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 1243 times.
1322 } 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 1243 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 32197 static int filter_opt_apply(void *logctx, AVFilterContext *f,
474 const char *key, const char *val)
475 {
476 32197 const AVOption *o = NULL;
477 int ret;
478
479 32197 ret = av_opt_set(f, key, val, AV_OPT_SEARCH_CHILDREN);
480
1/2
✓ Branch 0 taken 32197 times.
✗ Branch 1 not taken.
32197 if (ret >= 0)
481 32197 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 16002 static int graph_opts_apply(void *logctx, AVFilterGraphSegment *seg)
530 {
531
2/2
✓ Branch 0 taken 16412 times.
✓ Branch 1 taken 16002 times.
32414 for (size_t i = 0; i < seg->nb_chains; i++) {
532 16412 AVFilterChain *ch = seg->chains[i];
533
534
2/2
✓ Branch 0 taken 36501 times.
✓ Branch 1 taken 16412 times.
52913 for (size_t j = 0; j < ch->nb_filters; j++) {
535 36501 AVFilterParams *p = ch->filters[j];
536 36501 const AVDictionaryEntry *e = NULL;
537
538
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36501 times.
36501 av_assert0(p->filter);
539
540
2/2
✓ Branch 1 taken 32197 times.
✓ Branch 2 taken 36501 times.
68698 while ((e = av_dict_iterate(p->opts, e))) {
541 32197 int ret = filter_opt_apply(logctx, p->filter, e->key, e->value);
542
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32197 times.
32197 if (ret < 0)
543 return ret;
544 }
545
546 36501 av_dict_free(&p->opts);
547 }
548 }
549
550 16002 return 0;
551 }
552
553 16002 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 16002 *inputs = NULL;
562 16002 *outputs = NULL;
563
564 16002 ret = avfilter_graph_segment_parse(graph, desc, 0, &seg);
565
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16002 times.
16002 if (ret < 0)
566 return ret;
567
568 16002 ret = avfilter_graph_segment_create_filters(seg, 0);
569
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16002 times.
16002 if (ret < 0)
570 goto fail;
571
572
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16002 times.
16002 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 16002 ret = graph_opts_apply(logctx, seg);
587
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16002 times.
16002 if (ret < 0)
588 goto fail;
589
590 16002 ret = avfilter_graph_segment_apply(seg, 0, inputs, outputs);
591
592 16002 fail:
593 16002 avfilter_graph_segment_free(&seg);
594 16002 return ret;
595 }
596
597 // Filters can be configured only if the formats of all inputs are known.
598 15088 static int ifilter_has_all_input_formats(FilterGraph *fg)
599 {
600
2/2
✓ Branch 0 taken 14403 times.
✓ Branch 1 taken 8025 times.
22428 for (int i = 0; i < fg->nb_inputs; i++) {
601 14403 InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[i]);
602
2/2
✓ Branch 0 taken 7063 times.
✓ Branch 1 taken 7340 times.
14403 if (ifp->format < 0)
603 7063 return 0;
604 }
605 8025 return 1;
606 }
607
608 static int filter_thread(void *arg);
609
610 15032 static char *describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in)
611 {
612 15032 AVFilterContext *ctx = inout->filter_ctx;
613
2/2
✓ Branch 0 taken 6924 times.
✓ Branch 1 taken 8108 times.
15032 AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads;
614
2/2
✓ Branch 0 taken 6924 times.
✓ Branch 1 taken 8108 times.
15032 int nb_pads = in ? ctx->nb_inputs : ctx->nb_outputs;
615
616
2/2
✓ Branch 0 taken 134 times.
✓ Branch 1 taken 14898 times.
15032 if (nb_pads > 1)
617 134 return av_strdup(ctx->filter->name);
618 14898 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 8108 static OutputFilter *ofilter_alloc(FilterGraph *fg, enum AVMediaType type)
637 {
638 OutputFilterPriv *ofp;
639 OutputFilter *ofilter;
640
641 8108 ofp = allocate_array_elem(&fg->outputs, sizeof(*ofp), &fg->nb_outputs);
642
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8108 times.
8108 if (!ofp)
643 return NULL;
644
645 8108 ofilter = &ofp->ofilter;
646 8108 ofilter->class = &ofilter_class;
647 8108 ofp->log_parent = fg;
648 8108 ofilter->graph = fg;
649 8108 ofilter->type = type;
650 8108 ofp->format = -1;
651 8108 ofp->color_space = AVCOL_SPC_UNSPECIFIED;
652 8108 ofp->color_range = AVCOL_RANGE_UNSPECIFIED;
653 8108 ofilter->index = fg->nb_outputs - 1;
654
655 16216 snprintf(ofp->log_name, sizeof(ofp->log_name), "%co%d",
656 8108 av_get_media_type_string(type)[0], ofilter->index);
657
658 8108 return ofilter;
659 }
660
661 6923 static int ifilter_bind_ist(InputFilter *ifilter, InputStream *ist,
662 const ViewSpecifier *vs)
663 {
664 6923 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
665 6923 FilterGraphPriv *fgp = fgp_from_fg(ifilter->graph);
666 SchedulerNode src;
667 int ret;
668
669
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6923 times.
6923 av_assert0(!ifp->bound);
670 6923 ifp->bound = 1;
671
672
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6919 times.
6923 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 6923 ifp->type_src = ist->st->codecpar->codec_type;
680
681 6923 ifp->opts.fallback = av_frame_alloc();
682
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6923 times.
6923 if (!ifp->opts.fallback)
683 return AVERROR(ENOMEM);
684
685 6923 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 6923 times.
6923 if (ret < 0)
688 return ret;
689
690 6923 ifilter->input_name = av_strdup(ifp->opts.name);
691
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6923 times.
6923 if (!ifilter->input_name)
692 return AVERROR(EINVAL);
693
694 6923 ret = sch_connect(fgp->sch,
695 6923 src, SCH_FILTER_IN(fgp->sch_idx, ifilter->index));
696
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6923 times.
6923 if (ret < 0)
697 return ret;
698
699
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6919 times.
6923 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 6923 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 8108 int ofilter_bind_enc(OutputFilter *ofilter, unsigned sched_idx_enc,
794 const OutputFilterOptions *opts)
795 {
796 8108 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
797 8108 FilterGraph *fg = ofilter->graph;
798 8108 FilterGraphPriv *fgp = fgp_from_fg(fg);
799 int ret;
800
801
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8108 times.
8108 av_assert0(!ofilter->bound);
802
2/4
✓ Branch 0 taken 8108 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8108 times.
8108 av_assert0(!opts->enc ||
803 ofilter->type == opts->enc->type);
804
805 8108 ofilter->bound = 1;
806 8108 av_freep(&ofilter->linklabel);
807
808 8108 ofp->flags = opts->flags;
809 8108 ofp->ts_offset = opts->ts_offset;
810 8108 ofp->enc_timebase = opts->output_tb;
811
812 8108 ofp->trim_start_us = opts->trim_start_us;
813 8108 ofp->trim_duration_us = opts->trim_duration_us;
814
815 8108 ofilter->output_name = av_strdup(opts->name);
816
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8108 times.
8108 if (!ofilter->output_name)
817 return AVERROR(EINVAL);
818
819 8108 ret = av_dict_copy(&ofp->sws_opts, opts->sws_opts, 0);
820
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8108 times.
8108 if (ret < 0)
821 return ret;
822
823 8108 ret = av_dict_copy(&ofp->swr_opts, opts->swr_opts, 0);
824
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8108 times.
8108 if (ret < 0)
825 return ret;
826
827
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 8049 times.
8108 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 6774 times.
✓ Branch 1 taken 1334 times.
8108 if (fgp->is_simple) {
831 // for simple filtergraph there is just one output,
832 // so use only graph-level information for logging
833 6774 ofp->log_parent = NULL;
834 6774 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 6775 times.
✓ Branch 1 taken 1333 times.
✗ Branch 2 not taken.
8108 switch (ofilter->type) {
839 6775 case AVMEDIA_TYPE_VIDEO:
840 6775 ofp->width = opts->width;
841 6775 ofp->height = opts->height;
842
2/2
✓ Branch 0 taken 5299 times.
✓ Branch 1 taken 1476 times.
6775 if (opts->format != AV_PIX_FMT_NONE) {
843 5299 ofp->format = opts->format;
844 } else
845 1476 ofp->formats = opts->formats;
846
847
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6775 times.
6775 if (opts->color_space != AVCOL_SPC_UNSPECIFIED)
848 ofp->color_space = opts->color_space;
849 else
850 6775 ofp->color_spaces = opts->color_spaces;
851
852
2/2
✓ Branch 0 taken 1607 times.
✓ Branch 1 taken 5168 times.
6775 if (opts->color_range != AVCOL_RANGE_UNSPECIFIED)
853 1607 ofp->color_range = opts->color_range;
854 else
855 5168 ofp->color_ranges = opts->color_ranges;
856
857 6775 fgp->disable_conversions |= !!(ofp->flags & OFILTER_FLAG_DISABLE_CONVERT);
858
859 6775 ofp->fps.last_frame = av_frame_alloc();
860
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6775 times.
6775 if (!ofp->fps.last_frame)
861 return AVERROR(ENOMEM);
862
863 6775 ofp->fps.vsync_method = opts->vsync_method;
864 6775 ofp->fps.framerate = opts->frame_rate;
865 6775 ofp->fps.framerate_max = opts->max_frame_rate;
866 6775 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 6775 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 63 times.
✓ Branch 3 taken 6712 times.
6775 if (opts->enc && opts->enc->id == AV_CODEC_ID_MPEG4)
870 63 ofp->fps.framerate_clip = 65535;
871
872 6775 ofp->fps.dup_warning = 1000;
873
874 6775 break;
875 1333 case AVMEDIA_TYPE_AUDIO:
876
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1333 times.
1333 if (opts->format != AV_SAMPLE_FMT_NONE) {
877 ofp->format = opts->format;
878 } else {
879 1333 ofp->formats = opts->formats;
880 }
881
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 1319 times.
1333 if (opts->sample_rate) {
882 14 ofp->sample_rate = opts->sample_rate;
883 } else
884 1319 ofp->sample_rates = opts->sample_rates;
885
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 1322 times.
1333 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 1322 ofp->ch_layouts = opts->ch_layouts;
891 }
892 1333 break;
893 }
894
895 8108 ret = sch_connect(fgp->sch, SCH_FILTER_OUT(fgp->sch_idx, ofilter->index),
896 8108 SCH_ENC(sched_idx_enc));
897
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8108 times.
8108 if (ret < 0)
898 return ret;
899
900 8108 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 6924 static InputFilter *ifilter_alloc(FilterGraph *fg)
961 {
962 InputFilterPriv *ifp;
963 InputFilter *ifilter;
964
965 6924 ifp = allocate_array_elem(&fg->inputs, sizeof(*ifp), &fg->nb_inputs);
966
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6924 times.
6924 if (!ifp)
967 return NULL;
968
969 6924 ifilter = &ifp->ifilter;
970 6924 ifilter->graph = fg;
971
972 6924 ifp->frame = av_frame_alloc();
973
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6924 times.
6924 if (!ifp->frame)
974 return NULL;
975
976 6924 ifilter->index = fg->nb_inputs - 1;
977 6924 ifp->format = -1;
978 6924 ifp->color_space = AVCOL_SPC_UNSPECIFIED;
979 6924 ifp->color_range = AVCOL_RANGE_UNSPECIFIED;
980
981 6924 ifp->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
982
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6924 times.
6924 if (!ifp->frame_queue)
983 return NULL;
984
985 6924 return ifilter;
986 }
987
988 10052 void fg_free(FilterGraph **pfg)
989 {
990 10052 FilterGraph *fg = *pfg;
991 FilterGraphPriv *fgp;
992
993
2/2
✓ Branch 0 taken 2074 times.
✓ Branch 1 taken 7978 times.
10052 if (!fg)
994 2074 return;
995 7978 fgp = fgp_from_fg(fg);
996
997
2/2
✓ Branch 0 taken 6924 times.
✓ Branch 1 taken 7978 times.
14902 for (int j = 0; j < fg->nb_inputs; j++) {
998 6924 InputFilter *ifilter = fg->inputs[j];
999 6924 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1000
1001
1/2
✓ Branch 0 taken 6924 times.
✗ Branch 1 not taken.
6924 if (ifp->frame_queue) {
1002 AVFrame *frame;
1003
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6924 times.
6924 while (av_fifo_read(ifp->frame_queue, &frame, 1) >= 0)
1004 av_frame_free(&frame);
1005 6924 av_fifo_freep2(&ifp->frame_queue);
1006 }
1007 6924 av_frame_free(&ifp->sub2video.frame);
1008
1009 6924 av_frame_free(&ifp->frame);
1010 6924 av_frame_free(&ifp->opts.fallback);
1011
1012 6924 av_buffer_unref(&ifp->hw_frames_ctx);
1013 6924 av_freep(&ifilter->linklabel);
1014 6924 av_freep(&ifp->opts.name);
1015 6924 av_frame_side_data_free(&ifp->side_data, &ifp->nb_side_data);
1016 6924 av_freep(&ifilter->name);
1017 6924 av_freep(&ifilter->input_name);
1018 6924 av_freep(&fg->inputs[j]);
1019 }
1020 7978 av_freep(&fg->inputs);
1021
2/2
✓ Branch 0 taken 8108 times.
✓ Branch 1 taken 7978 times.
16086 for (int j = 0; j < fg->nb_outputs; j++) {
1022 8108 OutputFilter *ofilter = fg->outputs[j];
1023 8108 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1024
1025 8108 av_frame_free(&ofp->fps.last_frame);
1026 8108 av_dict_free(&ofp->sws_opts);
1027 8108 av_dict_free(&ofp->swr_opts);
1028
1029 8108 av_freep(&ofilter->linklabel);
1030 8108 av_freep(&ofilter->name);
1031 8108 av_freep(&ofilter->output_name);
1032 8108 av_freep(&ofilter->apad);
1033 8108 av_channel_layout_uninit(&ofp->ch_layout);
1034 8108 av_frame_side_data_free(&ofp->side_data, &ofp->nb_side_data);
1035 8108 av_freep(&fg->outputs[j]);
1036 }
1037 7978 av_freep(&fg->outputs);
1038 7978 av_freep(&fg->graph_desc);
1039
1040 7978 av_frame_free(&fgp->frame);
1041 7978 av_frame_free(&fgp->frame_enc);
1042
1043 7978 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 7978 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 7978 int ret = 0;
1068
1069 7978 fgp = av_mallocz(sizeof(*fgp));
1070
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7978 times.
7978 if (!fgp) {
1071 av_freep(&graph_desc);
1072 return AVERROR(ENOMEM);
1073 }
1074 7978 fg = &fgp->fg;
1075
1076
2/2
✓ Branch 0 taken 6774 times.
✓ Branch 1 taken 1204 times.
7978 if (pfg) {
1077 6774 *pfg = fg;
1078 6774 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 7978 fg->class = &fg_class;
1091 7978 fg->graph_desc = graph_desc;
1092 7978 fgp->disable_conversions = !auto_conversion_filters;
1093 7978 fgp->nb_threads = -1;
1094 7978 fgp->sch = sch;
1095
1096 7978 snprintf(fgp->log_name, sizeof(fgp->log_name), "fc#%d", fg->index);
1097
1098 7978 fgp->frame = av_frame_alloc();
1099 7978 fgp->frame_enc = av_frame_alloc();
1100
2/4
✓ Branch 0 taken 7978 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7978 times.
7978 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 7978 graph = avfilter_graph_alloc();
1106
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7978 times.
7978 if (!graph)
1107 return AVERROR(ENOMEM);;
1108 7978 graph->nb_threads = 1;
1109
1110 7978 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 7978 times.
7978 if (ret < 0)
1113 goto fail;
1114
1115
2/2
✓ Branch 0 taken 14823 times.
✓ Branch 1 taken 6828 times.
21651 for (unsigned i = 0; i < graph->nb_filters; i++) {
1116 14823 const AVFilter *f = graph->filters[i]->filter;
1117
2/2
✓ Branch 1 taken 1167 times.
✓ Branch 2 taken 13656 times.
14823 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 13673 times.
13674 !strcmp(f->name, "apad")) {
1120 1150 fgp->have_sources = 1;
1121 1150 break;
1122 }
1123 }
1124
1125
2/2
✓ Branch 0 taken 6924 times.
✓ Branch 1 taken 7978 times.
14902 for (AVFilterInOut *cur = inputs; cur; cur = cur->next) {
1126 6924 InputFilter *const ifilter = ifilter_alloc(fg);
1127
1128
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6924 times.
6924 if (!ifilter) {
1129 ret = AVERROR(ENOMEM);
1130 goto fail;
1131 }
1132
1133 6924 ifilter->linklabel = cur->name;
1134 6924 cur->name = NULL;
1135
1136 6924 ifilter->type = avfilter_pad_get_type(cur->filter_ctx->input_pads,
1137 cur->pad_idx);
1138
1139
3/4
✓ Branch 0 taken 1264 times.
✓ Branch 1 taken 5660 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1264 times.
6924 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 6924 ifilter->name = describe_filter_link(fg, cur, 1);
1147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6924 times.
6924 if (!ifilter->name) {
1148 ret = AVERROR(ENOMEM);
1149 goto fail;
1150 }
1151 }
1152
1153
2/2
✓ Branch 0 taken 8108 times.
✓ Branch 1 taken 7978 times.
16086 for (AVFilterInOut *cur = outputs; cur; cur = cur->next) {
1154 8108 const enum AVMediaType type = avfilter_pad_get_type(cur->filter_ctx->output_pads,
1155 cur->pad_idx);
1156 8108 OutputFilter *const ofilter = ofilter_alloc(fg, type);
1157
1158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8108 times.
8108 if (!ofilter) {
1159 ret = AVERROR(ENOMEM);
1160 goto fail;
1161 }
1162
1163 8108 ofilter->linklabel = cur->name;
1164 8108 cur->name = NULL;
1165
1166 8108 ofilter->name = describe_filter_link(fg, cur, 0);
1167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8108 times.
8108 if (!ofilter->name) {
1168 ret = AVERROR(ENOMEM);
1169 goto fail;
1170 }
1171 }
1172
1173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7978 times.
7978 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 7978 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 7978 times.
7978 if (ret < 0)
1182 goto fail;
1183 7978 fgp->sch_idx = ret;
1184
1185 7978 fail:
1186 7978 avfilter_inout_free(&inputs);
1187 7978 avfilter_inout_free(&outputs);
1188 7978 avfilter_graph_free(&graph);
1189
1190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7978 times.
7978 if (ret < 0)
1191 return ret;
1192
1193 7978 return 0;
1194 }
1195
1196 6774 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 6774 const enum AVMediaType type = ist->par->codec_type;
1203 FilterGraph *fg;
1204 FilterGraphPriv *fgp;
1205 int ret;
1206
1207 6774 ret = fg_create(pfg, graph_desc, sch);
1208
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6774 times.
6774 if (ret < 0)
1209 return ret;
1210 6774 fg = *pfg;
1211 6774 fgp = fgp_from_fg(fg);
1212
1213 6774 fgp->is_simple = 1;
1214
1215 6774 snprintf(fgp->log_name, sizeof(fgp->log_name), "%cf%s",
1216 6774 av_get_media_type_string(type)[0], opts->name);
1217
1218
2/4
✓ Branch 0 taken 6774 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6774 times.
6774 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 6774 times.
6774 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 6774 ret = ifilter_bind_ist(fg->inputs[0], ist, opts->vs);
1235
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6774 times.
6774 if (ret < 0)
1236 return ret;
1237
1238 6774 ret = ofilter_bind_enc(fg->outputs[0], sched_idx_enc, opts);
1239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6774 times.
6774 if (ret < 0)
1240 return ret;
1241
1242
2/2
✓ Branch 0 taken 4238 times.
✓ Branch 1 taken 2536 times.
6774 if (opts->nb_threads >= 0)
1243 4238 fgp->nb_threads = opts->nb_threads;
1244
1245 6774 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 8362 int fg_finalise_bindings(void)
1404 {
1405 int ret;
1406
1407
2/2
✓ Branch 0 taken 1204 times.
✓ Branch 1 taken 8362 times.
9566 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 8362 times.
9566 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 8362 return 0;
1430 }
1431
1432 15124 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 15124 AVFilterGraph *graph = (*last_filter)->graph;
1437 AVFilterContext *ctx;
1438 const AVFilter *trim;
1439 15124 enum AVMediaType type = avfilter_pad_get_type((*last_filter)->output_pads, *pad_idx);
1440
2/2
✓ Branch 0 taken 12525 times.
✓ Branch 1 taken 2599 times.
15124 const char *name = (type == AVMEDIA_TYPE_VIDEO) ? "trim" : "atrim";
1441 15124 int ret = 0;
1442
1443
4/4
✓ Branch 0 taken 13821 times.
✓ Branch 1 taken 1303 times.
✓ Branch 2 taken 13804 times.
✓ Branch 3 taken 17 times.
15124 if (duration == INT64_MAX && start_time == AV_NOPTS_VALUE)
1444 13804 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 6820 static int configure_output_video_filter(FilterGraphPriv *fgp, AVFilterGraph *graph,
1510 OutputFilter *ofilter, AVFilterInOut *out)
1511 {
1512 6820 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1513 6820 AVFilterContext *last_filter = out->filter_ctx;
1514 AVBPrint bprint;
1515 6820 int pad_idx = out->pad_idx;
1516 int ret;
1517 char name[255];
1518
1519 6820 snprintf(name, sizeof(name), "out_%s", ofilter->output_name);
1520 6820 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 6820 times.
6820 if (ret < 0)
1525 return ret;
1526
1527
4/6
✓ Branch 0 taken 5469 times.
✓ Branch 1 taken 1351 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5469 times.
✓ Branch 4 taken 1351 times.
✗ Branch 5 not taken.
6820 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 6820 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
6820 av_assert0(!(ofp->flags & OFILTER_FLAG_DISABLE_CONVERT) ||
1551 ofp->format != AV_PIX_FMT_NONE || !ofp->formats);
1552 6820 av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
1553 6820 choose_pix_fmts(ofp, &bprint);
1554 6820 choose_color_spaces(ofp, &bprint);
1555 6820 choose_color_ranges(ofp, &bprint);
1556
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6820 times.
6820 if (!av_bprint_is_complete(&bprint))
1557 return AVERROR(ENOMEM);
1558
1559
2/2
✓ Branch 0 taken 5685 times.
✓ Branch 1 taken 1135 times.
6820 if (bprint.len) {
1560 AVFilterContext *filter;
1561
1562 5685 ret = avfilter_graph_create_filter(&filter,
1563 avfilter_get_by_name("format"),
1564 5685 "format", bprint.str, NULL, graph);
1565 5685 av_bprint_finalize(&bprint, NULL);
1566
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5685 times.
5685 if (ret < 0)
1567 return ret;
1568
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5685 times.
5685 if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
1569 return ret;
1570
1571 5685 last_filter = filter;
1572 5685 pad_idx = 0;
1573 }
1574
1575 6820 snprintf(name, sizeof(name), "trim_out_%s", ofilter->output_name);
1576 6820 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 6820 times.
6820 if (ret < 0)
1579 return ret;
1580
1581
1582
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6820 times.
6820 if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
1583 return ret;
1584
1585 6820 return 0;
1586 }
1587
1588 1334 static int configure_output_audio_filter(FilterGraphPriv *fgp, AVFilterGraph *graph,
1589 OutputFilter *ofilter, AVFilterInOut *out)
1590 {
1591 1334 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1592 1334 AVFilterContext *last_filter = out->filter_ctx;
1593 1334 int pad_idx = out->pad_idx;
1594 AVBPrint args;
1595 char name[255];
1596 int ret;
1597
1598 1334 snprintf(name, sizeof(name), "out_%s", ofilter->output_name);
1599 1334 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 1334 times.
1334 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 1334 av_bprint_init(&args, 0, AV_BPRINT_SIZE_UNLIMITED);
1625
1626 1334 choose_sample_fmts(ofp, &args);
1627 1334 choose_sample_rates(ofp, &args);
1628 1334 choose_channel_layouts(ofp, &args);
1629
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1334 times.
1334 if (!av_bprint_is_complete(&args)) {
1630 ret = AVERROR(ENOMEM);
1631 goto fail;
1632 }
1633
1/2
✓ Branch 0 taken 1334 times.
✗ Branch 1 not taken.
1334 if (args.len) {
1634 AVFilterContext *format;
1635
1636 1334 snprintf(name, sizeof(name), "format_out_%s", ofilter->output_name);
1637 1334 ret = avfilter_graph_create_filter(&format,
1638 avfilter_get_by_name("aformat"),
1639 1334 name, args.str, NULL, graph);
1640
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1334 times.
1334 if (ret < 0)
1641 goto fail;
1642
1643 1334 ret = avfilter_link(last_filter, pad_idx, format, 0);
1644
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1334 times.
1334 if (ret < 0)
1645 goto fail;
1646
1647 1334 last_filter = format;
1648 1334 pad_idx = 0;
1649 }
1650
1651
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1334 times.
1334 if (ofilter->apad) {
1652 AUTO_INSERT_FILTER("-apad", "apad", ofilter->apad);
1653 fgp->have_sources = 1;
1654 }
1655
1656 1334 snprintf(name, sizeof(name), "trim for output %s", ofilter->output_name);
1657 1334 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 1334 times.
1334 if (ret < 0)
1660 goto fail;
1661
1662
1/2
✓ Branch 1 taken 1334 times.
✗ Branch 2 not taken.
1334 if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
1663 goto fail;
1664 1334 fail:
1665 1334 av_bprint_finalize(&args, NULL);
1666
1667 1334 return ret;
1668 }
1669
1670 8154 static int configure_output_filter(FilterGraphPriv *fgp, AVFilterGraph *graph,
1671 OutputFilter *ofilter, AVFilterInOut *out)
1672 {
1673
2/3
✓ Branch 0 taken 6820 times.
✓ Branch 1 taken 1334 times.
✗ Branch 2 not taken.
8154 switch (ofilter->type) {
1674 6820 case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fgp, graph, ofilter, out);
1675 1334 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 5705 static int configure_input_video_filter(FilterGraph *fg, AVFilterGraph *graph,
1692 InputFilter *ifilter, AVFilterInOut *in)
1693 {
1694 5705 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1695
1696 AVFilterContext *last_filter;
1697 5705 const AVFilter *buffer_filt = avfilter_get_by_name("buffer");
1698 const AVPixFmtDescriptor *desc;
1699 char name[255];
1700 5705 int ret, pad_idx = 0;
1701 5705 AVBufferSrcParameters *par = av_buffersrc_parameters_alloc();
1702
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5705 times.
5705 if (!par)
1703 return AVERROR(ENOMEM);
1704
1705
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5701 times.
5705 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE)
1706 4 sub2video_prepare(ifp);
1707
1708 5705 snprintf(name, sizeof(name), "graph %d input from stream %s", fg->index,
1709 ifp->opts.name);
1710
1711 5705 ifilter->filter = avfilter_graph_alloc_filter(graph, buffer_filt, name);
1712
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5705 times.
5705 if (!ifilter->filter) {
1713 ret = AVERROR(ENOMEM);
1714 goto fail;
1715 }
1716
1717 5705 par->format = ifp->format;
1718 5705 par->time_base = ifp->time_base;
1719 5705 par->frame_rate = ifp->opts.framerate;
1720 5705 par->width = ifp->width;
1721 5705 par->height = ifp->height;
1722 5705 par->sample_aspect_ratio = ifp->sample_aspect_ratio.den > 0 ?
1723
2/2
✓ Branch 0 taken 5701 times.
✓ Branch 1 taken 4 times.
5705 ifp->sample_aspect_ratio : (AVRational){ 0, 1 };
1724 5705 par->color_space = ifp->color_space;
1725 5705 par->color_range = ifp->color_range;
1726 5705 par->hw_frames_ctx = ifp->hw_frames_ctx;
1727 5705 par->side_data = ifp->side_data;
1728 5705 par->nb_side_data = ifp->nb_side_data;
1729
1730 5705 ret = av_buffersrc_parameters_set(ifilter->filter, par);
1731
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5705 times.
5705 if (ret < 0)
1732 goto fail;
1733 5705 av_freep(&par);
1734
1735 5705 ret = avfilter_init_dict(ifilter->filter, NULL);
1736
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5705 times.
5705 if (ret < 0)
1737 goto fail;
1738
1739 5705 last_filter = ifilter->filter;
1740
1741 5705 desc = av_pix_fmt_desc_get(ifp->format);
1742
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5705 times.
5705 av_assert0(desc);
1743
1744
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 5699 times.
5705 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 5705 ifp->displaymatrix_applied = 0;
1757
2/2
✓ Branch 0 taken 5704 times.
✓ Branch 1 taken 1 times.
5705 if ((ifp->opts.flags & IFILTER_FLAG_AUTOROTATE) &&
1758
1/2
✓ Branch 0 taken 5704 times.
✗ Branch 1 not taken.
5704 !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
1759 5704 int32_t *displaymatrix = ifp->displaymatrix;
1760 double theta;
1761
1762 5704 theta = get_rotation(displaymatrix);
1763
1764
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5700 times.
5704 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 5700 times.
5700 } 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 5700 times.
5700 } 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 5700 times.
5700 } 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 5700 times.
5700 } 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 5704 times.
5704 if (ret < 0)
1789 return ret;
1790
1791 5704 ifp->displaymatrix_applied = 1;
1792 }
1793
1794 5705 snprintf(name, sizeof(name), "trim_in_%s", ifp->opts.name);
1795 5705 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 5705 times.
5705 if (ret < 0)
1798 return ret;
1799
1800
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5705 times.
5705 if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
1801 return ret;
1802 5705 return 0;
1803 fail:
1804 av_freep(&par);
1805
1806 return ret;
1807 }
1808
1809 1265 static int configure_input_audio_filter(FilterGraph *fg, AVFilterGraph *graph,
1810 InputFilter *ifilter, AVFilterInOut *in)
1811 {
1812 1265 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1813 AVFilterContext *last_filter;
1814 AVBufferSrcParameters *par;
1815 1265 const AVFilter *abuffer_filt = avfilter_get_by_name("abuffer");
1816 AVBPrint args;
1817 char name[255];
1818 1265 int ret, pad_idx = 0;
1819
1820 1265 av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);
1821 1265 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 1265 av_get_sample_fmt_name(ifp->format));
1825
1/2
✓ Branch 1 taken 1265 times.
✗ Branch 2 not taken.
1265 if (av_channel_layout_check(&ifp->ch_layout) &&
1826
2/2
✓ Branch 0 taken 1252 times.
✓ Branch 1 taken 13 times.
1265 ifp->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
1827 1252 av_bprintf(&args, ":channel_layout=");
1828 1252 av_channel_layout_describe_bprint(&ifp->ch_layout, &args);
1829 } else
1830 13 av_bprintf(&args, ":channels=%d", ifp->ch_layout.nb_channels);
1831 1265 snprintf(name, sizeof(name), "graph_%d_in_%s", fg->index, ifp->opts.name);
1832
1833
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1265 times.
1265 if ((ret = avfilter_graph_create_filter(&ifilter->filter, abuffer_filt,
1834 1265 name, args.str, NULL,
1835 graph)) < 0)
1836 return ret;
1837 1265 par = av_buffersrc_parameters_alloc();
1838
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1265 times.
1265 if (!par)
1839 return AVERROR(ENOMEM);
1840 1265 par->side_data = ifp->side_data;
1841 1265 par->nb_side_data = ifp->nb_side_data;
1842 1265 ret = av_buffersrc_parameters_set(ifilter->filter, par);
1843 1265 av_free(par);
1844
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1265 times.
1265 if (ret < 0)
1845 return ret;
1846 1265 last_filter = ifilter->filter;
1847
1848 1265 snprintf(name, sizeof(name), "trim for input stream %s", ifp->opts.name);
1849 1265 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 1265 times.
1265 if (ret < 0)
1852 return ret;
1853
1854
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1265 times.
1265 if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
1855 return ret;
1856
1857 1265 return 0;
1858 }
1859
1860 6970 static int configure_input_filter(FilterGraph *fg, AVFilterGraph *graph,
1861 InputFilter *ifilter, AVFilterInOut *in)
1862 {
1863
2/3
✓ Branch 0 taken 5705 times.
✓ Branch 1 taken 1265 times.
✗ Branch 2 not taken.
6970 switch (ifilter->type) {
1864 5705 case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, graph, ifilter, in);
1865 1265 case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, graph, ifilter, in);
1866 default: av_assert0(0); return 0;
1867 }
1868 }
1869
1870 8024 static void cleanup_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
1871 {
1872
2/2
✓ Branch 0 taken 8154 times.
✓ Branch 1 taken 8024 times.
16178 for (int i = 0; i < fg->nb_outputs; i++)
1873 8154 fg->outputs[i]->filter = NULL;
1874
2/2
✓ Branch 0 taken 6970 times.
✓ Branch 1 taken 8024 times.
14994 for (int i = 0; i < fg->nb_inputs; i++)
1875 6970 fg->inputs[i]->filter = NULL;
1876 8024 avfilter_graph_free(&fgt->graph);
1877 8024 }
1878
1879 9224 static int filter_is_buffersrc(const AVFilterContext *f)
1880 {
1881
2/2
✓ Branch 0 taken 4095 times.
✓ Branch 1 taken 5129 times.
13319 return f->nb_inputs == 0 &&
1882
2/2
✓ Branch 0 taken 1752 times.
✓ Branch 1 taken 2343 times.
4095 (!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 8024 static int graph_is_meta(AVFilterGraph *graph)
1887 {
1888
2/2
✓ Branch 0 taken 17518 times.
✓ Branch 1 taken 1754 times.
19272 for (unsigned i = 0; i < graph->nb_filters; i++) {
1889 17518 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 12176 times.
✓ Branch 1 taken 5342 times.
✓ Branch 2 taken 6270 times.
✓ Branch 3 taken 2954 times.
26742 if (!((f->filter->flags & AVFILTER_FLAG_METADATA_ONLY) ||
1896
2/2
✓ Branch 0 taken 9224 times.
✓ Branch 1 taken 2952 times.
12176 f->nb_outputs == 0 ||
1897 9224 filter_is_buffersrc(f)))
1898 6270 return 0;
1899 }
1900 1754 return 1;
1901 }
1902
1903 static int sub2video_frame(InputFilter *ifilter, AVFrame *frame, int buffer);
1904
1905 8024 static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
1906 {
1907 8024 FilterGraphPriv *fgp = fgp_from_fg(fg);
1908 AVBufferRef *hw_device;
1909 AVFilterInOut *inputs, *outputs, *cur;
1910 8024 int ret = AVERROR_BUG, i, simple = filtergraph_is_simple(fg);
1911 8024 int have_input_eof = 0;
1912 8024 const char *graph_desc = fg->graph_desc;
1913
1914 8024 cleanup_filtergraph(fg, fgt);
1915 8024 fgt->graph = avfilter_graph_alloc();
1916
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8024 times.
8024 if (!fgt->graph)
1917 return AVERROR(ENOMEM);
1918
1919
2/2
✓ Branch 0 taken 6820 times.
✓ Branch 1 taken 1204 times.
8024 if (simple) {
1920 6820 OutputFilterPriv *ofp = ofp_from_ofilter(fg->outputs[0]);
1921
1922
2/2
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 6443 times.
6820 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 4026 times.
✓ Branch 1 taken 2417 times.
6443 } else if (fgp->nb_threads >= 0) {
1927 4026 ret = av_opt_set_int(fgt->graph, "threads", fgp->nb_threads, 0);
1928
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4026 times.
4026 if (ret < 0)
1929 return ret;
1930 }
1931
1932
2/2
✓ Branch 1 taken 4379 times.
✓ Branch 2 taken 2441 times.
6820 if (av_dict_count(ofp->sws_opts)) {
1933 4379 ret = av_dict_get_string(ofp->sws_opts,
1934 4379 &fgt->graph->scale_sws_opts,
1935 '=', ':');
1936
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4379 times.
4379 if (ret < 0)
1937 goto fail;
1938 }
1939
1940
2/2
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 6761 times.
6820 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 8024 hw_device = hw_device_for_filter();
1953
1954 8024 ret = graph_parse(fg, fgt->graph, graph_desc, &inputs, &outputs, hw_device);
1955
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8024 times.
8024 if (ret < 0)
1956 goto fail;
1957
1958
2/2
✓ Branch 0 taken 6970 times.
✓ Branch 1 taken 8024 times.
14994 for (cur = inputs, i = 0; cur; cur = cur->next, i++)
1959
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6970 times.
6970 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 8024 avfilter_inout_free(&inputs);
1965
1966
2/2
✓ Branch 0 taken 8154 times.
✓ Branch 1 taken 8024 times.
16178 for (cur = outputs, i = 0; cur; cur = cur->next, i++) {
1967 8154 ret = configure_output_filter(fgp, fgt->graph, fg->outputs[i], cur);
1968
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8154 times.
8154 if (ret < 0) {
1969 avfilter_inout_free(&outputs);
1970 goto fail;
1971 }
1972 }
1973 8024 avfilter_inout_free(&outputs);
1974
1975
2/2
✓ Branch 0 taken 6210 times.
✓ Branch 1 taken 1814 times.
8024 if (fgp->disable_conversions)
1976 6210 avfilter_graph_set_auto_convert(fgt->graph, AVFILTER_AUTO_CONVERT_NONE);
1977
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8024 times.
8024 if ((ret = avfilter_graph_config(fgt->graph, NULL)) < 0)
1978 goto fail;
1979
1980 8024 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 8154 times.
✓ Branch 1 taken 8024 times.
16178 for (int i = 0; i < fg->nb_outputs; i++) {
1985 const AVFrameSideData *const *sd;
1986 int nb_sd;
1987 8154 OutputFilter *ofilter = fg->outputs[i];
1988 8154 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1989 8154 AVFilterContext *sink = ofilter->filter;
1990
1991 8154 ofp->format = av_buffersink_get_format(sink);
1992
1993 8154 ofp->width = av_buffersink_get_w(sink);
1994 8154 ofp->height = av_buffersink_get_h(sink);
1995 8154 ofp->color_space = av_buffersink_get_colorspace(sink);
1996 8154 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 8108 times.
✓ Branch 1 taken 46 times.
8154 if (!ofp->tb_out_locked) {
2002 8108 AVRational fr = av_buffersink_get_frame_rate(sink);
2003
3/4
✓ Branch 0 taken 8087 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 8087 times.
✗ Branch 3 not taken.
8108 if (ofp->fps.framerate.num <= 0 && ofp->fps.framerate.den <= 0 &&
2004
4/4
✓ Branch 0 taken 6752 times.
✓ Branch 1 taken 1335 times.
✓ Branch 2 taken 6738 times.
✓ Branch 3 taken 14 times.
8087 fr.num > 0 && fr.den > 0)
2005 6738 ofp->fps.framerate = fr;
2006 8108 ofp->tb_out = av_buffersink_get_time_base(sink);
2007 }
2008 8154 ofp->sample_aspect_ratio = av_buffersink_get_sample_aspect_ratio(sink);
2009
2010 8154 ofp->sample_rate = av_buffersink_get_sample_rate(sink);
2011 8154 av_channel_layout_uninit(&ofp->ch_layout);
2012 8154 ret = av_buffersink_get_ch_layout(sink, &ofp->ch_layout);
2013
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8154 times.
8154 if (ret < 0)
2014 goto fail;
2015 8154 av_frame_side_data_free(&ofp->side_data, &ofp->nb_side_data);
2016 8154 sd = av_buffersink_get_side_data(sink, &nb_sd);
2017
2/2
✓ Branch 0 taken 226 times.
✓ Branch 1 taken 7928 times.
8154 if (nb_sd)
2018
2/2
✓ Branch 0 taken 233 times.
✓ Branch 1 taken 226 times.
459 for (int j = 0; j < nb_sd; j++) {
2019 233 ret = av_frame_side_data_clone(&ofp->side_data, &ofp->nb_side_data,
2020 233 sd[j], 0);
2021
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 233 times.
233 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 6970 times.
✓ Branch 1 taken 8024 times.
14994 for (int i = 0; i < fg->nb_inputs; i++) {
2029 6970 InputFilter *ifilter = fg->inputs[i];
2030 6970 InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[i]);
2031 AVFrame *tmp;
2032
2/2
✓ Branch 1 taken 265 times.
✓ Branch 2 taken 6970 times.
7235 while (av_fifo_read(ifp->frame_queue, &tmp, 1) >= 0) {
2033
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 226 times.
265 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
2034 39 sub2video_frame(&ifp->ifilter, tmp, !fgt->graph);
2035 } else {
2036
2/2
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 135 times.
226 if (ifp->type_src == AVMEDIA_TYPE_VIDEO) {
2037
1/2
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
91 if (ifp->displaymatrix_applied)
2038 91 av_frame_remove_side_data(tmp, AV_FRAME_DATA_DISPLAYMATRIX);
2039 }
2040 226 ret = av_buffersrc_add_frame(ifilter->filter, tmp);
2041 }
2042 265 av_frame_free(&tmp);
2043
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 265 times.
265 if (ret < 0)
2044 goto fail;
2045 }
2046 }
2047
2048 /* send the EOFs for the finished inputs */
2049
2/2
✓ Branch 0 taken 6970 times.
✓ Branch 1 taken 8024 times.
14994 for (int i = 0; i < fg->nb_inputs; i++) {
2050 6970 InputFilter *ifilter = fg->inputs[i];
2051
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6962 times.
6970 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 8016 times.
8024 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 8024 return 0;
2067 fail:
2068 cleanup_filtergraph(fg, fgt);
2069 return ret;
2070 }
2071
2072 6964 static int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
2073 {
2074 6964 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2075 AVFrameSideData *sd;
2076 int ret;
2077
2078 6964 ret = av_buffer_replace(&ifp->hw_frames_ctx, frame->hw_frames_ctx);
2079
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6964 times.
6964 if (ret < 0)
2080 return ret;
2081
2082
2/2
✓ Branch 0 taken 1262 times.
✓ Branch 1 taken 5702 times.
12634 ifp->time_base = (ifilter->type == AVMEDIA_TYPE_AUDIO) ? (AVRational){ 1, frame->sample_rate } :
2083
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 5670 times.
5702 (ifp->opts.flags & IFILTER_FLAG_CFR) ? av_inv_q(ifp->opts.framerate) :
2084 frame->time_base;
2085
2086 6964 ifp->format = frame->format;
2087
2088 6964 ifp->width = frame->width;
2089 6964 ifp->height = frame->height;
2090 6964 ifp->sample_aspect_ratio = frame->sample_aspect_ratio;
2091 6964 ifp->color_space = frame->colorspace;
2092 6964 ifp->color_range = frame->color_range;
2093
2094 6964 ifp->sample_rate = frame->sample_rate;
2095 6964 ret = av_channel_layout_copy(&ifp->ch_layout, &frame->ch_layout);
2096
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6964 times.
6964 if (ret < 0)
2097 return ret;
2098
2099 6964 av_frame_side_data_free(&ifp->side_data, &ifp->nb_side_data);
2100
2/2
✓ Branch 0 taken 499 times.
✓ Branch 1 taken 6964 times.
7463 for (int i = 0; i < frame->nb_side_data; i++) {
2101 499 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 233 times.
499 if (!(desc->props & AV_SIDE_DATA_PROP_GLOBAL))
2104 266 continue;
2105
2106 233 ret = av_frame_side_data_clone(&ifp->side_data,
2107 &ifp->nb_side_data,
2108 233 frame->side_data[i], 0);
2109
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 233 times.
233 if (ret < 0)
2110 return ret;
2111 }
2112
2113 6964 sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX);
2114
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6960 times.
6964 if (sd)
2115 4 memcpy(ifp->displaymatrix, sd->data, sizeof(ifp->displaymatrix));
2116 6964 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 6964 sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DOWNMIX_INFO);
2122
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6959 times.
6964 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 6964 ifp->downmixinfo_present = !!sd;
2130
2131 6964 return 0;
2132 }
2133
2134 37956 int filtergraph_is_simple(const FilterGraph *fg)
2135 {
2136 37956 const FilterGraphPriv *fgp = cfgp_from_cfg(fg);
2137 37956 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 364245 static int choose_input(const FilterGraph *fg, const FilterGraphThread *fgt)
2166 {
2167 364245 int nb_requests, nb_requests_max = -1;
2168 364245 int best_input = -1;
2169
2170
2/2
✓ Branch 0 taken 376860 times.
✓ Branch 1 taken 364245 times.
741105 for (int i = 0; i < fg->nb_inputs; i++) {
2171 376860 InputFilter *ifilter = fg->inputs[i];
2172
2173
2/2
✓ Branch 0 taken 1220 times.
✓ Branch 1 taken 375640 times.
376860 if (fgt->eof_in[i])
2174 1220 continue;
2175
2176 375640 nb_requests = av_buffersrc_get_nb_failed_requests(ifilter->filter);
2177
2/2
✓ Branch 0 taken 366416 times.
✓ Branch 1 taken 9224 times.
375640 if (nb_requests > nb_requests_max) {
2178 366416 nb_requests_max = nb_requests;
2179 366416 best_input = i;
2180 }
2181 }
2182
2183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 364245 times.
364245 av_assert0(best_input >= 0);
2184
2185 364245 return best_input;
2186 }
2187
2188 8105 static int choose_out_timebase(OutputFilterPriv *ofp, AVFrame *frame)
2189 {
2190 8105 OutputFilter *ofilter = &ofp->ofilter;
2191 8105 FPSConvContext *fps = &ofp->fps;
2192 8105 AVRational tb = (AVRational){ 0, 0 };
2193 AVRational fr;
2194 const FrameData *fd;
2195
2196 8105 fd = frame_data_c(frame);
2197
2198 // apply -enc_time_base
2199
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8104 times.
8105 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 8104 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8105 switch (ofp->enc_timebase.num) {
2207 8104 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 1330 times.
✓ Branch 1 taken 6775 times.
8105 if (ofilter->type == AVMEDIA_TYPE_AUDIO) {
2214
1/2
✓ Branch 0 taken 1330 times.
✗ Branch 1 not taken.
1330 tb = tb.num ? tb : (AVRational){ 1, frame->sample_rate };
2215 1330 goto finish;
2216 }
2217
2218 6775 fr = fps->framerate;
2219
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6759 times.
6775 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 5663 times.
✓ Branch 1 taken 1112 times.
✓ Branch 2 taken 338 times.
✓ Branch 3 taken 5325 times.
6775 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 6759 times.
✓ Branch 1 taken 16 times.
6775 if (fr.num > 0) {
2242
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 6705 times.
6759 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 6696 times.
6759 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 6774 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
6775 if (!(tb.num > 0 && tb.den > 0))
2253 6774 tb = av_inv_q(fr);
2254
3/4
✓ Branch 0 taken 6759 times.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6759 times.
6775 if (!(tb.num > 0 && tb.den > 0))
2255 16 tb = frame->time_base;
2256
2257 6775 fps->framerate = fr;
2258 8105 finish:
2259 8105 ofp->tb_out = tb;
2260 8105 ofp->tb_out_locked = 1;
2261
2262 8105 return 0;
2263 }
2264
2265 139573 static double adjust_frame_pts_to_encoder_tb(void *logctx, AVFrame *frame,
2266 AVRational tb_dst, int64_t start_time)
2267 {
2268 139573 double float_pts = AV_NOPTS_VALUE; // this is identical to frame.pts but with higher precision
2269
2270 139573 AVRational tb = tb_dst;
2271 139573 AVRational filter_tb = frame->time_base;
2272 139573 const int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16);
2273
2274
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 139573 times.
139573 if (frame->pts == AV_NOPTS_VALUE)
2275 goto early_exit;
2276
2277 139573 tb.den <<= extra_bits;
2278 139573 float_pts = av_rescale_q(frame->pts, filter_tb, tb) -
2279 139573 av_rescale_q(start_time, AV_TIME_BASE_Q, tb);
2280 139573 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 6075 times.
✓ Branch 1 taken 133498 times.
139573 if (float_pts != llrint(float_pts))
2285
1/2
✓ Branch 0 taken 6075 times.
✗ Branch 1 not taken.
6075 float_pts += FFSIGN(float_pts) * 1.0 / (1<<17);
2286
2287 139573 frame->pts = av_rescale_q(frame->pts, filter_tb, tb_dst) -
2288 139573 av_rescale_q(start_time, AV_TIME_BASE_Q, tb_dst);
2289 139573 frame->time_base = tb_dst;
2290
2291 139573 early_exit:
2292
2293
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 139573 times.
139573 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 139573 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 143318 static void video_sync_process(OutputFilterPriv *ofp, AVFrame *frame,
2309 int64_t *nb_frames, int64_t *nb_frames_prev)
2310 {
2311 143318 OutputFilter *ofilter = &ofp->ofilter;
2312 143318 FPSConvContext *fps = &ofp->fps;
2313 double delta0, delta, sync_ipts, duration;
2314
2315
2/2
✓ Branch 0 taken 3745 times.
✓ Branch 1 taken 139573 times.
143318 if (!frame) {
2316 3745 *nb_frames_prev = *nb_frames = mid_pred(fps->frames_prev_hist[0],
2317 3745 fps->frames_prev_hist[1],
2318 3745 fps->frames_prev_hist[2]);
2319
2320
4/4
✓ Branch 0 taken 3744 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 3742 times.
3745 if (!*nb_frames && fps->last_dropped) {
2321 2 atomic_fetch_add(&ofilter->nb_frames_drop, 1);
2322 2 fps->last_dropped++;
2323 }
2324
2325 3745 goto finish;
2326 }
2327
2328 139573 duration = frame->duration * av_q2d(frame->time_base) / av_q2d(ofp->tb_out);
2329
2330 139573 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 139573 delta0 = sync_ipts - ofp->next_pts;
2335 139573 delta = delta0 + duration;
2336
2337 // tracks the number of times the PREVIOUS frame should be duplicated,
2338 // mostly for variable framerate (VFR)
2339 139573 *nb_frames_prev = 0;
2340 /* by default, we output a single frame */
2341 139573 *nb_frames = 1;
2342
2343
4/4
✓ Branch 0 taken 5041 times.
✓ Branch 1 taken 134532 times.
✓ Branch 2 taken 3856 times.
✓ Branch 3 taken 1185 times.
139573 if (delta0 < 0 &&
2344 3856 delta > 0 &&
2345
1/2
✓ Branch 0 taken 3856 times.
✗ Branch 1 not taken.
3856 fps->vsync_method != VSYNC_PASSTHROUGH
2346 #if FFMPEG_OPT_VSYNC_DROP
2347
1/2
✓ Branch 0 taken 3856 times.
✗ Branch 1 not taken.
3856 && fps->vsync_method != VSYNC_DROP
2348 #endif
2349 ) {
2350
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 3811 times.
3856 if (delta0 < -0.6) {
2351 45 av_log(ofp, AV_LOG_VERBOSE, "Past duration %f too large\n", -delta0);
2352 } else
2353 3811 av_log(ofp, AV_LOG_DEBUG, "Clipping frame in rate conversion by %f\n", -delta0);
2354 3856 sync_ipts = ofp->next_pts;
2355 3856 duration += delta0;
2356 3856 delta0 = 0;
2357 }
2358
2359
4/5
✓ Branch 0 taken 6946 times.
✓ Branch 1 taken 27914 times.
✓ Branch 2 taken 82315 times.
✓ Branch 3 taken 22398 times.
✗ Branch 4 not taken.
139573 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 82315 case VSYNC_VFR:
2381
2/2
✓ Branch 0 taken 99 times.
✓ Branch 1 taken 82216 times.
82315 if (delta <= -0.6)
2382 99 *nb_frames = 0;
2383
2/2
✓ Branch 0 taken 64878 times.
✓ Branch 1 taken 17338 times.
82216 else if (delta > 0.6)
2384 64878 ofp->next_pts = llrint(sync_ipts);
2385 82315 frame->duration = llrint(duration);
2386 82315 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 143318 finish:
2399 143318 memmove(fps->frames_prev_hist + 1,
2400 143318 fps->frames_prev_hist,
2401 sizeof(fps->frames_prev_hist[0]) * (FF_ARRAY_ELEMS(fps->frames_prev_hist) - 1));
2402 143318 fps->frames_prev_hist[0] = *nb_frames_prev;
2403
2404
4/4
✓ Branch 0 taken 143315 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 474 times.
✓ Branch 3 taken 142841 times.
143318 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 143315 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 269 times.
✓ Branch 5 taken 143049 times.
143318 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 4219 times.
✓ Branch 1 taken 139099 times.
✓ Branch 2 taken 474 times.
✓ Branch 3 taken 3745 times.
143318 fps->last_dropped = *nb_frames == *nb_frames_prev && frame;
2428
4/4
✓ Branch 0 taken 474 times.
✓ Branch 1 taken 142844 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 467 times.
143318 fps->dropped_keyframe |= fps->last_dropped && (frame->flags & AV_FRAME_FLAG_KEY);
2429 }
2430
2431 5047 static int close_output(OutputFilterPriv *ofp, FilterGraphThread *fgt)
2432 {
2433 5047 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 5044 times.
5047 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 5047 fgt->eof_out[ofp->ofilter.index] = 1;
2481
2482 5047 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, NULL);
2483
2/2
✓ Branch 0 taken 4919 times.
✓ Branch 1 taken 128 times.
5047 return (ret == AVERROR_EOF) ? 0 : ret;
2484 }
2485
2486 397352 static int fg_output_frame(OutputFilterPriv *ofp, FilterGraphThread *fgt,
2487 AVFrame *frame)
2488 {
2489 397352 FilterGraphPriv *fgp = fgp_from_fg(ofp->ofilter.graph);
2490 397352 AVFrame *frame_prev = ofp->fps.last_frame;
2491 397352 enum AVMediaType type = ofp->ofilter.type;
2492
2493 397352 int64_t nb_frames = !!frame, nb_frames_prev = 0;
2494
2495
5/6
✓ Branch 0 taken 143318 times.
✓ Branch 1 taken 254034 times.
✓ Branch 2 taken 3745 times.
✓ Branch 3 taken 139573 times.
✓ Branch 4 taken 3745 times.
✗ Branch 5 not taken.
397352 if (type == AVMEDIA_TYPE_VIDEO && (frame || fgt->got_frame))
2496 143318 video_sync_process(ofp, frame, &nb_frames, &nb_frames_prev);
2497
2498
2/2
✓ Branch 0 taken 392263 times.
✓ Branch 1 taken 394291 times.
786554 for (int64_t i = 0; i < nb_frames; i++) {
2499 AVFrame *frame_out;
2500 int ret;
2501
2502
2/2
✓ Branch 0 taken 139531 times.
✓ Branch 1 taken 252732 times.
392263 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 139462 times.
139600 frame_prev : frame;
2505
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 139531 times.
139531 if (!frame_in)
2506 break;
2507
2508 139531 frame_out = fgp->frame_enc;
2509 139531 ret = av_frame_ref(frame_out, frame_in);
2510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 139531 times.
139531 if (ret < 0)
2511 return ret;
2512
2513 139531 frame_out->pts = ofp->next_pts;
2514
2515
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 139524 times.
139531 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 392263 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, frame_out);
2536
2/2
✓ Branch 0 taken 3061 times.
✓ Branch 1 taken 389202 times.
392263 if (ret < 0) {
2537 3061 av_frame_unref(frame_out);
2538
2539
1/2
✓ Branch 0 taken 3061 times.
✗ Branch 1 not taken.
3061 if (!fgt->eof_out[ofp->ofilter.index]) {
2540 3061 fgt->eof_out[ofp->ofilter.index] = 1;
2541 3061 fgp->nb_outputs_done++;
2542 }
2543
2544
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3061 times.
3061 return ret == AVERROR_EOF ? 0 : ret;
2545 }
2546
2547
2/2
✓ Branch 0 taken 136501 times.
✓ Branch 1 taken 252701 times.
389202 if (type == AVMEDIA_TYPE_VIDEO) {
2548 136501 ofp->fps.frame_number++;
2549 136501 ofp->next_pts++;
2550
2551
3/4
✓ Branch 0 taken 136069 times.
✓ Branch 1 taken 432 times.
✓ Branch 2 taken 136069 times.
✗ Branch 3 not taken.
136501 if (i == nb_frames_prev && frame)
2552 136069 frame->flags &= ~AV_FRAME_FLAG_KEY;
2553 }
2554
2555 389202 fgt->got_frame = 1;
2556 }
2557
2558
4/4
✓ Branch 0 taken 389244 times.
✓ Branch 1 taken 5047 times.
✓ Branch 2 taken 136543 times.
✓ Branch 3 taken 252701 times.
394291 if (frame && frame_prev) {
2559 136543 av_frame_unref(frame_prev);
2560 136543 av_frame_move_ref(frame_prev, frame);
2561 }
2562
2563
2/2
✓ Branch 0 taken 5047 times.
✓ Branch 1 taken 389244 times.
394291 if (!frame)
2564 5047 return close_output(ofp, fgt);
2565
2566 389244 return 0;
2567 }
2568
2569 831279 static int fg_output_step(OutputFilterPriv *ofp, FilterGraphThread *fgt,
2570 AVFrame *frame)
2571 {
2572 831279 FilterGraphPriv *fgp = fgp_from_fg(ofp->ofilter.graph);
2573 831279 AVFilterContext *filter = ofp->ofilter.filter;
2574 FrameData *fd;
2575 int ret;
2576
2577 831279 ret = av_buffersink_get_frame_flags(filter, frame,
2578 AV_BUFFERSINK_FLAG_NO_REQUEST);
2579
4/4
✓ Branch 0 taken 4151 times.
✓ Branch 1 taken 827128 times.
✓ Branch 2 taken 3495 times.
✓ Branch 3 taken 656 times.
831279 if (ret == AVERROR_EOF && !fgt->eof_out[ofp->ofilter.index]) {
2580 3495 ret = fg_output_frame(ofp, fgt, NULL);
2581
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3495 times.
3495 return (ret < 0) ? ret : 1;
2582
4/4
✓ Branch 0 taken 392963 times.
✓ Branch 1 taken 434821 times.
✓ Branch 2 taken 656 times.
✓ Branch 3 taken 392307 times.
827784 } else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2583 435477 return 1;
2584
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 392307 times.
392307 } 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 392305 times.
392307 if (fgt->eof_out[ofp->ofilter.index]) {
2592 2 av_frame_unref(frame);
2593 2 return 0;
2594 }
2595
2596 392305 frame->time_base = av_buffersink_get_time_base(filter);
2597
2598
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 392305 times.
392305 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 8105 times.
✓ Branch 1 taken 384200 times.
392305 if (!ofp->tb_out_locked) {
2605 8105 ret = choose_out_timebase(ofp, frame);
2606
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8105 times.
8105 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 392305 fd = frame_data(frame);
2614
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 392305 times.
392305 if (!fd) {
2615 av_frame_unref(frame);
2616 return AVERROR(ENOMEM);
2617 }
2618
2619 392305 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 281493 times.
✓ Branch 1 taken 110812 times.
392305 if (!fgp->is_meta)
2624 281493 fd->bits_per_raw_sample = 0;
2625
2626
2/2
✓ Branch 0 taken 139573 times.
✓ Branch 1 taken 252732 times.
392305 if (ofp->ofilter.type == AVMEDIA_TYPE_VIDEO) {
2627
2/2
✓ Branch 0 taken 2417 times.
✓ Branch 1 taken 137156 times.
139573 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 139573 fd->frame_rate_filter = ofp->fps.framerate;
2634 }
2635
2636 392305 ret = fg_output_frame(ofp, fgt, frame);
2637 392305 av_frame_unref(frame);
2638
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 392305 times.
392305 if (ret < 0)
2639 return ret;
2640
2641 392305 return 0;
2642 }
2643
2644 /* retrieve all frames available at filtergraph outputs
2645 * and send them to consumers */
2646 400889 static int read_frames(FilterGraph *fg, FilterGraphThread *fgt,
2647 AVFrame *frame)
2648 {
2649 400889 FilterGraphPriv *fgp = fgp_from_fg(fg);
2650 400889 int did_step = 0;
2651
2652 // graph not configured, just select the input to request
2653
2/2
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 400619 times.
400889 if (!fgt->graph) {
2654
1/2
✓ Branch 0 taken 644 times.
✗ Branch 1 not taken.
644 for (int i = 0; i < fg->nb_inputs; i++) {
2655 644 InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[i]);
2656
3/4
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 374 times.
✓ Branch 2 taken 270 times.
✗ Branch 3 not taken.
644 if (ifp->format < 0 && !fgt->eof_in[i]) {
2657 270 fgt->next_in = i;
2658 270 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 427957 times.
✓ Branch 1 taken 3061 times.
431018 while (fgp->nb_outputs_done < fg->nb_outputs) {
2670 int ret;
2671
2672 /* Reap all buffers present in the buffer sinks */
2673
2/2
✓ Branch 0 taken 438972 times.
✓ Branch 1 taken 427957 times.
866929 for (int i = 0; i < fg->nb_outputs; i++) {
2674 438972 OutputFilterPriv *ofp = ofp_from_ofilter(fg->outputs[i]);
2675
2676 438972 ret = 0;
2677
2/2
✓ Branch 0 taken 831279 times.
✓ Branch 1 taken 438972 times.
1270251 while (!ret) {
2678 831279 ret = fg_output_step(ofp, fgt, frame);
2679
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 831279 times.
831279 if (ret < 0)
2680 return ret;
2681 }
2682 }
2683
2684 // return after one iteration, so that scheduler can rate-control us
2685
4/4
✓ Branch 0 taken 30397 times.
✓ Branch 1 taken 397560 times.
✓ Branch 2 taken 28402 times.
✓ Branch 3 taken 1995 times.
427957 if (did_step && fgp->have_sources)
2686 28402 return 0;
2687
2688 399555 ret = avfilter_graph_request_oldest(fgt->graph);
2689
2/2
✓ Branch 0 taken 364245 times.
✓ Branch 1 taken 35310 times.
399555 if (ret == AVERROR(EAGAIN)) {
2690 364245 fgt->next_in = choose_input(fg, fgt);
2691 364245 return 0;
2692
2/2
✓ Branch 0 taken 4911 times.
✓ Branch 1 taken 30399 times.
35310 } else if (ret < 0) {
2693
1/2
✓ Branch 0 taken 4911 times.
✗ Branch 1 not taken.
4911 if (ret == AVERROR_EOF)
2694 4911 av_log(fg, AV_LOG_VERBOSE, "Filtergraph returned EOF, finishing\n");
2695 else
2696 av_log(fg, AV_LOG_ERROR,
2697 "Error requesting a frame from the filtergraph: %s\n",
2698 av_err2str(ret));
2699 4911 return ret;
2700 }
2701 30399 fgt->next_in = fg->nb_inputs;
2702
2703 30399 did_step = 1;
2704 }
2705
2706 3061 return AVERROR_EOF;
2707 }
2708
2709 948 static void sub2video_heartbeat(InputFilter *ifilter, int64_t pts, AVRational tb)
2710 {
2711 948 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2712 int64_t pts2;
2713
2714 /* subtitles seem to be usually muxed ahead of other streams;
2715 if not, subtracting a larger time here is necessary */
2716 948 pts2 = av_rescale_q(pts, tb, ifp->time_base) - 1;
2717
2718 /* do not send the heartbeat frame if the subtitle is already ahead */
2719
2/2
✓ Branch 0 taken 769 times.
✓ Branch 1 taken 179 times.
948 if (pts2 <= ifp->sub2video.last_pts)
2720 769 return;
2721
2722
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)
2723 /* if we have hit the end of the current displayed subpicture,
2724 or if we need to initialize the system, update the
2725 overlayed subpicture and its start/end times */
2726 88 sub2video_update(ifp, pts2 + 1, NULL);
2727 else
2728 91 sub2video_push_ref(ifp, pts2);
2729 }
2730
2731 1079 static int sub2video_frame(InputFilter *ifilter, AVFrame *frame, int buffer)
2732 {
2733 1079 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2734 int ret;
2735
2736
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1040 times.
1079 if (buffer) {
2737 AVFrame *tmp;
2738
2739
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (!frame)
2740 return 0;
2741
2742 39 tmp = av_frame_alloc();
2743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (!tmp)
2744 return AVERROR(ENOMEM);
2745
2746 39 av_frame_move_ref(tmp, frame);
2747
2748 39 ret = av_fifo_write(ifp->frame_queue, &tmp, 1);
2749
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (ret < 0) {
2750 av_frame_free(&tmp);
2751 return ret;
2752 }
2753
2754 39 return 0;
2755 }
2756
2757 // heartbeat frame
2758
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]) {
2759 948 sub2video_heartbeat(ifilter, frame->pts, frame->time_base);
2760 948 return 0;
2761 }
2762
2763
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 88 times.
92 if (!frame) {
2764
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (ifp->sub2video.end_pts < INT64_MAX)
2765 4 sub2video_update(ifp, INT64_MAX, NULL);
2766
2767 4 return av_buffersrc_add_frame(ifilter->filter, NULL);
2768 }
2769
2770
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 ifp->width = frame->width ? frame->width : ifp->width;
2771
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 ifp->height = frame->height ? frame->height : ifp->height;
2772
2773 88 sub2video_update(ifp, INT64_MIN, (const AVSubtitle*)frame->buf[0]->data);
2774
2775 88 return 0;
2776 }
2777
2778 3297 static int send_eof(FilterGraphThread *fgt, InputFilter *ifilter,
2779 int64_t pts, AVRational tb)
2780 {
2781 3297 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2782 int ret;
2783
2784
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3297 times.
3297 if (fgt->eof_in[ifilter->index])
2785 return 0;
2786
2787 3297 fgt->eof_in[ifilter->index] = 1;
2788
2789
2/2
✓ Branch 0 taken 3289 times.
✓ Branch 1 taken 8 times.
3297 if (ifilter->filter) {
2790 3289 pts = av_rescale_q_rnd(pts, tb, ifp->time_base,
2791 AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
2792
2793 3289 ret = av_buffersrc_close(ifilter->filter, pts, AV_BUFFERSRC_FLAG_PUSH);
2794
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3289 times.
3289 if (ret < 0)
2795 return ret;
2796 } else {
2797
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5 times.
8 if (ifp->format < 0) {
2798 // the filtergraph was never configured, use the fallback parameters
2799 3 ifp->format = ifp->opts.fallback->format;
2800 3 ifp->sample_rate = ifp->opts.fallback->sample_rate;
2801 3 ifp->width = ifp->opts.fallback->width;
2802 3 ifp->height = ifp->opts.fallback->height;
2803 3 ifp->sample_aspect_ratio = ifp->opts.fallback->sample_aspect_ratio;
2804 3 ifp->color_space = ifp->opts.fallback->colorspace;
2805 3 ifp->color_range = ifp->opts.fallback->color_range;
2806 3 ifp->time_base = ifp->opts.fallback->time_base;
2807
2808 3 ret = av_channel_layout_copy(&ifp->ch_layout,
2809 3 &ifp->opts.fallback->ch_layout);
2810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0)
2811 return ret;
2812
2813 3 av_frame_side_data_free(&ifp->side_data, &ifp->nb_side_data);
2814 3 ret = clone_side_data(&ifp->side_data, &ifp->nb_side_data,
2815 3 ifp->opts.fallback->side_data,
2816 3 ifp->opts.fallback->nb_side_data, 0);
2817
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0)
2818 return ret;
2819
2820
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if (ifilter_has_all_input_formats(ifilter->graph)) {
2821 3 ret = configure_filtergraph(ifilter->graph, fgt);
2822
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0) {
2823 av_log(ifilter->graph, AV_LOG_ERROR, "Error initializing filters!\n");
2824 return ret;
2825 }
2826 }
2827 }
2828
2829
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (ifp->format < 0) {
2830 av_log(ifilter->graph, AV_LOG_ERROR,
2831 "Cannot determine format of input %s after EOF\n",
2832 ifp->opts.name);
2833 return AVERROR_INVALIDDATA;
2834 }
2835 }
2836
2837 3297 return 0;
2838 }
2839
2840 enum ReinitReason {
2841 VIDEO_CHANGED = (1 << 0),
2842 AUDIO_CHANGED = (1 << 1),
2843 MATRIX_CHANGED = (1 << 2),
2844 DOWNMIX_CHANGED = (1 << 3),
2845 HWACCEL_CHANGED = (1 << 4)
2846 };
2847
2848 136 static const char *unknown_if_null(const char *str)
2849 {
2850
1/2
✓ Branch 0 taken 136 times.
✗ Branch 1 not taken.
136 return str ? str : "unknown";
2851 }
2852
2853 366966 static int send_frame(FilterGraph *fg, FilterGraphThread *fgt,
2854 InputFilter *ifilter, AVFrame *frame)
2855 {
2856 366966 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2857 FrameData *fd;
2858 AVFrameSideData *sd;
2859 366966 int need_reinit = 0, ret;
2860
2861 /* determine if the parameters for this input changed */
2862
2/3
✓ Branch 0 taken 251979 times.
✓ Branch 1 taken 114987 times.
✗ Branch 2 not taken.
366966 switch (ifilter->type) {
2863 251979 case AVMEDIA_TYPE_AUDIO:
2864
2/2
✓ Branch 0 taken 250718 times.
✓ Branch 1 taken 1261 times.
251979 if (ifp->format != frame->format ||
2865
3/4
✓ Branch 0 taken 250718 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 250717 times.
501436 ifp->sample_rate != frame->sample_rate ||
2866 250718 av_channel_layout_compare(&ifp->ch_layout, &frame->ch_layout))
2867 1262 need_reinit |= AUDIO_CHANGED;
2868 251979 break;
2869 114987 case AVMEDIA_TYPE_VIDEO:
2870
2/2
✓ Branch 0 taken 109319 times.
✓ Branch 1 taken 5668 times.
114987 if (ifp->format != frame->format ||
2871
2/2
✓ Branch 0 taken 109291 times.
✓ Branch 1 taken 28 times.
109319 ifp->width != frame->width ||
2872
2/2
✓ Branch 0 taken 109285 times.
✓ Branch 1 taken 6 times.
109291 ifp->height != frame->height ||
2873
1/2
✓ Branch 0 taken 109285 times.
✗ Branch 1 not taken.
109285 ifp->color_space != frame->colorspace ||
2874
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 109285 times.
109285 ifp->color_range != frame->color_range)
2875 5702 need_reinit |= VIDEO_CHANGED;
2876 114987 break;
2877 }
2878
2879
2/2
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 366858 times.
366966 if (sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX)) {
2880
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 4 times.
108 if (!ifp->displaymatrix_present ||
2881
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 104 times.
104 memcmp(sd->data, ifp->displaymatrix, sizeof(ifp->displaymatrix)))
2882 4 need_reinit |= MATRIX_CHANGED;
2883
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 366858 times.
366858 } else if (ifp->displaymatrix_present)
2884 need_reinit |= MATRIX_CHANGED;
2885
2886
2/2
✓ Branch 1 taken 419 times.
✓ Branch 2 taken 366547 times.
366966 if (sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DOWNMIX_INFO)) {
2887
2/2
✓ Branch 0 taken 414 times.
✓ Branch 1 taken 5 times.
419 if (!ifp->downmixinfo_present ||
2888
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 414 times.
414 memcmp(sd->data, &ifp->downmixinfo, sizeof(ifp->downmixinfo)))
2889 5 need_reinit |= DOWNMIX_CHANGED;
2890
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 366547 times.
366547 } else if (ifp->downmixinfo_present)
2891 need_reinit |= DOWNMIX_CHANGED;
2892
2893
5/6
✓ Branch 0 taken 6964 times.
✓ Branch 1 taken 360002 times.
✓ Branch 2 taken 47 times.
✓ Branch 3 taken 6917 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 47 times.
366966 if (need_reinit && fgt->graph && (ifp->opts.flags & IFILTER_FLAG_DROPCHANGED)) {
2894 ifp->nb_dropped++;
2895 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);
2896 av_frame_unref(frame);
2897 return 0;
2898 }
2899
2900
4/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 366916 times.
✓ Branch 2 taken 49 times.
✓ Branch 3 taken 1 times.
366966 if (!(ifp->opts.flags & IFILTER_FLAG_REINIT) && fgt->graph)
2901 49 need_reinit = 0;
2902
2903
1/2
✓ Branch 0 taken 366966 times.
✗ Branch 1 not taken.
366966 if (!!ifp->hw_frames_ctx != !!frame->hw_frames_ctx ||
2904
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 366966 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
366966 (ifp->hw_frames_ctx && ifp->hw_frames_ctx->data != frame->hw_frames_ctx->data))
2905 need_reinit |= HWACCEL_CHANGED;
2906
2907
2/2
✓ Branch 0 taken 6964 times.
✓ Branch 1 taken 360002 times.
366966 if (need_reinit) {
2908 6964 ret = ifilter_parameters_from_frame(ifilter, frame);
2909
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6964 times.
6964 if (ret < 0)
2910 return ret;
2911 }
2912
2913 /* (re)init the graph if possible, otherwise buffer the frame and return */
2914
4/4
✓ Branch 0 taken 360002 times.
✓ Branch 1 taken 6964 times.
✓ Branch 2 taken 143 times.
✓ Branch 3 taken 359859 times.
366966 if (need_reinit || !fgt->graph) {
2915 7107 AVFrame *tmp = av_frame_alloc();
2916
2917
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7107 times.
7107 if (!tmp)
2918 227 return AVERROR(ENOMEM);
2919
2920
2/2
✓ Branch 1 taken 226 times.
✓ Branch 2 taken 6881 times.
7107 if (!ifilter_has_all_input_formats(fg)) {
2921 226 av_frame_move_ref(tmp, frame);
2922
2923 226 ret = av_fifo_write(ifp->frame_queue, &tmp, 1);
2924
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 226 times.
226 if (ret < 0)
2925 av_frame_free(&tmp);
2926
2927 226 return ret;
2928 }
2929
2930
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 6834 times.
6881 ret = fgt->graph ? read_frames(fg, fgt, tmp) : 0;
2931 6881 av_frame_free(&tmp);
2932
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6880 times.
6881 if (ret < 0)
2933 1 return ret;
2934
2935
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 6834 times.
6880 if (fgt->graph) {
2936 AVBPrint reason;
2937 46 av_bprint_init(&reason, 0, AV_BPRINT_SIZE_AUTOMATIC);
2938
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 45 times.
46 if (need_reinit & AUDIO_CHANGED) {
2939 1 const char *sample_format_name = av_get_sample_fmt_name(frame->format);
2940 1 av_bprintf(&reason, "audio parameters changed to %d Hz, ", frame->sample_rate);
2941 1 av_channel_layout_describe_bprint(&frame->ch_layout, &reason);
2942 1 av_bprintf(&reason, ", %s, ", unknown_if_null(sample_format_name));
2943 }
2944
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 1 times.
46 if (need_reinit & VIDEO_CHANGED) {
2945 45 const char *pixel_format_name = av_get_pix_fmt_name(frame->format);
2946 45 const char *color_space_name = av_color_space_name(frame->colorspace);
2947 45 const char *color_range_name = av_color_range_name(frame->color_range);
2948 45 av_bprintf(&reason, "video parameters changed to %s(%s, %s), %dx%d, ",
2949 unknown_if_null(pixel_format_name), unknown_if_null(color_range_name),
2950 unknown_if_null(color_space_name), frame->width, frame->height);
2951 }
2952
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (need_reinit & MATRIX_CHANGED)
2953 av_bprintf(&reason, "display matrix changed, ");
2954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (need_reinit & DOWNMIX_CHANGED)
2955 av_bprintf(&reason, "downmix medatata changed, ");
2956
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (need_reinit & HWACCEL_CHANGED)
2957 av_bprintf(&reason, "hwaccel changed, ");
2958
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 if (reason.len > 1)
2959 46 reason.str[reason.len - 2] = '\0'; // remove last comma
2960
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);
2961 }
2962
2963 6880 ret = configure_filtergraph(fg, fgt);
2964
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6880 times.
6880 if (ret < 0) {
2965 av_log(fg, AV_LOG_ERROR, "Error reinitializing filters!\n");
2966 return ret;
2967 }
2968 }
2969
2970 366739 frame->pts = av_rescale_q(frame->pts, frame->time_base, ifp->time_base);
2971 366739 frame->duration = av_rescale_q(frame->duration, frame->time_base, ifp->time_base);
2972 366739 frame->time_base = ifp->time_base;
2973
2974
2/2
✓ Branch 0 taken 114845 times.
✓ Branch 1 taken 251894 times.
366739 if (ifp->displaymatrix_applied)
2975 114845 av_frame_remove_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX);
2976
2977 366739 fd = frame_data(frame);
2978
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 366739 times.
366739 if (!fd)
2979 return AVERROR(ENOMEM);
2980 366739 fd->wallclock[LATENCY_PROBE_FILTER_PRE] = av_gettime_relative();
2981
2982 366739 ret = av_buffersrc_add_frame_flags(ifilter->filter, frame,
2983 AV_BUFFERSRC_FLAG_PUSH);
2984
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 366738 times.
366739 if (ret < 0) {
2985 1 av_frame_unref(frame);
2986
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret != AVERROR_EOF)
2987 av_log(fg, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret));
2988 1 return ret;
2989 }
2990
2991 366738 return 0;
2992 }
2993
2994 7978 static void fg_thread_set_name(const FilterGraph *fg)
2995 {
2996 char name[16];
2997
2/2
✓ Branch 1 taken 6774 times.
✓ Branch 2 taken 1204 times.
7978 if (filtergraph_is_simple(fg)) {
2998 6774 OutputFilterPriv *ofp = ofp_from_ofilter(fg->outputs[0]);
2999 13548 snprintf(name, sizeof(name), "%cf%s",
3000 6774 av_get_media_type_string(ofp->ofilter.type)[0],
3001 ofp->ofilter.output_name);
3002 } else {
3003 1204 snprintf(name, sizeof(name), "fc%d", fg->index);
3004 }
3005
3006 7978 ff_thread_setname(name);
3007 7978 }
3008
3009 7978 static void fg_thread_uninit(FilterGraphThread *fgt)
3010 {
3011
1/2
✓ Branch 0 taken 7978 times.
✗ Branch 1 not taken.
7978 if (fgt->frame_queue_out) {
3012 AVFrame *frame;
3013
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7978 times.
7978 while (av_fifo_read(fgt->frame_queue_out, &frame, 1) >= 0)
3014 av_frame_free(&frame);
3015 7978 av_fifo_freep2(&fgt->frame_queue_out);
3016 }
3017
3018 7978 av_frame_free(&fgt->frame);
3019 7978 av_freep(&fgt->eof_in);
3020 7978 av_freep(&fgt->eof_out);
3021
3022 7978 avfilter_graph_free(&fgt->graph);
3023
3024 7978 memset(fgt, 0, sizeof(*fgt));
3025 7978 }
3026
3027 7978 static int fg_thread_init(FilterGraphThread *fgt, const FilterGraph *fg)
3028 {
3029 7978 memset(fgt, 0, sizeof(*fgt));
3030
3031 7978 fgt->frame = av_frame_alloc();
3032
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7978 times.
7978 if (!fgt->frame)
3033 goto fail;
3034
3035 7978 fgt->eof_in = av_calloc(fg->nb_inputs, sizeof(*fgt->eof_in));
3036
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7978 times.
7978 if (!fgt->eof_in)
3037 goto fail;
3038
3039 7978 fgt->eof_out = av_calloc(fg->nb_outputs, sizeof(*fgt->eof_out));
3040
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7978 times.
7978 if (!fgt->eof_out)
3041 goto fail;
3042
3043 7978 fgt->frame_queue_out = av_fifo_alloc2(1, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
3044
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7978 times.
7978 if (!fgt->frame_queue_out)
3045 goto fail;
3046
3047 7978 return 0;
3048
3049 fail:
3050 fg_thread_uninit(fgt);
3051 return AVERROR(ENOMEM);
3052 }
3053
3054 7978 static int filter_thread(void *arg)
3055 {
3056 7978 FilterGraphPriv *fgp = arg;
3057 7978 FilterGraph *fg = &fgp->fg;
3058
3059 FilterGraphThread fgt;
3060 7978 int ret = 0, input_status = 0;
3061
3062 7978 ret = fg_thread_init(&fgt, fg);
3063
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7978 times.
7978 if (ret < 0)
3064 goto finish;
3065
3066 7978 fg_thread_set_name(fg);
3067
3068 // if we have all input parameters the graph can now be configured
3069
2/2
✓ Branch 1 taken 6837 times.
✓ Branch 2 taken 1141 times.
7978 if (ifilter_has_all_input_formats(fg)) {
3070 1141 ret = configure_filtergraph(fg, &fgt);
3071
1/2
✓ Branch 0 taken 1141 times.
✗ Branch 1 not taken.
1141 if (ret < 0) {
3072 av_log(fg, AV_LOG_ERROR, "Error configuring filter graph: %s\n",
3073 av_err2str(ret));
3074 goto finish;
3075 }
3076 }
3077
3078 392873 while (1) {
3079 InputFilter *ifilter;
3080 400851 InputFilterPriv *ifp = NULL;
3081 enum FrameOpaque o;
3082 400851 unsigned input_idx = fgt.next_in;
3083
3084 400851 input_status = sch_filter_receive(fgp->sch, fgp->sch_idx,
3085 400851 &input_idx, fgt.frame);
3086
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 400844 times.
400851 if (input_status == AVERROR_EOF) {
3087 7 av_log(fg, AV_LOG_VERBOSE, "Filtering thread received EOF\n");
3088 7 break;
3089
2/2
✓ Branch 0 taken 29541 times.
✓ Branch 1 taken 371303 times.
400844 } else if (input_status == AVERROR(EAGAIN)) {
3090 // should only happen when we didn't request any input
3091
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29541 times.
29541 av_assert0(input_idx == fg->nb_inputs);
3092 29541 goto read_frames;
3093 }
3094
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 371303 times.
371303 av_assert0(input_status >= 0);
3095
3096 371303 o = (intptr_t)fgt.frame->opaque;
3097
3098 371303 o = (intptr_t)fgt.frame->opaque;
3099
3100 // message on the control stream
3101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 371303 times.
371303 if (input_idx == fg->nb_inputs) {
3102 FilterCommand *fc;
3103
3104 av_assert0(o == FRAME_OPAQUE_SEND_COMMAND && fgt.frame->buf[0]);
3105
3106 fc = (FilterCommand*)fgt.frame->buf[0]->data;
3107 send_command(fg, fgt.graph, fc->time, fc->target, fc->command, fc->arg,
3108 fc->all_filters);
3109 av_frame_unref(fgt.frame);
3110 2 continue;
3111 }
3112
3113 // we received an input frame or EOF
3114 371303 ifilter = fg->inputs[input_idx];
3115 371303 ifp = ifp_from_ifilter(ifilter);
3116
3117
2/2
✓ Branch 0 taken 1040 times.
✓ Branch 1 taken 370263 times.
371303 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
3118
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;
3119
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,
3120
2/2
✓ Branch 0 taken 952 times.
✓ Branch 1 taken 88 times.
1040 !fgt.graph);
3121
2/2
✓ Branch 0 taken 366966 times.
✓ Branch 1 taken 3297 times.
370263 } else if (fgt.frame->buf[0]) {
3122 366966 ret = send_frame(fg, &fgt, ifilter, fgt.frame);
3123 } else {
3124 av_assert1(o == FRAME_OPAQUE_EOF);
3125 3297 ret = send_eof(&fgt, ifilter, fgt.frame->pts, fgt.frame->time_base);
3126 }
3127 371303 av_frame_unref(fgt.frame);
3128
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 371301 times.
371303 if (ret == AVERROR_EOF) {
3129 2 av_log(fg, AV_LOG_VERBOSE, "Input %u no longer accepts new data\n",
3130 input_idx);
3131 2 sch_filter_receive_finish(fgp->sch, fgp->sch_idx, input_idx);
3132 2 continue;
3133 }
3134
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 371301 times.
371301 if (ret < 0)
3135 goto finish;
3136
3137 371301 read_frames:
3138 // retrieve all newly avalable frames
3139 400842 ret = read_frames(fg, &fgt, fgt.frame);
3140
2/2
✓ Branch 0 taken 7971 times.
✓ Branch 1 taken 392871 times.
400842 if (ret == AVERROR_EOF) {
3141 7971 av_log(fg, AV_LOG_VERBOSE, "All consumers returned EOF\n");
3142
3/4
✓ Branch 0 taken 6832 times.
✓ Branch 1 taken 1139 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6832 times.
7971 if (ifp && ifp->opts.flags & IFILTER_FLAG_DROPCHANGED)
3143 av_log(fg, AV_LOG_INFO, "Total changed input frames dropped : %"PRId64"\n", ifp->nb_dropped);
3144 7971 break;
3145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 392871 times.
392871 } else if (ret < 0) {
3146 av_log(fg, AV_LOG_ERROR, "Error sending frames to consumers: %s\n",
3147 av_err2str(ret));
3148 goto finish;
3149 }
3150 }
3151
3152
2/2
✓ Branch 0 taken 8108 times.
✓ Branch 1 taken 7978 times.
16086 for (unsigned i = 0; i < fg->nb_outputs; i++) {
3153 8108 OutputFilterPriv *ofp = ofp_from_ofilter(fg->outputs[i]);
3154
3155
3/4
✓ Branch 0 taken 1552 times.
✓ Branch 1 taken 6556 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1552 times.
8108 if (fgt.eof_out[i] || !fgt.graph)
3156 6556 continue;
3157
3158 1552 ret = fg_output_frame(ofp, &fgt, NULL);
3159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1552 times.
1552 if (ret < 0)
3160 goto finish;
3161 }
3162
3163 7978 finish:
3164
3165
2/4
✓ Branch 0 taken 7978 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7978 times.
7978 if (print_graphs || print_graphs_file)
3166 print_filtergraph(fg, fgt.graph);
3167
3168 // EOF is normal termination
3169
2/2
✓ Branch 0 taken 6492 times.
✓ Branch 1 taken 1486 times.
7978 if (ret == AVERROR_EOF)
3170 6492 ret = 0;
3171
3172 7978 fg_thread_uninit(&fgt);
3173
3174 7978 return ret;
3175 }
3176
3177 void fg_send_command(FilterGraph *fg, double time, const char *target,
3178 const char *command, const char *arg, int all_filters)
3179 {
3180 FilterGraphPriv *fgp = fgp_from_fg(fg);
3181 AVBufferRef *buf;
3182 FilterCommand *fc;
3183
3184 fc = av_mallocz(sizeof(*fc));
3185 if (!fc)
3186 return;
3187
3188 buf = av_buffer_create((uint8_t*)fc, sizeof(*fc), filter_command_free, NULL, 0);
3189 if (!buf) {
3190 av_freep(&fc);
3191 return;
3192 }
3193
3194 fc->target = av_strdup(target);
3195 fc->command = av_strdup(command);
3196 fc->arg = av_strdup(arg);
3197 if (!fc->target || !fc->command || !fc->arg) {
3198 av_buffer_unref(&buf);
3199 return;
3200 }
3201
3202 fc->time = time;
3203 fc->all_filters = all_filters;
3204
3205 fgp->frame->buf[0] = buf;
3206 fgp->frame->opaque = (void*)(intptr_t)FRAME_OPAQUE_SEND_COMMAND;
3207
3208 sch_filter_command(fgp->sch, fgp->sch_idx, fgp->frame);
3209 }
3210