FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_filter.c
Date: 2024-04-24 18:52:15
Exec Total Coverage
Lines: 1217 1623 75.0%
Functions: 63 69 91.3%
Branches: 699 1073 65.1%

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