FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_filter.c
Date: 2025-10-30 16:00:47
Exec Total Coverage
Lines: 1409 1844 76.4%
Functions: 69 73 94.5%
Branches: 832 1261 66.0%

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