FFmpeg
Loading...
Searching...
No Matches
ffmpeg_filter.c
Go to the documentation of this file.
1/*
2 * ffmpeg filter configuration
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <stdint.h>
22
23#include "ffmpeg.h"
24#include "graph/graphprint.h"
25
29
31#include "libavutil/avassert.h"
32#include "libavutil/avstring.h"
33#include "libavutil/bprint.h"
36#include "libavutil/mem.h"
37#include "libavutil/opt.h"
38#include "libavutil/pixdesc.h"
39#include "libavutil/pixfmt.h"
40#include "libavutil/samplefmt.h"
41#include "libavutil/time.h"
42#include "libavutil/timestamp.h"
43
44typedef struct FilterGraphPriv {
46
47 // name used for logging
48 char log_name[32];
49
51 // true when the filtergraph contains only meta filters
52 // that do not modify the frame data
55
57
59
60 // frame for temporarily holding output from the filtergraph
62 // frame for sending output to the encoder
64
66 unsigned sch_idx;
68
70{
71 return (FilterGraphPriv*)fg;
72}
73
75{
76 return (const FilterGraphPriv*)fg;
77}
78
79// data that is local to the filter thread and not visible outside of it
80typedef struct FilterGraphThread {
82
84
85 // Temporary buffer for output frames, since on filtergraph reset
86 // we cannot send them to encoders immediately.
87 // The output index is stored in frame opaque.
89
90 // index of the next input to request from the scheduler
91 unsigned next_in;
92 // set to 1 after at least one frame passed through this output
94
95 // EOF status of each input/output, as received by the thread
96 uint8_t *eof_in;
97 uint8_t *eof_out;
99
100typedef struct InputFilterPriv {
102
104
105 // used to hold submitted input
107
108 // For inputs bound to a filtergraph output
110
111 // source data type: AVMEDIA_TYPE_SUBTITLE for sub2video,
112 // same as type otherwise
114
115 int eof;
116 int bound;
118 uint64_t nb_dropped;
119
120 // parameters configured for this input
122
129
132
134
137
139
141
145
148
152
153 struct {
154 AVFrame *frame;
155
158
159 /// marks if sub2video_update should force an initialization
160 unsigned int initialize;
163
165{
166 return (InputFilterPriv*)ifilter;
167}
168
169typedef struct FPSConvContext {
171 /* number of frames emitted by the video-encoding sync code */
173 /* history of nb_frames_prev, i.e. the number of times the
174 * previous frame was duplicated by vsync code in recent
175 * do_video_out() calls */
177
178 uint64_t dup_warning;
179
182
184
190
195
196typedef struct OutputFilterPriv {
198
200 char log_name[32];
201
203
204 /* desired output stream properties */
213
214 unsigned crop_top;
215 unsigned crop_bottom;
216 unsigned crop_left;
217 unsigned crop_right;
218
221
222 // time base in which the output is sent to our downstream
223 // does not need to match the filtersink's timebase
225 // at least one frame with the above timebase was sent
226 // to our downstream, so it cannot change anymore
228
230
233
234 // those are only set if no format is specified and the encoder gives us multiple options
235 // They point directly to the relevant lists of the encoder.
236 union {
239 };
241 const int *sample_rates;
246
248
252 // offset for output timestamps, in AV_TIME_BASE_Q
256
259
260 unsigned flags;
262
264{
265 return (OutputFilterPriv*)ofilter;
266}
267
268typedef struct FilterCommand {
269 char *target;
270 char *command;
271 char *arg;
272
273 double time;
276
277static void filter_command_free(void *opaque, uint8_t *data)
278{
280
281 av_freep(&fc->target);
282 av_freep(&fc->command);
283 av_freep(&fc->arg);
284
285 av_free(data);
286}
287
289{
291 int ret;
292
294
295 frame->width = ifp->width;
296 frame->height = ifp->height;
297 frame->format = ifp->format;
298 frame->colorspace = ifp->color_space;
299 frame->color_range = ifp->color_range;
300 frame->alpha_mode = ifp->alpha_mode;
301 frame->chroma_location = ifp->chroma_location;
302
303 ret = av_frame_get_buffer(frame, 0);
304 if (ret < 0)
305 return ret;
306
307 memset(frame->data[0], 0, frame->height * frame->linesize[0]);
308
309 return 0;
310}
311
312static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h,
314{
315 uint32_t *pal, *dst2;
316 uint8_t *src, *src2;
317 int x, y;
318
319 if (r->type != SUBTITLE_BITMAP) {
320 av_log(NULL, AV_LOG_WARNING, "sub2video: non-bitmap subtitle\n");
321 return;
322 }
323 if (r->x < 0 || r->x + r->w > w || r->y < 0 || r->y + r->h > h) {
324 av_log(NULL, AV_LOG_WARNING, "sub2video: rectangle (%d %d %d %d) overflowing %d %d\n",
325 r->x, r->y, r->w, r->h, w, h
326 );
327 return;
328 }
329
330 dst += r->y * dst_linesize + r->x * 4;
331 src = r->data[0];
332 pal = (uint32_t *)r->data[1];
333 for (y = 0; y < r->h; y++) {
334 dst2 = (uint32_t *)dst;
335 src2 = src;
336 for (x = 0; x < r->w; x++)
337 *(dst2++) = pal[*(src2++)];
338 dst += dst_linesize;
339 src += r->linesize[0];
340 }
341}
342
344{
346 int ret;
347
348 av_assert1(frame->data[0]);
349 ifp->sub2video.last_pts = frame->pts = pts;
353 if (ret != AVERROR_EOF && ret < 0)
355 "Error while add the frame to buffer source(%s).\n",
356 av_err2str(ret));
357}
358
359static void sub2video_update(InputFilterPriv *ifp, int64_t heartbeat_pts,
360 const AVSubtitle *sub)
361{
363 uint8_t *dst;
364 int dst_linesize;
365 int num_rects;
366 int64_t pts, end_pts;
367
368 if (sub) {
369 pts = av_rescale_q(sub->pts + sub->start_display_time * 1000LL,
371 end_pts = av_rescale_q(sub->pts + sub->end_display_time * 1000LL,
373 num_rects = sub->num_rects;
374 } else {
375 /* If we are initializing the system, utilize current heartbeat
376 PTS as the start time, and show until the following subpicture
377 is received. Otherwise, utilize the previous subpicture's end time
378 as the fall-back value. */
379 pts = ifp->sub2video.initialize ?
380 heartbeat_pts : ifp->sub2video.end_pts;
381 end_pts = INT64_MAX;
382 num_rects = 0;
383 }
384 if (sub2video_get_blank_frame(ifp) < 0) {
386 "Impossible to get a blank canvas.\n");
387 return;
388 }
389 dst = frame->data [0];
390 dst_linesize = frame->linesize[0];
391 for (int i = 0; i < num_rects; i++)
392 sub2video_copy_rect(dst, dst_linesize, frame->width, frame->height, sub->rects[i]);
394 ifp->sub2video.end_pts = end_pts;
395 ifp->sub2video.initialize = 0;
396}
397
398/* Define a function for appending a list of allowed formats
399 * to an AVBPrint. If nonempty, the list will have a header. */
400#define DEF_CHOOSE_FORMAT(name, type, var, supported_list, none, printf_format, get_name) \
401static void choose_ ## name (OutputFilterPriv *ofp, AVBPrint *bprint) \
402{ \
403 if (ofp->var == none && !ofp->supported_list) \
404 return; \
405 av_bprintf(bprint, #name "="); \
406 if (ofp->var != none) { \
407 av_bprintf(bprint, printf_format, get_name(ofp->var)); \
408 } else { \
409 const type *p; \
410 \
411 for (p = ofp->supported_list; *p != none; p++) { \
412 av_bprintf(bprint, printf_format "|", get_name(*p)); \
413 } \
414 if (bprint->len > 0) \
415 bprint->str[--bprint->len] = '\0'; \
416 } \
417 av_bprint_chars(bprint, ':', 1); \
418}
419
422
425
427 "%d", )
428
429DEF_CHOOSE_FORMAT(color_spaces, enum AVColorSpace, color_space, color_spaces,
431
432DEF_CHOOSE_FORMAT(color_ranges, enum AVColorRange, color_range, color_ranges,
434
435DEF_CHOOSE_FORMAT(alpha_modes, enum AVAlphaMode, alpha_mode, alpha_modes,
437
438DEF_CHOOSE_FORMAT(chroma_locations, enum AVChromaLocation, chroma_location,
439 chroma_locations, AVCHROMA_LOC_UNSPECIFIED, "%s",
441
442static void choose_channel_layouts(OutputFilterPriv *ofp, AVBPrint *bprint)
443{
444 if (av_channel_layout_check(&ofp->ch_layout)) {
445 av_bprintf(bprint, "channel_layouts=");
446 av_channel_layout_describe_bprint(&ofp->ch_layout, bprint);
447 } else if (ofp->ch_layouts) {
448 const AVChannelLayout *p;
449
450 av_bprintf(bprint, "channel_layouts=");
451 for (p = ofp->ch_layouts; p->nb_channels; p++) {
452 av_channel_layout_describe_bprint(p, bprint);
453 av_bprintf(bprint, "|");
454 }
455 if (bprint->len > 0)
456 bprint->str[--bprint->len] = '\0';
457 } else
458 return;
459 av_bprint_chars(bprint, ':', 1);
460}
461
462static int read_binary(void *logctx, const char *path,
463 uint8_t **data, int *len)
464{
465 AVIOContext *io = NULL;
467 int ret;
468
469 *data = NULL;
470 *len = 0;
471
472 ret = avio_open2(&io, path, AVIO_FLAG_READ, &int_cb, NULL);
473 if (ret < 0) {
474 av_log(logctx, AV_LOG_ERROR, "Cannot open file '%s': %s\n",
475 path, av_err2str(ret));
476 return ret;
477 }
478
479 fsize = avio_size(io);
480 if (fsize < 0 || fsize > INT_MAX) {
481 av_log(logctx, AV_LOG_ERROR, "Cannot obtain size of file %s\n", path);
482 ret = AVERROR(EIO);
483 goto fail;
484 }
485
486 *data = av_malloc(fsize);
487 if (!*data) {
488 ret = AVERROR(ENOMEM);
489 goto fail;
490 }
491
492 ret = avio_read(io, *data, fsize);
493 if (ret != fsize) {
494 av_log(logctx, AV_LOG_ERROR, "Error reading file %s\n", path);
495 ret = ret < 0 ? ret : AVERROR(EIO);
496 goto fail;
497 }
498
499 *len = fsize;
500
501 ret = 0;
502fail:
503 avio_close(io);
504 if (ret < 0) {
505 av_freep(data);
506 *len = 0;
507 }
508 return ret;
509}
510
511static int filter_opt_apply(void *logctx, AVFilterContext *f,
512 const char *key, const char *val)
513{
514 const AVOption *o = NULL;
515 int ret;
516
518 if (ret >= 0)
519 return 0;
520
521 if (ret == AVERROR_OPTION_NOT_FOUND && key[0] == '/')
523 if (!o)
524 goto err_apply;
525
526 // key is a valid option name prefixed with '/'
527 // interpret value as a path from which to load the actual option value
528 key++;
529
530 if (o->type == AV_OPT_TYPE_BINARY) {
531 uint8_t *data;
532 int len;
533
534 ret = read_binary(logctx, val, &data, &len);
535 if (ret < 0)
536 goto err_load;
537
539 av_freep(&data);
540 } else {
542 if (!data) {
543 ret = AVERROR(EIO);
544 goto err_load;
545 }
546
548 av_freep(&data);
549 }
550 if (ret < 0)
551 goto err_apply;
552
553 return 0;
554
555err_apply:
556 av_log(logctx, AV_LOG_ERROR,
557 "Error applying option '%s' to filter '%s': %s\n",
558 key, f->filter->name, av_err2str(ret));
559 return ret;
560err_load:
561 av_log(logctx, AV_LOG_ERROR,
562 "Error loading value for option '%s' from file '%s'\n",
563 key, val);
564 return ret;
565}
566
567static int graph_opts_apply(void *logctx, AVFilterGraphSegment *seg)
568{
569 for (size_t i = 0; i < seg->nb_chains; i++) {
570 AVFilterChain *ch = seg->chains[i];
571
572 for (size_t j = 0; j < ch->nb_filters; j++) {
573 AVFilterParams *p = ch->filters[j];
574 const AVDictionaryEntry *e = NULL;
575
576 av_assert0(p->filter);
577
578 while ((e = av_dict_iterate(p->opts, e))) {
579 int ret = filter_opt_apply(logctx, p->filter, e->key, e->value);
580 if (ret < 0)
581 return ret;
582 }
583
584 av_dict_free(&p->opts);
585 }
586 }
587
588 return 0;
589}
590
591static int graph_parse(void *logctx,
592 AVFilterGraph *graph, const char *desc,
594 AVBufferRef *hw_device)
595{
597 int ret;
598
599 *inputs = NULL;
600 *outputs = NULL;
601
602 ret = avfilter_graph_segment_parse(graph, desc, 0, &seg);
603 if (ret < 0)
604 return ret;
605
607 if (ret < 0)
608 goto fail;
609
610 if (hw_device) {
611 for (int i = 0; i < graph->nb_filters; i++) {
612 AVFilterContext *f = graph->filters[i];
613
614 if (!(f->filter->flags & AVFILTER_FLAG_HWDEVICE))
615 continue;
616 f->hw_device_ctx = av_buffer_ref(hw_device);
617 if (!f->hw_device_ctx) {
618 ret = AVERROR(ENOMEM);
619 goto fail;
620 }
621 }
622 }
623
624 ret = graph_opts_apply(logctx, seg);
625 if (ret < 0)
626 goto fail;
627
629
630fail:
632 return ret;
633}
634
635// Filters can be configured only if the formats of all inputs are known.
637{
638 for (int i = 0; i < fg->nb_inputs; i++) {
640 if (ifp->format < 0)
641 return 0;
642 }
643 return 1;
644}
645
646static int filter_thread(void *arg);
647
648static char *describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in)
649{
651 AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads;
652 int nb_pads = in ? ctx->nb_inputs : ctx->nb_outputs;
653
654 if (nb_pads > 1)
655 return av_strdup(ctx->filter->name);
656 return av_asprintf("%s:%s", ctx->filter->name,
657 avfilter_pad_get_name(pads, inout->pad_idx));
658}
659
660static const char *ofilter_item_name(void *obj)
661{
662 OutputFilterPriv *ofp = obj;
663 return ofp->log_name;
664}
665
666static const AVOption ofilter_options[] = {
667 {"video_size", "set video size", offsetof(OutputFilterPriv, width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, INT_MAX },
668 {"pixel_format", "set pixel format", offsetof(OutputFilterPriv, format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX },
669 {"colorspace", "color space", offsetof(OutputFilterPriv, color_space), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 0, INT_MAX },
670 {"color_range", "color range", offsetof(OutputFilterPriv, color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, INT_MAX },
671 {"alpha_mode", "color range", offsetof(OutputFilterPriv, alpha_mode), AV_OPT_TYPE_INT, {.i64 = AVALPHA_MODE_UNSPECIFIED }, 0, INT_MAX },
672 {"chroma_location", "chroma sample location", offsetof(OutputFilterPriv, chroma_location), AV_OPT_TYPE_INT, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, INT_MAX },
673 {"ar", "set audio sampling rate (in Hz)", offsetof(OutputFilterPriv, sample_rate), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX },
674 {"ch_layout", NULL, offsetof(OutputFilterPriv, ch_layout), AV_OPT_TYPE_CHLAYOUT, {.str = NULL }, 0, 0 },
675 { NULL },
676};
677
678static const AVClass ofilter_class = {
679 .class_name = "OutputFilter",
680 .version = LIBAVUTIL_VERSION_INT,
681 .item_name = ofilter_item_name,
682 .option = ofilter_options,
683 .parent_log_context_offset = offsetof(OutputFilterPriv, log_parent),
684 .category = AV_CLASS_CATEGORY_FILTER,
685};
686
688{
689 OutputFilterPriv *ofp;
690 OutputFilter *ofilter;
691
692 ofp = allocate_array_elem(&fg->outputs, sizeof(*ofp), &fg->nb_outputs);
693 if (!ofp)
694 return NULL;
695
696 ofilter = &ofp->ofilter;
697 ofilter->class = &ofilter_class;
698 ofp->log_parent = fg;
699 ofilter->graph = fg;
700 ofilter->type = type;
702 ofp->reinit_opts = (ReinitOpts){ .pts = AV_NOPTS_VALUE };
703 ofilter->index = fg->nb_outputs - 1;
704
705 snprintf(ofp->log_name, sizeof(ofp->log_name), "%co%d",
706 av_get_media_type_string(type)[0], ofilter->index);
707
708 return ofilter;
709}
710
711static int ifilter_bind_ist(InputFilter *ifilter, InputStream *ist,
712 const ViewSpecifier *vs)
713{
714 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
715 FilterGraphPriv *fgp = fgp_from_fg(ifilter->graph);
717 int ret;
718
719 av_assert0(!ifp->bound);
720 ifp->bound = 1;
721
722 if (ifilter->type != ist->par->codec_type &&
723 !(ifilter->type == AVMEDIA_TYPE_VIDEO && ist->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
724 av_log(fgp, AV_LOG_ERROR, "Tried to connect %s stream to %s filtergraph input\n",
726 return AVERROR(EINVAL);
727 }
728
729 ifp->type_src = ist->st->codecpar->codec_type;
730
732 if (!ifp->opts.fallback)
733 return AVERROR(ENOMEM);
734
735 ret = ist_filter_add(ist, ifilter, filtergraph_is_simple(ifilter->graph),
736 vs, &ifp->opts, &src);
737 if (ret < 0)
738 return ret;
739
740 ifilter->input_name = av_strdup(ifp->opts.name);
741 if (!ifilter->input_name)
742 return AVERROR(EINVAL);
743
744 ret = sch_connect(fgp->sch,
745 src, SCH_FILTER_IN(fgp->sch_idx, ifilter->index));
746 if (ret < 0)
747 return ret;
748
749 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
751 if (!ifp->sub2video.frame)
752 return AVERROR(ENOMEM);
753
754 ifp->width = ifp->opts.sub2video_width;
755 ifp->height = ifp->opts.sub2video_height;
756
757 /* rectangles are AV_PIX_FMT_PAL8, but we have no guarantee that the
758 palettes for all rectangles are identical or compatible */
760
762
763 av_log(fgp, AV_LOG_VERBOSE, "sub2video: using %dx%d canvas\n",
764 ifp->width, ifp->height);
765 }
766
767 return 0;
768}
769
771 const ViewSpecifier *vs)
772{
775 int ret;
776
777 av_assert0(!ifp->bound);
778 ifp->bound = 1;
779
780 if (ifp->ifilter.type != dec->type) {
781 av_log(fgp, AV_LOG_ERROR, "Tried to connect %s decoder to %s filtergraph input\n",
783 return AVERROR(EINVAL);
784 }
785
786 ifp->type_src = ifp->ifilter.type;
787
788 ret = dec_filter_add(dec, &ifp->ifilter, &ifp->opts, vs, &src);
789 if (ret < 0)
790 return ret;
791
792 ifp->ifilter.input_name = av_strdup(ifp->opts.name);
793 if (!ifp->ifilter.input_name)
794 return AVERROR(EINVAL);
795
796 ret = sch_connect(fgp->sch, src, SCH_FILTER_IN(fgp->sch_idx, ifp->ifilter.index));
797 if (ret < 0)
798 return ret;
799
800 return 0;
801}
802
803static int set_channel_layout(OutputFilterPriv *f, const AVChannelLayout *layouts_allowed,
804 const AVChannelLayout *layout_requested)
805{
806 int i, err;
807
808 if (layout_requested->order != AV_CHANNEL_ORDER_UNSPEC) {
809 /* Pass the layout through for all orders but UNSPEC */
810 err = av_channel_layout_copy(&f->ch_layout, layout_requested);
811 if (err < 0)
812 return err;
813 return 0;
814 }
815
816 /* Requested layout is of order UNSPEC */
817 if (!layouts_allowed) {
818 /* Use the default native layout for the requested amount of channels when the
819 encoder doesn't have a list of supported layouts */
820 av_channel_layout_default(&f->ch_layout, layout_requested->nb_channels);
821 return 0;
822 }
823 /* Encoder has a list of supported layouts. Pick the first layout in it with the
824 same amount of channels as the requested layout */
825 for (i = 0; layouts_allowed[i].nb_channels; i++) {
826 if (layouts_allowed[i].nb_channels == layout_requested->nb_channels)
827 break;
828 }
829 if (layouts_allowed[i].nb_channels) {
830 /* Use it if one is found */
831 err = av_channel_layout_copy(&f->ch_layout, &layouts_allowed[i]);
832 if (err < 0)
833 return err;
834 return 0;
835 }
836 /* If no layout for the amount of channels requested was found, use the default
837 native layout for it. */
838 av_channel_layout_default(&f->ch_layout, layout_requested->nb_channels);
839
840 return 0;
841}
842
843static int parse_reinit_opts(AVFifo **pout, const char *opts, void *logctx)
844{
845 AVFifo *out;
846 int ret = AVERROR_BUG;
847 char *ptr, *str, *substr = NULL;
848 const char *token;
849
850 str = av_strdup(opts);
851 if (!str)
852 return AVERROR(ENOMEM);
853
855 if (!out) {
856 ret = AVERROR(ENOMEM);
857 goto end;
858 }
859
860 token = av_strtok(str, ",", &ptr);
861 while (token) {
862 ReinitOpts o = { 0 };
863 const char *subtoken;
864 char *subptr, *endptr;
865
866 substr = av_strdup(token);
867 if (!substr) {
868 ret = AVERROR(ENOMEM);
869 goto end;
870 }
871 subtoken = av_strtok(substr, "|", &subptr);
872 if (subtoken && subptr) {
873 if (!av_strstart(subtoken, "pts=", &subtoken)) {
874 av_log(logctx, AV_LOG_ERROR, "Invalid reinit identifier\n");
875 ret = AVERROR(ENOMEM);
876 goto end;
877 }
878 o.pts = strtoll(subtoken, &endptr, 0);
879 if (*endptr || o.pts < 0) {
880 ret = AVERROR(EINVAL);
881 goto end;
882 }
883 ret = av_dict_parse_string(&o.dict, subptr, "=", ":", 0);
884 if (ret < 0) {
885 av_log(logctx, AV_LOG_ERROR, "Error parsing encoder options\n");
886 goto end;
887 }
888 ret = av_fifo_write(out, &o, 1);
889 if (ret < 0) {
890 av_dict_free(&o.dict);
891 goto end;
892 }
893 } else {
894 ret = AVERROR(EINVAL);
895 goto end;
896 }
897 av_freep(&substr);
898 if (ptr)
899 ptr += strspn(ptr, " \n\t\r");
900 token = av_strtok(NULL, ",", &ptr);
901 }
902
903 ret = 0;
904end:
905 *pout = out;
906 av_free(substr);
907 av_free(str);
908
909 return ret;
910}
911
912int ofilter_bind_enc(OutputFilter *ofilter, unsigned sched_idx_enc,
914{
915 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
916 FilterGraph *fg = ofilter->graph;
917 FilterGraphPriv *fgp = fgp_from_fg(fg);
918 int ret;
919
920 av_assert0(!ofilter->bound);
921 av_assert0(!opts->enc ||
922 ofilter->type == opts->enc->type);
923
924 ofp->needed = ofilter->bound = 1;
925 av_freep(&ofilter->linklabel);
926
927 ofp->flags |= opts->flags;
928 ofp->ts_offset = opts->ts_offset;
929 ofp->enc_timebase = opts->output_tb;
930
931 ofp->trim_start_us = opts->trim_start_us;
932 ofp->trim_duration_us = opts->trim_duration_us;
933
934 ofilter->output_name = av_strdup(opts->name);
935 if (!ofilter->output_name)
936 return AVERROR(EINVAL);
937
938 if (opts->reinit_opts) {
939 ret = parse_reinit_opts(&ofp->reinit_opts_fifo, opts->reinit_opts, ofilter);
940 if (ret < 0)
941 return ret;
942 }
943
944 ret = av_dict_copy(&ofp->sws_opts, opts->sws_opts, 0);
945 if (ret < 0)
946 return ret;
947
948 ret = av_dict_copy(&ofp->swr_opts, opts->swr_opts, 0);
949 if (ret < 0)
950 return ret;
951
952 if (opts->flags & OFILTER_FLAG_AUDIO_24BIT)
953 av_dict_set(&ofp->swr_opts, "output_sample_bits", "24", 0);
954
955 if (fgp->is_simple) {
956 // for simple filtergraph there is just one output,
957 // so use only graph-level information for logging
958 ofp->log_parent = NULL;
959 av_strlcpy(ofp->log_name, fgp->log_name, sizeof(ofp->log_name));
960 } else
961 av_strlcatf(ofp->log_name, sizeof(ofp->log_name), "->%s", ofilter->output_name);
962
963 switch (ofilter->type) {
965 ofp->width = opts->width;
966 ofp->height = opts->height;
967 if (opts->format != AV_PIX_FMT_NONE) {
968 ofp->format = opts->format;
969 } else
970 ofp->pix_fmts = opts->pix_fmts;
971
972 if (opts->color_space != AVCOL_SPC_UNSPECIFIED)
973 ofp->color_space = opts->color_space;
974 else
975 ofp->color_spaces = opts->color_spaces;
976
977 if (opts->color_range != AVCOL_RANGE_UNSPECIFIED)
978 ofp->color_range = opts->color_range;
979 else
980 ofp->color_ranges = opts->color_ranges;
981
982 if (opts->alpha_mode != AVALPHA_MODE_UNSPECIFIED)
983 ofp->alpha_mode = opts->alpha_mode;
984 else
985 ofp->alpha_modes = opts->alpha_modes;
986
987 if (opts->chroma_location != AVCHROMA_LOC_UNSPECIFIED)
988 ofp->chroma_location = opts->chroma_location;
989 else
990 ofp->chroma_locations = opts->chroma_locations;
991
993
995 if (!ofp->fps.last_frame)
996 return AVERROR(ENOMEM);
997
998 ofp->fps.vsync_method = opts->vsync_method;
999 ofp->fps.framerate = opts->frame_rate;
1000 ofp->fps.framerate_max = opts->max_frame_rate;
1001 ofp->fps.framerate_supported = opts->frame_rates;
1002
1003 // reduce frame rate for mpeg4 to be within the spec limits
1004 if (opts->enc && opts->enc->id == AV_CODEC_ID_MPEG4)
1005 ofp->fps.framerate_clip = 65535;
1006
1007 ofp->fps.dup_warning = 1000;
1008
1009 break;
1010 case AVMEDIA_TYPE_AUDIO:
1011 if (opts->format != AV_SAMPLE_FMT_NONE) {
1012 ofp->format = opts->format;
1013 } else {
1014 ofp->sample_fmts = opts->sample_fmts;
1015 }
1016 if (opts->sample_rate) {
1017 ofp->sample_rate = opts->sample_rate;
1018 } else
1019 ofp->sample_rates = opts->sample_rates;
1020 if (opts->ch_layout.nb_channels) {
1021 int ret = set_channel_layout(ofp, opts->ch_layouts, &opts->ch_layout);
1022 if (ret < 0)
1023 return ret;
1024 } else {
1025 ofp->ch_layouts = opts->ch_layouts;
1026 }
1027 break;
1028 }
1029
1030 ret = sch_connect(fgp->sch, SCH_FILTER_OUT(fgp->sch_idx, ofilter->index),
1031 SCH_ENC(sched_idx_enc));
1032 if (ret < 0)
1033 return ret;
1034
1035 return 0;
1036}
1037
1040{
1041 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1042
1043 av_assert0(!ofilter->bound);
1044 av_assert0(ofilter->type == ifp->ifilter.type);
1045
1046 ofp->needed = ofilter->bound = 1;
1047 av_freep(&ofilter->linklabel);
1048
1049 ofilter->output_name = av_strdup(opts->name);
1050 if (!ofilter->output_name)
1051 return AVERROR(EINVAL);
1052
1053 ifp->ofilter_src = ofilter;
1054
1055 av_strlcatf(ofp->log_name, sizeof(ofp->log_name), "->%s", ofilter->output_name);
1056
1057 return 0;
1058}
1059
1060static int ifilter_bind_fg(InputFilterPriv *ifp, FilterGraph *fg_src, int out_idx)
1061{
1063 OutputFilter *ofilter_src = fg_src->outputs[out_idx];
1065 char name[32];
1066 int ret;
1067
1068 av_assert0(!ifp->bound);
1069 ifp->bound = 1;
1070
1071 if (ifp->ifilter.type != ofilter_src->type) {
1072 av_log(fgp, AV_LOG_ERROR, "Tried to connect %s output to %s input\n",
1073 av_get_media_type_string(ofilter_src->type),
1075 return AVERROR(EINVAL);
1076 }
1077
1078 ifp->type_src = ifp->ifilter.type;
1079
1080 memset(&opts, 0, sizeof(opts));
1081
1082 snprintf(name, sizeof(name), "fg:%d:%d", fgp->fg.index, ifp->ifilter.index);
1083 opts.name = name;
1084
1085 ret = ofilter_bind_ifilter(ofilter_src, ifp, &opts);
1086 if (ret < 0)
1087 return ret;
1088
1089 ret = sch_connect(fgp->sch, SCH_FILTER_OUT(fg_src->index, out_idx),
1090 SCH_FILTER_IN(fgp->sch_idx, ifp->ifilter.index));
1091 if (ret < 0)
1092 return ret;
1093
1094 return 0;
1095}
1096
1098{
1099 InputFilterPriv *ifp;
1100 InputFilter *ifilter;
1101
1102 ifp = allocate_array_elem(&fg->inputs, sizeof(*ifp), &fg->nb_inputs);
1103 if (!ifp)
1104 return NULL;
1105
1106 ifilter = &ifp->ifilter;
1107 ifilter->graph = fg;
1108
1109 ifp->frame = av_frame_alloc();
1110 if (!ifp->frame)
1111 return NULL;
1112
1113 ifilter->index = fg->nb_inputs - 1;
1114 ifp->format = -1;
1119
1121 if (!ifp->frame_queue)
1122 return NULL;
1123
1124 return ifilter;
1125}
1126
1128{
1129 FilterGraph *fg = *pfg;
1130 FilterGraphPriv *fgp;
1131
1132 if (!fg)
1133 return;
1134 fgp = fgp_from_fg(fg);
1135
1136 for (int j = 0; j < fg->nb_inputs; j++) {
1137 InputFilter *ifilter = fg->inputs[j];
1138 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1139
1140 if (ifp->frame_queue) {
1141 AVFrame *frame;
1142 while (av_fifo_read(ifp->frame_queue, &frame, 1) >= 0)
1145 }
1147
1148 av_frame_free(&ifp->frame);
1150
1153 av_freep(&ifilter->linklabel);
1154 av_freep(&ifp->opts.name);
1157 av_freep(&ifilter->name);
1158 av_freep(&ifilter->input_name);
1159 av_freep(&fg->inputs[j]);
1160 }
1161 av_freep(&fg->inputs);
1162 for (int j = 0; j < fg->nb_outputs; j++) {
1163 OutputFilter *ofilter = fg->outputs[j];
1164 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1165
1167 av_dict_free(&ofp->sws_opts);
1168 av_dict_free(&ofp->swr_opts);
1169
1170 av_freep(&ofilter->linklabel);
1171 av_freep(&ofilter->name);
1172 av_freep(&ofilter->output_name);
1173 av_freep(&ofilter->apad);
1175 if (ofp->reinit_opts_fifo) {
1176 while (av_fifo_read(ofp->reinit_opts_fifo, &ofp->reinit_opts, 1) >= 0)
1179 }
1182 av_freep(&fg->outputs[j]);
1183 }
1184 av_freep(&fg->outputs);
1185 av_freep(&fg->graph_desc);
1186
1187 av_frame_free(&fgp->frame);
1188 av_frame_free(&fgp->frame_enc);
1189
1190 av_freep(pfg);
1191}
1192
1193static const char *fg_item_name(void *obj)
1194{
1195 const FilterGraphPriv *fgp = obj;
1196
1197 return fgp->log_name;
1198}
1199
1200static const AVClass fg_class = {
1201 .class_name = "FilterGraph",
1202 .version = LIBAVUTIL_VERSION_INT,
1203 .item_name = fg_item_name,
1204 .category = AV_CLASS_CATEGORY_FILTER,
1205};
1206
1207int fg_create(FilterGraph **pfg, char **graph_desc, Scheduler *sch,
1209{
1210 FilterGraphPriv *fgp;
1211 FilterGraph *fg;
1212
1214 AVFilterGraph *graph;
1215 int ret = 0;
1216
1217 fgp = av_mallocz(sizeof(*fgp));
1218 if (!fgp) {
1219 av_freep(graph_desc);
1220 return AVERROR(ENOMEM);
1221 }
1222 fg = &fgp->fg;
1223
1224 if (pfg) {
1225 *pfg = fg;
1226 fg->index = -1;
1227 } else {
1229 if (ret < 0) {
1230 av_freep(graph_desc);
1231 av_freep(&fgp);
1232 return ret;
1233 }
1234
1235 fg->index = nb_filtergraphs - 1;
1236 }
1237
1238 fg->class = &fg_class;
1239 fg->graph_desc = *graph_desc;
1241 fgp->nb_threads = -1;
1242 fgp->sch = sch;
1243
1244 *graph_desc = NULL;
1245
1246 snprintf(fgp->log_name, sizeof(fgp->log_name), "fc#%d", fg->index);
1247
1248 fgp->frame = av_frame_alloc();
1249 fgp->frame_enc = av_frame_alloc();
1250 if (!fgp->frame || !fgp->frame_enc)
1251 return AVERROR(ENOMEM);
1252
1253 /* this graph is only used for determining the kinds of inputs
1254 * and outputs we have, and is discarded on exit from this function */
1255 graph = avfilter_graph_alloc();
1256 if (!graph)
1257 return AVERROR(ENOMEM);;
1258 graph->nb_threads = 1;
1259
1260 ret = graph_parse(fg, graph, fg->graph_desc, &inputs, &outputs,
1262 if (ret < 0)
1263 goto fail;
1264
1265 for (AVFilterInOut *cur = inputs; cur; cur = cur->next) {
1266 InputFilter *const ifilter = ifilter_alloc(fg);
1267
1268 if (!ifilter) {
1269 ret = AVERROR(ENOMEM);
1270 goto fail;
1271 }
1272
1273 ifilter->linklabel = cur->name;
1274 cur->name = NULL;
1275
1276 ifilter->type = avfilter_pad_get_type(cur->filter_ctx->input_pads,
1277 cur->pad_idx);
1278
1279 if (ifilter->type != AVMEDIA_TYPE_VIDEO && ifilter->type != AVMEDIA_TYPE_AUDIO) {
1280 av_log(fg, AV_LOG_FATAL, "Only video and audio filters supported "
1281 "currently.\n");
1282 ret = AVERROR(ENOSYS);
1283 goto fail;
1284 }
1285
1286 ifilter->name = describe_filter_link(fg, cur, 1);
1287 if (!ifilter->name) {
1288 ret = AVERROR(ENOMEM);
1289 goto fail;
1290 }
1291 }
1292
1293 for (AVFilterInOut *cur = outputs; cur; cur = cur->next) {
1294 const enum AVMediaType type = avfilter_pad_get_type(cur->filter_ctx->output_pads,
1295 cur->pad_idx);
1296 OutputFilter *const ofilter = ofilter_alloc(fg, type);
1297 OutputFilterPriv *ofp;
1298
1299 if (!ofilter) {
1300 ret = AVERROR(ENOMEM);
1301 goto fail;
1302 }
1303 ofp = ofp_from_ofilter(ofilter);
1304
1305 ofilter->linklabel = cur->name;
1306 cur->name = NULL;
1307
1308 ofilter->name = describe_filter_link(fg, cur, 0);
1309 if (!ofilter->name) {
1310 ret = AVERROR(ENOMEM);
1311 goto fail;
1312 }
1313
1314 // opts should only be needed in this function to fill fields from filtergraphs
1315 // whose output is meant to be treated as if it was stream, e.g. merged HEIF
1316 // tile groups.
1317 if (opts) {
1318 ofp->flags = opts->flags;
1319 ofp->side_data = opts->side_data;
1320 ofp->nb_side_data = opts->nb_side_data;
1321
1322 ofp->crop_top = opts->crop_top;
1323 ofp->crop_bottom = opts->crop_bottom;
1324 ofp->crop_left = opts->crop_left;
1325 ofp->crop_right = opts->crop_right;
1326
1329 if (sd)
1330 memcpy(ofp->displaymatrix, sd->data, sizeof(ofp->displaymatrix));
1331 }
1332 }
1333
1334 if (!fg->nb_outputs) {
1335 av_log(fg, AV_LOG_FATAL, "A filtergraph has zero outputs, this is not supported\n");
1336 ret = AVERROR(ENOSYS);
1337 goto fail;
1338 }
1339
1340 ret = sch_add_filtergraph(sch, fg->nb_inputs, fg->nb_outputs,
1341 filter_thread, fgp);
1342 if (ret < 0)
1343 goto fail;
1344 fgp->sch_idx = ret;
1345
1346fail:
1349 avfilter_graph_free(&graph);
1350
1351 if (ret < 0)
1352 return ret;
1353
1354 return 0;
1355}
1356
1358 InputStream *ist,
1359 char **graph_desc,
1360 Scheduler *sch, unsigned sched_idx_enc,
1362{
1363 const enum AVMediaType type = ist->par->codec_type;
1364 FilterGraph *fg;
1365 FilterGraphPriv *fgp;
1366 int ret;
1367
1368 ret = fg_create(pfg, graph_desc, sch, NULL);
1369 if (ret < 0)
1370 return ret;
1371 fg = *pfg;
1372 fgp = fgp_from_fg(fg);
1373
1374 fgp->is_simple = 1;
1375
1376 snprintf(fgp->log_name, sizeof(fgp->log_name), "%cf%s",
1378
1379 if (fg->nb_inputs != 1 || fg->nb_outputs != 1) {
1380 av_log(fg, AV_LOG_ERROR, "Simple filtergraph '%s' was expected "
1381 "to have exactly 1 input and 1 output. "
1382 "However, it had %d input(s) and %d output(s). Please adjust, "
1383 "or use a complex filtergraph (-filter_complex) instead.\n",
1384 *graph_desc, fg->nb_inputs, fg->nb_outputs);
1385 return AVERROR(EINVAL);
1386 }
1387 if (fg->outputs[0]->type != type) {
1388 av_log(fg, AV_LOG_ERROR, "Filtergraph has a %s output, cannot connect "
1389 "it to %s output stream\n",
1392 return AVERROR(EINVAL);
1393 }
1394
1395 ret = ifilter_bind_ist(fg->inputs[0], ist, opts->vs);
1396 if (ret < 0)
1397 return ret;
1398
1399 ret = ofilter_bind_enc(fg->outputs[0], sched_idx_enc, opts);
1400 if (ret < 0)
1401 return ret;
1402
1403 if (opts->nb_threads >= 0)
1404 fgp->nb_threads = opts->nb_threads;
1405
1406 return 0;
1407}
1408
1409static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter, int commit)
1410{
1411 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1412 InputStream *ist = NULL;
1413 enum AVMediaType type = ifilter->type;
1414 ViewSpecifier vs = { .type = VIEW_SPECIFIER_TYPE_NONE };
1415 const char *spec;
1416 char *p;
1417 int i, ret;
1418
1419 if (ifilter->linklabel && !strncmp(ifilter->linklabel, "dec:", 4)) {
1420 // bind to a standalone decoder
1421 int dec_idx;
1422
1423 dec_idx = strtol(ifilter->linklabel + 4, &p, 0);
1424 if (dec_idx < 0 || dec_idx >= nb_decoders) {
1425 av_log(fg, AV_LOG_ERROR, "Invalid decoder index %d in filtergraph description %s\n",
1426 dec_idx, fg->graph_desc);
1427 return AVERROR(EINVAL);
1428 }
1429
1430 if (type == AVMEDIA_TYPE_VIDEO) {
1431 spec = *p == ':' ? p + 1 : p;
1432 ret = view_specifier_parse(&spec, &vs);
1433 if (ret < 0)
1434 return ret;
1435 }
1436
1437 ret = ifilter_bind_dec(ifp, decoders[dec_idx], &vs);
1438 if (ret < 0)
1439 av_log(fg, AV_LOG_ERROR, "Error binding a decoder to filtergraph input %s\n",
1440 ifilter->name);
1441 return ret;
1442 } else if (ifilter->linklabel) {
1445 AVStream *st = NULL;
1446 int file_idx;
1447
1448 // try finding an unbound filtergraph output with this label
1449 for (int i = 0; i < nb_filtergraphs; i++) {
1450 FilterGraph *fg_src = filtergraphs[i];
1451
1452 if (fg == fg_src)
1453 continue;
1454
1455 for (int j = 0; j < fg_src->nb_outputs; j++) {
1456 OutputFilter *ofilter = fg_src->outputs[j];
1457
1458 if (!ofilter->bound && ofilter->linklabel &&
1459 !strcmp(ofilter->linklabel, ifilter->linklabel)) {
1460 if (commit) {
1462 "Binding input with label '%s' to filtergraph output %d:%d\n",
1463 ifilter->linklabel, i, j);
1464
1465 ret = ifilter_bind_fg(ifp, fg_src, j);
1466 if (ret < 0) {
1467 av_log(fg, AV_LOG_ERROR, "Error binding filtergraph input %s\n",
1468 ifilter->linklabel);
1469 return ret;
1470 }
1471 } else
1472 ofp_from_ofilter(ofilter)->needed = 1;
1473 return 0;
1474 }
1475 }
1476 }
1477
1478 // bind to an explicitly specified demuxer stream
1479 file_idx = strtol(ifilter->linklabel, &p, 0);
1480 if (file_idx < 0 || file_idx >= nb_input_files) {
1481 av_log(fg, AV_LOG_FATAL, "Invalid file index %d in filtergraph description %s.\n",
1482 file_idx, fg->graph_desc);
1483 return AVERROR(EINVAL);
1484 }
1485 s = input_files[file_idx]->ctx;
1486
1487 ret = stream_specifier_parse(&ss, *p == ':' ? p + 1 : p, 1, fg);
1488 if (ret < 0) {
1489 av_log(fg, AV_LOG_ERROR, "Invalid stream specifier: %s\n", p);
1490 return ret;
1491 }
1492
1493 if (type == AVMEDIA_TYPE_VIDEO) {
1494 spec = ss.remainder ? ss.remainder : "";
1495 ret = view_specifier_parse(&spec, &vs);
1496 if (ret < 0) {
1498 return ret;
1499 }
1500 }
1501
1502 for (i = 0; i < s->nb_streams; i++) {
1503 enum AVMediaType stream_type = s->streams[i]->codecpar->codec_type;
1504 if (stream_type != type &&
1505 !(stream_type == AVMEDIA_TYPE_SUBTITLE &&
1506 type == AVMEDIA_TYPE_VIDEO /* sub2video hack */))
1507 continue;
1508 if (stream_specifier_match(&ss, s, s->streams[i], fg)) {
1509 st = s->streams[i];
1510 break;
1511 }
1512 }
1514 if (!st) {
1515 av_log(fg, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s "
1516 "matches no streams.\n", p, fg->graph_desc);
1517 return AVERROR(EINVAL);
1518 }
1519 ist = input_files[file_idx]->streams[st->index];
1520
1521 if (commit)
1523 "Binding input with label '%s' to input stream %d:%d\n",
1524 ifilter->linklabel, ist->file->index, ist->index);
1525 } else {
1526 // try finding an unbound filtergraph output
1527 for (int i = 0; i < nb_filtergraphs; i++) {
1528 FilterGraph *fg_src = filtergraphs[i];
1529
1530 if (fg == fg_src)
1531 continue;
1532
1533 for (int j = 0; j < fg_src->nb_outputs; j++) {
1534 OutputFilter *ofilter = fg_src->outputs[j];
1535
1536 if (!ofilter->bound) {
1537 if (commit) {
1539 "Binding unlabeled filtergraph input to filtergraph output %d:%d\n", i, j);
1540
1541 ret = ifilter_bind_fg(ifp, fg_src, j);
1542 if (ret < 0) {
1543 av_log(fg, AV_LOG_ERROR, "Error binding filtergraph input %d:%d\n", i, j);
1544 return ret;
1545 }
1546 } else
1547 ofp_from_ofilter(ofilter)->needed = 1;
1548 return 0;
1549 }
1550 }
1551 }
1552
1553 ist = ist_find_unused(type);
1554 if (!ist) {
1555 av_log(fg, AV_LOG_FATAL,
1556 "Cannot find an unused %s input stream to feed the "
1557 "unlabeled input pad %s.\n",
1559 return AVERROR(EINVAL);
1560 }
1561
1562 if (commit)
1564 "Binding unlabeled input %d to input stream %d:%d\n",
1565 ifilter->index, ist->file->index, ist->index);
1566 }
1567 av_assert0(ist);
1568
1569 if (commit) {
1570 ret = ifilter_bind_ist(ifilter, ist, &vs);
1571 if (ret < 0) {
1572 av_log(fg, AV_LOG_ERROR,
1573 "Error binding an input stream to complex filtergraph input %s.\n",
1574 ifilter->name);
1575 return ret;
1576 }
1577 }
1578
1579 return 0;
1580}
1581
1582static int bind_inputs(FilterGraph *fg, int commit)
1583{
1584 // bind filtergraph inputs to input streams or other filtergraphs
1585 for (int i = 0; i < fg->nb_inputs; i++) {
1587 int ret;
1588
1589 if (ifp->bound)
1590 continue;
1591
1592 ret = fg_complex_bind_input(fg, &ifp->ifilter, commit);
1593 if (ret < 0)
1594 return ret;
1595 }
1596
1597 return 0;
1598}
1599
1601{
1602 int ret;
1603
1604 for (int i = 0; i < nb_filtergraphs; i++) {
1605 ret = bind_inputs(filtergraphs[i], 0);
1606 if (ret < 0)
1607 return ret;
1608 }
1609
1610 // check that all outputs were bound
1611 for (int i = nb_filtergraphs - 1; i >= 0; i--) {
1612 FilterGraph *fg = filtergraphs[i];
1614
1615 for (int j = 0; j < fg->nb_outputs; j++) {
1616 OutputFilter *output = fg->outputs[j];
1617 if (!ofp_from_ofilter(output)->needed) {
1618 if (!fg->is_internal) {
1619 av_log(fg, AV_LOG_FATAL,
1620 "Filter '%s' has output %d (%s) unconnected\n",
1621 output->name, j,
1622 output->linklabel ? (const char *)output->linklabel : "unlabeled");
1623 return AVERROR(EINVAL);
1624 }
1625
1626 av_log(fg, AV_LOG_DEBUG,
1627 "Internal filter '%s' has output %d (%s) unconnected. Removing graph\n",
1628 output->name, j,
1629 output->linklabel ? (const char *)output->linklabel : "unlabeled");
1633 if (nb_filtergraphs > 0)
1634 memmove(&filtergraphs[i],
1635 &filtergraphs[i + 1],
1636 (nb_filtergraphs - i) * sizeof(*filtergraphs));
1637 break;
1638 }
1639 }
1640 }
1641
1642 for (int i = 0; i < nb_filtergraphs; i++) {
1643 ret = bind_inputs(filtergraphs[i], 1);
1644 if (ret < 0)
1645 return ret;
1646 }
1647
1648 return 0;
1649}
1650
1652 AVFilterContext **last_filter, int *pad_idx,
1653 const char *filter_name)
1654{
1655 AVFilterGraph *graph = (*last_filter)->graph;
1657 const AVFilter *trim;
1658 enum AVMediaType type = avfilter_pad_get_type((*last_filter)->output_pads, *pad_idx);
1659 const char *name = (type == AVMEDIA_TYPE_VIDEO) ? "trim" : "atrim";
1660 int ret = 0;
1661
1662 if (duration == INT64_MAX && start_time == AV_NOPTS_VALUE)
1663 return 0;
1664
1665 trim = avfilter_get_by_name(name);
1666 if (!trim) {
1667 av_log(logctx, AV_LOG_ERROR, "%s filter not present, cannot limit "
1668 "recording time.\n", name);
1670 }
1671
1672 ctx = avfilter_graph_alloc_filter(graph, trim, filter_name);
1673 if (!ctx)
1674 return AVERROR(ENOMEM);
1675
1676 if (duration != INT64_MAX) {
1677 ret = av_opt_set_int(ctx, "durationi", duration,
1679 }
1680 if (ret >= 0 && start_time != AV_NOPTS_VALUE) {
1681 ret = av_opt_set_int(ctx, "starti", start_time,
1683 }
1684 if (ret < 0) {
1685 av_log(ctx, AV_LOG_ERROR, "Error configuring the %s filter", name);
1686 return ret;
1687 }
1688
1689 ret = avfilter_init_str(ctx, NULL);
1690 if (ret < 0)
1691 return ret;
1692
1693 ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
1694 if (ret < 0)
1695 return ret;
1696
1697 *last_filter = ctx;
1698 *pad_idx = 0;
1699 return 0;
1700}
1701
1702static int insert_filter(AVFilterContext **last_filter, int *pad_idx,
1703 const char *filter_name, const char *args)
1704{
1705 AVFilterGraph *graph = (*last_filter)->graph;
1706 const AVFilter *filter = avfilter_get_by_name(filter_name);
1708 int ret;
1709
1710 if (!filter)
1711 return AVERROR_BUG;
1712
1714 filter,
1715 filter_name, args, NULL, graph);
1716 if (ret < 0)
1717 return ret;
1718
1719 ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
1720 if (ret < 0)
1721 return ret;
1722
1723 *last_filter = ctx;
1724 *pad_idx = 0;
1725 return 0;
1726}
1727
1729 OutputFilter *ofilter, AVFilterInOut *out)
1730{
1731 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1732 AVFilterContext *last_filter = out->filter_ctx;
1733 AVBPrint bprint;
1734 int pad_idx = out->pad_idx;
1735 int ret;
1736 char name[255];
1737
1738 snprintf(name, sizeof(name), "out_%s", ofilter->output_name);
1739 ret = avfilter_graph_create_filter(&ofilter->filter,
1740 avfilter_get_by_name("buffersink"),
1741 name, NULL, NULL, graph);
1742
1743 if (ret < 0)
1744 return ret;
1745
1746 if (ofp->flags & OFILTER_FLAG_CROP) {
1747 char crop_buf[64];
1748 snprintf(crop_buf, sizeof(crop_buf), "w=iw-%u-%u:h=ih-%u-%u:x=%u:y=%u",
1749 ofp->crop_left, ofp->crop_right,
1750 ofp->crop_top, ofp->crop_bottom,
1751 ofp->crop_left, ofp->crop_top);
1752 ret = insert_filter(&last_filter, &pad_idx, "crop", crop_buf);
1753 if (ret < 0)
1754 return ret;
1755 }
1756
1757 if (ofp->flags & OFILTER_FLAG_AUTOROTATE) {
1758 int32_t *displaymatrix = ofp->displaymatrix;
1759 double theta;
1760
1761 theta = get_rotation(displaymatrix);
1762
1763 if (fabs(theta - 90) < 1.0) {
1764 ret = insert_filter(&last_filter, &pad_idx, "transpose",
1765 displaymatrix[3] > 0 ? "cclock_flip" : "clock");
1766 } else if (fabs(theta - 180) < 1.0) {
1767 if (displaymatrix[0] < 0) {
1768 ret = insert_filter(&last_filter, &pad_idx, "hflip", NULL);
1769 if (ret < 0)
1770 return ret;
1771 }
1772 if (displaymatrix[4] < 0) {
1773 ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
1774 }
1775 } else if (fabs(theta - 270) < 1.0) {
1776 ret = insert_filter(&last_filter, &pad_idx, "transpose",
1777 displaymatrix[3] < 0 ? "clock_flip" : "cclock");
1778 } else if (fabs(theta) > 1.0) {
1779 char rotate_buf[64];
1780 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1781 ret = insert_filter(&last_filter, &pad_idx, "rotate", rotate_buf);
1782 } else if (fabs(theta) < 1.0) {
1783 if (displaymatrix && displaymatrix[4] < 0) {
1784 ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
1785 }
1786 }
1787 if (ret < 0)
1788 return ret;
1789
1791 }
1792
1793 if ((ofp->width || ofp->height) && (ofp->flags & OFILTER_FLAG_AUTOSCALE) &&
1794 // skip add scale for hardware format
1795 !(ofp->format != AV_PIX_FMT_NONE &&
1797 char args[255];
1799 const AVDictionaryEntry *e = NULL;
1800
1801 snprintf(args, sizeof(args), "%d:%d",
1802 ofp->width, ofp->height);
1803
1804 while ((e = av_dict_iterate(ofp->sws_opts, e))) {
1805 av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
1806 }
1807
1808 snprintf(name, sizeof(name), "scaler_out_%s", ofilter->output_name);
1810 name, args, NULL, graph)) < 0)
1811 return ret;
1812 if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
1813 return ret;
1814
1815 last_filter = filter;
1816 pad_idx = 0;
1817 }
1818
1820 ofp->format != AV_PIX_FMT_NONE || !ofp->pix_fmts);
1822 choose_pix_fmts(ofp, &bprint);
1823 choose_color_spaces(ofp, &bprint);
1824 choose_color_ranges(ofp, &bprint);
1825 choose_alpha_modes(ofp, &bprint);
1826 choose_chroma_locations(ofp, &bprint);
1827 if (!av_bprint_is_complete(&bprint))
1828 return AVERROR(ENOMEM);
1829
1830 if (bprint.len) {
1832
1834 avfilter_get_by_name("format"),
1835 "format", bprint.str, NULL, graph);
1836 av_bprint_finalize(&bprint, NULL);
1837 if (ret < 0)
1838 return ret;
1839 if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
1840 return ret;
1841
1842 last_filter = filter;
1843 pad_idx = 0;
1844 }
1845
1846 snprintf(name, sizeof(name), "trim_out_%s", ofilter->output_name);
1847 ret = insert_trim(fgp, ofp->trim_start_us, ofp->trim_duration_us,
1848 &last_filter, &pad_idx, name);
1849 if (ret < 0)
1850 return ret;
1851
1852
1853 if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
1854 return ret;
1855
1856 return 0;
1857}
1858
1860 OutputFilter *ofilter, AVFilterInOut *out)
1861{
1862 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1863 AVFilterContext *last_filter = out->filter_ctx;
1864 int pad_idx = out->pad_idx;
1865 AVBPrint args;
1866 char name[255];
1867 int ret;
1868
1869 snprintf(name, sizeof(name), "out_%s", ofilter->output_name);
1870 ret = avfilter_graph_create_filter(&ofilter->filter,
1871 avfilter_get_by_name("abuffersink"),
1872 name, NULL, NULL, graph);
1873 if (ret < 0)
1874 return ret;
1875
1876#define AUTO_INSERT_FILTER(opt_name, filter_name, arg) do { \
1877 AVFilterContext *filt_ctx; \
1878 \
1879 av_log(ofilter, AV_LOG_INFO, opt_name " is forwarded to lavfi " \
1880 "similarly to -af " filter_name "=%s.\n", arg); \
1881 \
1882 ret = avfilter_graph_create_filter(&filt_ctx, \
1883 avfilter_get_by_name(filter_name), \
1884 filter_name, arg, NULL, graph); \
1885 if (ret < 0) \
1886 goto fail; \
1887 \
1888 ret = avfilter_link(last_filter, pad_idx, filt_ctx, 0); \
1889 if (ret < 0) \
1890 goto fail; \
1891 \
1892 last_filter = filt_ctx; \
1893 pad_idx = 0; \
1894} while (0)
1896
1897 choose_sample_fmts(ofp, &args);
1898 choose_sample_rates(ofp, &args);
1899 choose_channel_layouts(ofp, &args);
1900 if (!av_bprint_is_complete(&args)) {
1901 ret = AVERROR(ENOMEM);
1902 goto fail;
1903 }
1904 if (args.len) {
1906
1907 snprintf(name, sizeof(name), "format_out_%s", ofilter->output_name);
1909 avfilter_get_by_name("aformat"),
1910 name, args.str, NULL, graph);
1911 if (ret < 0)
1912 goto fail;
1913
1914 ret = avfilter_link(last_filter, pad_idx, format, 0);
1915 if (ret < 0)
1916 goto fail;
1917
1918 last_filter = format;
1919 pad_idx = 0;
1920 }
1921
1922 if (ofilter->apad)
1923 AUTO_INSERT_FILTER("-apad", "apad", ofilter->apad);
1924
1925 snprintf(name, sizeof(name), "trim for output %s", ofilter->output_name);
1926 ret = insert_trim(fgp, ofp->trim_start_us, ofp->trim_duration_us,
1927 &last_filter, &pad_idx, name);
1928 if (ret < 0)
1929 goto fail;
1930
1931 if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
1932 goto fail;
1933fail:
1934 av_bprint_finalize(&args, NULL);
1935
1936 return ret;
1937}
1938
1940 OutputFilter *ofilter, AVFilterInOut *out)
1941{
1942 switch (ofilter->type) {
1943 case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fgp, graph, ofilter, out);
1944 case AVMEDIA_TYPE_AUDIO: return configure_output_audio_filter(fgp, graph, ofilter, out);
1945 default: av_assert0(0); return 0;
1946 }
1947}
1948
1950{
1951 ifp->sub2video.last_pts = INT64_MIN;
1952 ifp->sub2video.end_pts = INT64_MIN;
1953
1954 /* sub2video structure has been (re-)initialized.
1955 Mark it as such so that the system will be
1956 initialized with the first received heartbeat. */
1957 ifp->sub2video.initialize = 1;
1958}
1959
1961 InputFilter *ifilter, AVFilterInOut *in)
1962{
1963 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1964
1965 AVFilterContext *last_filter;
1966 const AVFilter *buffer_filt = avfilter_get_by_name("buffer");
1967 const AVPixFmtDescriptor *desc;
1968 char name[255];
1969 int ret, pad_idx = 0;
1971 if (!par)
1972 return AVERROR(ENOMEM);
1973
1974 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE)
1975 sub2video_prepare(ifp);
1976
1977 snprintf(name, sizeof(name), "graph %d input from stream %s", fg->index,
1978 ifp->opts.name);
1979
1980 ifilter->filter = avfilter_graph_alloc_filter(graph, buffer_filt, name);
1981 if (!ifilter->filter) {
1982 ret = AVERROR(ENOMEM);
1983 goto fail;
1984 }
1985
1986 par->format = ifp->format;
1987 par->time_base = ifp->time_base;
1988 par->frame_rate = ifp->opts.framerate;
1989 par->width = ifp->width;
1990 par->height = ifp->height;
1992 ifp->sample_aspect_ratio : (AVRational){ 0, 1 };
1993 par->color_space = ifp->color_space;
1994 par->color_range = ifp->color_range;
1995 par->alpha_mode = ifp->alpha_mode;
1996 par->chroma_location = ifp->chroma_location;
1997 par->hw_frames_ctx = ifp->hw_frames_ctx;
1998 par->side_data = ifp->side_data;
1999 par->nb_side_data = ifp->nb_side_data;
2000
2001 ret = av_buffersrc_parameters_set(ifilter->filter, par);
2002 if (ret < 0)
2003 goto fail;
2004 av_freep(&par);
2005
2006 ret = avfilter_init_dict(ifilter->filter, NULL);
2007 if (ret < 0)
2008 goto fail;
2009
2010 last_filter = ifilter->filter;
2011
2014
2015 if ((ifp->opts.flags & IFILTER_FLAG_CROP)) {
2016 char crop_buf[64];
2017 snprintf(crop_buf, sizeof(crop_buf), "w=iw-%u-%u:h=ih-%u-%u:x=%u:y=%u",
2018 ifp->opts.crop_left, ifp->opts.crop_right,
2019 ifp->opts.crop_top, ifp->opts.crop_bottom,
2020 ifp->opts.crop_left, ifp->opts.crop_top);
2021 ret = insert_filter(&last_filter, &pad_idx, "crop", crop_buf);
2022 if (ret < 0)
2023 return ret;
2024 }
2025
2026 // TODO: insert hwaccel enabled filters like transpose_vaapi into the graph
2027 ifp->displaymatrix_applied = 0;
2028 if ((ifp->opts.flags & IFILTER_FLAG_AUTOROTATE) &&
2029 !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
2030 int32_t *displaymatrix = ifp->displaymatrix;
2031 double theta;
2032
2033 theta = get_rotation(displaymatrix);
2034
2035 if (fabs(theta - 90) < 1.0) {
2036 ret = insert_filter(&last_filter, &pad_idx, "transpose",
2037 displaymatrix[3] > 0 ? "cclock_flip" : "clock");
2038 } else if (fabs(theta - 180) < 1.0) {
2039 if (displaymatrix[0] < 0) {
2040 ret = insert_filter(&last_filter, &pad_idx, "hflip", NULL);
2041 if (ret < 0)
2042 return ret;
2043 }
2044 if (displaymatrix[4] < 0) {
2045 ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
2046 }
2047 } else if (fabs(theta - 270) < 1.0) {
2048 ret = insert_filter(&last_filter, &pad_idx, "transpose",
2049 displaymatrix[3] < 0 ? "clock_flip" : "cclock");
2050 } else if (fabs(theta) > 1.0) {
2051 char rotate_buf[64];
2052 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
2053 ret = insert_filter(&last_filter, &pad_idx, "rotate", rotate_buf);
2054 } else if (fabs(theta) < 1.0) {
2055 if (displaymatrix && displaymatrix[4] < 0) {
2056 ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
2057 }
2058 }
2059 if (ret < 0)
2060 return ret;
2061
2062 ifp->displaymatrix_applied = 1;
2063 }
2064
2065 snprintf(name, sizeof(name), "trim_in_%s", ifp->opts.name);
2066 ret = insert_trim(fg, ifp->opts.trim_start_us, ifp->opts.trim_end_us,
2067 &last_filter, &pad_idx, name);
2068 if (ret < 0)
2069 return ret;
2070
2071 if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
2072 return ret;
2073 return 0;
2074fail:
2075 av_freep(&par);
2076
2077 return ret;
2078}
2079
2081 InputFilter *ifilter, AVFilterInOut *in)
2082{
2083 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2084 AVFilterContext *last_filter;
2086 const AVFilter *abuffer_filt = avfilter_get_by_name("abuffer");
2087 AVBPrint args;
2088 char name[255];
2089 int ret, pad_idx = 0;
2090
2092 av_bprintf(&args, "time_base=%d/%d:sample_rate=%d:sample_fmt=%s",
2093 ifp->time_base.num, ifp->time_base.den,
2094 ifp->sample_rate,
2098 av_bprintf(&args, ":channel_layout=");
2100 } else
2101 av_bprintf(&args, ":channels=%d", ifp->ch_layout.nb_channels);
2102 snprintf(name, sizeof(name), "graph_%d_in_%s", fg->index, ifp->opts.name);
2103
2104 if ((ret = avfilter_graph_create_filter(&ifilter->filter, abuffer_filt,
2105 name, args.str, NULL,
2106 graph)) < 0)
2107 return ret;
2109 if (!par)
2110 return AVERROR(ENOMEM);
2111 par->side_data = ifp->side_data;
2112 par->nb_side_data = ifp->nb_side_data;
2113 ret = av_buffersrc_parameters_set(ifilter->filter, par);
2114 av_free(par);
2115 if (ret < 0)
2116 return ret;
2117 last_filter = ifilter->filter;
2118
2119 snprintf(name, sizeof(name), "trim for input stream %s", ifp->opts.name);
2120 ret = insert_trim(fg, ifp->opts.trim_start_us, ifp->opts.trim_end_us,
2121 &last_filter, &pad_idx, name);
2122 if (ret < 0)
2123 return ret;
2124
2125 if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
2126 return ret;
2127
2128 return 0;
2129}
2130
2132 InputFilter *ifilter, AVFilterInOut *in)
2133{
2134 switch (ifilter->type) {
2135 case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, graph, ifilter, in);
2136 case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, graph, ifilter, in);
2137 default: av_assert0(0); return 0;
2138 }
2139}
2140
2142{
2143 for (int i = 0; i < fg->nb_outputs; i++)
2144 fg->outputs[i]->filter = NULL;
2145 for (int i = 0; i < fg->nb_inputs; i++)
2146 fg->inputs[i]->filter = NULL;
2148}
2149
2151{
2152 return f->nb_inputs == 0 &&
2153 (!strcmp(f->filter->name, "buffer") ||
2154 !strcmp(f->filter->name, "abuffer"));
2155}
2156
2158{
2159 for (unsigned i = 0; i < graph->nb_filters; i++) {
2160 const AVFilterContext *f = graph->filters[i];
2161
2162 /* in addition to filters flagged as meta, also
2163 * disregard sinks and buffersources (but not other sources,
2164 * since they introduce data we are not aware of)
2165 */
2166 if (!((f->filter->flags & AVFILTER_FLAG_METADATA_ONLY) ||
2167 f->nb_outputs == 0 ||
2169 return 0;
2170 }
2171 return 1;
2172}
2173
2174static int sub2video_frame(InputFilter *ifilter, AVFrame *frame, int buffer);
2175
2177{
2178 FilterGraphPriv *fgp = fgp_from_fg(fg);
2179 AVBufferRef *hw_device;
2180 AVFilterInOut *inputs, *outputs, *cur;
2181 int ret = AVERROR_BUG, i, simple = filtergraph_is_simple(fg);
2182 int have_input_eof = 0;
2183 const char *graph_desc = fg->graph_desc;
2184
2185 cleanup_filtergraph(fg, fgt);
2186 fgt->graph = avfilter_graph_alloc();
2187 if (!fgt->graph)
2188 return AVERROR(ENOMEM);
2189
2190 if (simple) {
2192
2193 if (filter_nbthreads) {
2194 ret = av_opt_set(fgt->graph, "threads", filter_nbthreads, 0);
2195 if (ret < 0)
2196 goto fail;
2197 } else if (fgp->nb_threads >= 0) {
2198 ret = av_opt_set_int(fgt->graph, "threads", fgp->nb_threads, 0);
2199 if (ret < 0)
2200 return ret;
2201 }
2202
2203 if (av_dict_count(ofp->sws_opts)) {
2204 ret = av_dict_get_string(ofp->sws_opts,
2205 &fgt->graph->scale_sws_opts,
2206 '=', ':');
2207 if (ret < 0)
2208 goto fail;
2209 }
2210
2211 if (av_dict_count(ofp->swr_opts)) {
2212 char *args;
2213 ret = av_dict_get_string(ofp->swr_opts, &args, '=', ':');
2214 if (ret < 0)
2215 goto fail;
2216 av_opt_set(fgt->graph, "aresample_swr_opts", args, 0);
2217 av_free(args);
2218 }
2219 } else {
2221 }
2222
2224 ret = av_opt_set_int(fgt->graph, "max_buffered_frames", filter_buffered_frames, 0);
2225 if (ret < 0)
2226 return ret;
2227 }
2228
2229 hw_device = hw_device_for_filter();
2230
2231 ret = graph_parse(fg, fgt->graph, graph_desc, &inputs, &outputs, hw_device);
2232 if (ret < 0)
2233 goto fail;
2234
2235 for (cur = inputs, i = 0; cur; cur = cur->next, i++)
2236 if ((ret = configure_input_filter(fg, fgt->graph, fg->inputs[i], cur)) < 0) {
2239 goto fail;
2240 }
2242
2243 for (cur = outputs, i = 0; cur; cur = cur->next, i++) {
2244 ret = configure_output_filter(fgp, fgt->graph, fg->outputs[i], cur);
2245 if (ret < 0) {
2247 goto fail;
2248 }
2249 }
2251
2252 if (fgp->disable_conversions)
2254 if ((ret = avfilter_graph_config(fgt->graph, NULL)) < 0)
2255 goto fail;
2256
2257 fgp->is_meta = graph_is_meta(fgt->graph);
2258
2259 /* limit the lists of allowed formats to the ones selected, to
2260 * make sure they stay the same if the filtergraph is reconfigured later */
2261 for (int i = 0; i < fg->nb_outputs; i++) {
2262 const AVFrameSideData *const *sd;
2263 int nb_sd;
2264 OutputFilter *ofilter = fg->outputs[i];
2265 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
2266 AVFilterContext *sink = ofilter->filter;
2267
2268 ofp->format = av_buffersink_get_format(sink);
2269
2270 ofp->width = av_buffersink_get_w(sink);
2271 ofp->height = av_buffersink_get_h(sink);
2276
2277 // If the timing parameters are not locked yet, get the tentative values
2278 // here but don't lock them. They will only be used if no output frames
2279 // are ever produced.
2280 if (!ofp->tb_out_locked) {
2282 if (ofp->fps.framerate.num <= 0 && ofp->fps.framerate.den <= 0 &&
2283 fr.num > 0 && fr.den > 0)
2284 ofp->fps.framerate = fr;
2286 }
2288
2291 ret = av_buffersink_get_ch_layout(sink, &ofp->ch_layout);
2292 if (ret < 0)
2293 goto fail;
2294 sd = av_buffersink_get_side_data(sink, &nb_sd);
2295 if (nb_sd)
2296 for (int j = 0; j < nb_sd; j++) {
2299 if (ret < 0) {
2301 goto fail;
2302 }
2303 }
2304 }
2305
2306 for (int i = 0; i < fg->nb_inputs; i++) {
2307 InputFilter *ifilter = fg->inputs[i];
2309 AVFrame *tmp;
2310 while (av_fifo_read(ifp->frame_queue, &tmp, 1) >= 0) {
2311 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
2312 sub2video_frame(&ifp->ifilter, tmp, !fgt->graph);
2313 } else {
2314 if (ifp->type_src == AVMEDIA_TYPE_VIDEO) {
2315 if (ifp->displaymatrix_applied)
2317 }
2318 ret = av_buffersrc_add_frame(ifilter->filter, tmp);
2319 }
2321 if (ret < 0)
2322 goto fail;
2323 }
2324 }
2325
2326 /* send the EOFs for the finished inputs */
2327 for (int i = 0; i < fg->nb_inputs; i++) {
2328 InputFilter *ifilter = fg->inputs[i];
2329 if (fgt->eof_in[i]) {
2330 ret = av_buffersrc_add_frame(ifilter->filter, NULL);
2331 if (ret < 0)
2332 goto fail;
2333 have_input_eof = 1;
2334 }
2335 }
2336
2337 if (have_input_eof) {
2338 // make sure the EOF propagates to the end of the graph
2340 if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
2341 goto fail;
2342 }
2343
2344 return 0;
2345fail:
2346 cleanup_filtergraph(fg, fgt);
2347 return ret;
2348}
2349
2351{
2352 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2353 AVFrameSideData *sd;
2354 int ret;
2355
2356 ret = av_buffer_replace(&ifp->hw_frames_ctx, frame->hw_frames_ctx);
2357 if (ret < 0)
2358 return ret;
2359
2360 ifp->time_base = (ifilter->type == AVMEDIA_TYPE_AUDIO) ? (AVRational){ 1, frame->sample_rate } :
2362 frame->time_base;
2363
2364 ifp->format = frame->format;
2365
2366 ifp->width = frame->width;
2367 ifp->height = frame->height;
2368 ifp->sample_aspect_ratio = frame->sample_aspect_ratio;
2369 ifp->color_space = frame->colorspace;
2370 ifp->color_range = frame->color_range;
2371 ifp->alpha_mode = frame->alpha_mode;
2372 ifp->chroma_location = frame->chroma_location;
2373
2374 ifp->sample_rate = frame->sample_rate;
2375 ret = av_channel_layout_copy(&ifp->ch_layout, &frame->ch_layout);
2376 if (ret < 0)
2377 return ret;
2378
2380 for (int i = 0; i < frame->nb_side_data; i++) {
2381 const AVSideDataDescriptor *desc = av_frame_side_data_desc(frame->side_data[i]->type);
2382
2383 if (!(desc->props & AV_SIDE_DATA_PROP_GLOBAL))
2384 continue;
2385
2387 &ifp->nb_side_data,
2388 frame->side_data[i], 0);
2389 if (ret < 0)
2390 return ret;
2391 }
2392
2394 if (sd) {
2395 memcpy(ifp->displaymatrix, sd->data, sizeof(ifp->displaymatrix));
2398 }
2399 ifp->displaymatrix_present = !!sd;
2400
2401 /* Copy downmix related side data to InputFilterPriv so it may be propagated
2402 * to the filter chain even though it's not "global", as filters like aresample
2403 * require this information during init and not when remixing a frame */
2405 if (sd) {
2407 &ifp->nb_side_data, sd, 0);
2408 if (ret < 0)
2409 return ret;
2410 memcpy(&ifp->downmixinfo, sd->data, sizeof(ifp->downmixinfo));
2411 }
2412 ifp->downmixinfo_present = !!sd;
2414 if (sd) {
2416 &ifp->nb_side_data, sd, 0);
2417 if (ret < 0)
2418 return ret;
2419 ret = av_buffer_replace(&ifp->downmixmatrix, sd->buf);
2420 if (ret < 0)
2421 return ret;
2422 ifp->downmixmatrix_size = sd->size;
2423 }
2424 ifp->downmixmatrix_present = !!sd;
2425
2426 return 0;
2427}
2428
2430{
2431 const OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
2432 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2433
2434 if (!ifp->opts.framerate.num) {
2435 ifp->opts.framerate = ofp->fps.framerate;
2436 if (ifp->opts.framerate.num > 0 && ifp->opts.framerate.den > 0)
2437 ifp->opts.flags |= IFILTER_FLAG_CFR;
2438 }
2439
2440 for (int i = 0; i < ofp->nb_side_data; i++) {
2441 int ret = av_frame_side_data_clone(&ifp->side_data, &ifp->nb_side_data,
2443 if (ret < 0)
2444 return ret;
2445 }
2446
2447 return 0;
2448}
2449
2451{
2452 const FilterGraphPriv *fgp = cfgp_from_cfg(fg);
2453 return fgp->is_simple;
2454}
2455
2457 double time, const char *target,
2458 const char *command, const char *arg, int all_filters)
2459{
2460 int ret;
2461
2462 if (!graph)
2463 return;
2464
2465 if (time < 0) {
2466 char response[4096];
2467 ret = avfilter_graph_send_command(graph, target, command, arg,
2468 response, sizeof(response),
2469 all_filters ? 0 : AVFILTER_CMD_FLAG_ONE);
2470 fprintf(stderr, "Command reply for stream %d: ret:%d res:\n%s",
2471 fg->index, ret, response);
2472 } else if (!all_filters) {
2473 fprintf(stderr, "Queuing commands only on filters supporting the specific command is unsupported\n");
2474 } else {
2475 ret = avfilter_graph_queue_command(graph, target, command, arg, 0, time);
2476 if (ret < 0)
2477 fprintf(stderr, "Queuing command failed with error %s\n", av_err2str(ret));
2478 }
2479}
2480
2481static int choose_input(const FilterGraph *fg, const FilterGraphThread *fgt)
2482{
2483 int nb_requests, nb_requests_max = -1;
2484 int best_input = -1;
2485
2486 for (int i = 0; i < fg->nb_inputs; i++) {
2487 InputFilter *ifilter = fg->inputs[i];
2488
2489 if (fgt->eof_in[i])
2490 continue;
2491
2492 nb_requests = av_buffersrc_get_nb_failed_requests(ifilter->filter);
2493 if (nb_requests > nb_requests_max) {
2494 nb_requests_max = nb_requests;
2495 best_input = i;
2496 }
2497 }
2498
2499 av_assert0(best_input >= 0);
2500
2501 return best_input;
2502}
2503
2505{
2506 OutputFilter *ofilter = &ofp->ofilter;
2507 FPSConvContext *fps = &ofp->fps;
2508 AVRational tb = (AVRational){ 0, 0 };
2509 AVRational fr;
2510 const FrameData *fd;
2511
2512 fd = frame_data_c(frame);
2513
2514 // apply -enc_time_base
2515 if (ofp->enc_timebase.num == ENC_TIME_BASE_DEMUX &&
2516 (fd->dec.tb.num <= 0 || fd->dec.tb.den <= 0)) {
2517 av_log(ofp, AV_LOG_ERROR,
2518 "Demuxing timebase not available - cannot use it for encoding\n");
2519 return AVERROR(EINVAL);
2520 }
2521
2522 switch (ofp->enc_timebase.num) {
2523 case 0: break;
2524 case ENC_TIME_BASE_DEMUX: tb = fd->dec.tb; break;
2525 case ENC_TIME_BASE_FILTER: tb = frame->time_base; break;
2526 default: tb = ofp->enc_timebase; break;
2527 }
2528
2529 if (ofilter->type == AVMEDIA_TYPE_AUDIO) {
2530 tb = tb.num ? tb : (AVRational){ 1, frame->sample_rate };
2531 goto finish;
2532 }
2533
2534 fr = fps->framerate;
2535 if (!fr.num) {
2537 if (fr_sink.num > 0 && fr_sink.den > 0)
2538 fr = fr_sink;
2539 }
2540
2541 if (fps->vsync_method == VSYNC_CFR || fps->vsync_method == VSYNC_VSCFR) {
2542 if (!fr.num && !fps->framerate_max.num) {
2543 fr = (AVRational){25, 1};
2545 "No information "
2546 "about the input framerate is available. Falling "
2547 "back to a default value of 25fps. Use the -r option "
2548 "if you want a different framerate.\n");
2549 }
2550
2551 if (fps->framerate_max.num &&
2552 (av_q2d(fr) > av_q2d(fps->framerate_max) ||
2553 !fr.den))
2554 fr = fps->framerate_max;
2555 }
2556
2557 if (fr.num > 0) {
2558 if (fps->framerate_supported) {
2559 int idx = av_find_nearest_q_idx(fr, fps->framerate_supported);
2560 fr = fps->framerate_supported[idx];
2561 }
2562 if (fps->framerate_clip) {
2563 av_reduce(&fr.num, &fr.den,
2564 fr.num, fr.den, fps->framerate_clip);
2565 }
2566 }
2567
2568 if (!(tb.num > 0 && tb.den > 0))
2569 tb = av_inv_q(fr);
2570 if (!(tb.num > 0 && tb.den > 0))
2571 tb = frame->time_base;
2572
2573 fps->framerate = fr;
2574finish:
2575 ofp->tb_out = tb;
2576 ofp->tb_out_locked = 1;
2577
2578 return 0;
2579}
2580
2581static double adjust_frame_pts_to_encoder_tb(void *logctx, AVFrame *frame,
2583{
2584 double float_pts = AV_NOPTS_VALUE; // this is identical to frame.pts but with higher precision
2585
2586 AVRational tb = tb_dst;
2587 AVRational filter_tb = frame->time_base;
2588 const int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16);
2589
2590 if (frame->pts == AV_NOPTS_VALUE)
2591 goto early_exit;
2592
2593 tb.den <<= extra_bits;
2594 float_pts = av_rescale_q(frame->pts, filter_tb, tb) -
2596 float_pts /= 1 << extra_bits;
2597 // when float_pts is not exactly an integer,
2598 // avoid exact midpoints to reduce the chance of rounding differences, this
2599 // can be removed in case the fps code is changed to work with integers
2600 if (float_pts != llrint(float_pts))
2601 float_pts += FFSIGN(float_pts) * 1.0 / (1<<17);
2602
2603 frame->pts = av_rescale_q(frame->pts, filter_tb, tb_dst) -
2605 frame->time_base = tb_dst;
2606
2607early_exit:
2608
2609 if (debug_ts) {
2610 av_log(logctx, AV_LOG_INFO,
2611 "filter -> pts:%s pts_time:%s exact:%f time_base:%d/%d\n",
2612 frame ? av_ts2str(frame->pts) : "NULL",
2613 av_ts2timestr(frame->pts, &tb_dst),
2614 float_pts, tb_dst.num, tb_dst.den);
2615 }
2616
2617 return float_pts;
2618}
2619
2621{
2622 int64_t max2, min2, m;
2623
2624 if (a >= b) {
2625 max2 = a;
2626 min2 = b;
2627 } else {
2628 max2 = b;
2629 min2 = a;
2630 }
2631 m = (c >= max2) ? max2 : c;
2632
2633 return (m >= min2) ? m : min2;
2634}
2635
2636
2637/* Convert frame timestamps to the encoder timebase and decide how many times
2638 * should this (and possibly previous) frame be repeated in order to conform to
2639 * desired target framerate (if any).
2640 */
2642 int64_t *nb_frames, int64_t *nb_frames_prev)
2643{
2644 OutputFilter *ofilter = &ofp->ofilter;
2645 FPSConvContext *fps = &ofp->fps;
2646 double delta0, delta, sync_ipts, duration;
2647
2648 if (!frame) {
2649 *nb_frames_prev = *nb_frames = median3(fps->frames_prev_hist[0],
2650 fps->frames_prev_hist[1],
2651 fps->frames_prev_hist[2]);
2652
2653 if (!*nb_frames && fps->last_dropped) {
2654 atomic_fetch_add(&ofilter->nb_frames_drop, 1);
2655 fps->last_dropped++;
2656 }
2657
2658 goto finish;
2659 }
2660
2661 duration = frame->duration * av_q2d(frame->time_base) / av_q2d(ofp->tb_out);
2662
2663 sync_ipts = adjust_frame_pts_to_encoder_tb(ofilter->graph, frame,
2664 ofp->tb_out, ofp->ts_offset);
2665 /* delta0 is the "drift" between the input frame and
2666 * where it would fall in the output. */
2667 delta0 = sync_ipts - ofp->next_pts;
2668 delta = delta0 + duration;
2669
2670 // tracks the number of times the PREVIOUS frame should be duplicated,
2671 // mostly for variable framerate (VFR)
2672 *nb_frames_prev = 0;
2673 /* by default, we output a single frame */
2674 *nb_frames = 1;
2675
2676 if (delta0 < 0 &&
2677 delta > 0 &&
2679 if (delta0 < -0.6) {
2680 av_log(ofp, AV_LOG_VERBOSE, "Past duration %f too large\n", -delta0);
2681 } else
2682 av_log(ofp, AV_LOG_DEBUG, "Clipping frame in rate conversion by %f\n", -delta0);
2683 sync_ipts = ofp->next_pts;
2684 duration += delta0;
2685 delta0 = 0;
2686 }
2687
2688 switch (fps->vsync_method) {
2689 case VSYNC_VSCFR:
2690 if (fps->frame_number == 0 && delta0 >= 0.5) {
2691 av_log(ofp, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta0));
2692 delta = duration;
2693 delta0 = 0;
2694 ofp->next_pts = llrint(sync_ipts);
2695 }
2697 case VSYNC_CFR:
2698 // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
2700 *nb_frames = 0;
2701 } else if (delta < -1.1)
2702 *nb_frames = 0;
2703 else if (delta > 1.1) {
2704 *nb_frames = llrintf(delta);
2705 if (delta0 > 1.1)
2706 *nb_frames_prev = llrintf(delta0 - 0.6);
2707 }
2708 frame->duration = 1;
2709 break;
2710 case VSYNC_VFR:
2711 if (delta <= -0.6)
2712 *nb_frames = 0;
2713 else if (delta > 0.6)
2714 ofp->next_pts = llrint(sync_ipts);
2715 frame->duration = llrint(duration);
2716 break;
2717 case VSYNC_PASSTHROUGH:
2718 ofp->next_pts = llrint(sync_ipts);
2719 frame->duration = llrint(duration);
2720 break;
2721 default:
2722 av_assert0(0);
2723 }
2724
2725finish:
2726 memmove(fps->frames_prev_hist + 1,
2727 fps->frames_prev_hist,
2728 sizeof(fps->frames_prev_hist[0]) * (FF_ARRAY_ELEMS(fps->frames_prev_hist) - 1));
2729 fps->frames_prev_hist[0] = *nb_frames_prev;
2730
2731 if (*nb_frames_prev == 0 && fps->last_dropped) {
2732 atomic_fetch_add(&ofilter->nb_frames_drop, 1);
2734 "*** dropping frame %"PRId64" at ts %"PRId64"\n",
2735 fps->frame_number, fps->last_frame->pts);
2736 }
2737 if (*nb_frames > (*nb_frames_prev && fps->last_dropped) + (*nb_frames > *nb_frames_prev)) {
2738 uint64_t nb_frames_dup;
2739 if (*nb_frames > dts_error_threshold * 30) {
2740 av_log(ofp, AV_LOG_ERROR, "%"PRId64" frame duplication too large, skipping\n", *nb_frames - 1);
2741 atomic_fetch_add(&ofilter->nb_frames_drop, 1);
2742 *nb_frames = 0;
2743 return;
2744 }
2745 nb_frames_dup = atomic_fetch_add(&ofilter->nb_frames_dup,
2746 *nb_frames - (*nb_frames_prev && fps->last_dropped) - (*nb_frames > *nb_frames_prev));
2747 av_log(ofp, AV_LOG_VERBOSE, "*** %"PRId64" dup!\n", *nb_frames - 1);
2748 if (nb_frames_dup > fps->dup_warning) {
2749 av_log(ofp, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", fps->dup_warning);
2750 fps->dup_warning *= 10;
2751 }
2752 }
2753
2754 fps->last_dropped = *nb_frames == *nb_frames_prev && frame;
2755 fps->dropped_keyframe |= fps->last_dropped && (frame->flags & AV_FRAME_FLAG_KEY);
2756}
2757
2759{
2761
2762 if (!ifp->eof) {
2764 ifp->eof = 1;
2765 }
2766}
2767
2769{
2771 int ret;
2772
2773 // we are finished and no frames were ever seen at this output,
2774 // at least initialize the encoder with a dummy frame
2775 if (!fgt->got_frame) {
2776 AVFrame *frame = fgt->frame;
2777 FrameData *fd;
2778
2779 frame->time_base = ofp->tb_out;
2780 frame->format = ofp->format;
2781
2782 frame->width = ofp->width;
2783 frame->height = ofp->height;
2784 frame->sample_aspect_ratio = ofp->sample_aspect_ratio;
2785
2786 frame->sample_rate = ofp->sample_rate;
2787 if (ofp->ch_layout.nb_channels) {
2788 ret = av_channel_layout_copy(&frame->ch_layout, &ofp->ch_layout);
2789 if (ret < 0)
2790 return ret;
2791 }
2792
2793 fd = frame_data(frame);
2794 if (!fd)
2795 return AVERROR(ENOMEM);
2796
2798 ret = clone_side_data(&fd->side_data, &fd->nb_side_data,
2799 ofp->side_data, ofp->nb_side_data, 0);
2800 if (ret < 0)
2801 return ret;
2802
2803 fd->frame_rate_filter = ofp->fps.framerate;
2804
2805 av_assert0(!frame->buf[0]);
2806
2808 "No filtered frames for output stream, trying to "
2809 "initialize anyway.\n");
2810
2811 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, frame);
2812 if (ret < 0) {
2814 return ret;
2815 }
2816 }
2817
2818 fgt->eof_out[ofp->ofilter.index] = 1;
2819
2820 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, NULL);
2821 return (ret == AVERROR_EOF) ? 0 : ret;
2822}
2823
2825 AVFrame *frame)
2826{
2828 AVFrame *frame_prev = ofp->fps.last_frame;
2829 enum AVMediaType type = ofp->ofilter.type;
2830
2831 int64_t nb_frames = !!frame, nb_frames_prev = 0;
2832
2833 if (type == AVMEDIA_TYPE_VIDEO && (frame || fgt->got_frame))
2834 video_sync_process(ofp, frame, &nb_frames, &nb_frames_prev);
2835
2836 for (int64_t i = 0; i < nb_frames; i++) {
2837 AVFrame *frame_out;
2838 int ret;
2839
2840 if (type == AVMEDIA_TYPE_VIDEO) {
2841 AVFrame *frame_in = (i < nb_frames_prev && frame_prev->buf[0]) ?
2842 frame_prev : frame;
2843 if (!frame_in)
2844 break;
2845
2846 frame_out = fgp->frame_enc;
2847 ret = av_frame_ref(frame_out, frame_in);
2848 if (ret < 0)
2849 return ret;
2850
2851 frame_out->pts = ofp->next_pts;
2852
2853 if (ofp->fps.dropped_keyframe) {
2854 frame_out->flags |= AV_FRAME_FLAG_KEY;
2855 ofp->fps.dropped_keyframe = 0;
2856 }
2857 } else {
2858 frame->pts = (frame->pts == AV_NOPTS_VALUE) ? ofp->next_pts :
2859 av_rescale_q(frame->pts, frame->time_base, ofp->tb_out) -
2861
2862 frame->time_base = ofp->tb_out;
2863 frame->duration = av_rescale_q(frame->nb_samples,
2864 (AVRational){ 1, frame->sample_rate },
2865 ofp->tb_out);
2866
2867 ofp->next_pts = frame->pts + frame->duration;
2868
2869 frame_out = frame;
2870 }
2871
2872 // send the frame to consumers
2873 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, frame_out);
2874 if (ret < 0) {
2875 av_frame_unref(frame_out);
2876
2877 if (!fgt->eof_out[ofp->ofilter.index]) {
2878 fgt->eof_out[ofp->ofilter.index] = 1;
2879 fgp->nb_outputs_done++;
2880 }
2881
2882 return ret == AVERROR_EOF ? 0 : ret;
2883 }
2884
2885 if (type == AVMEDIA_TYPE_VIDEO) {
2886 ofp->fps.frame_number++;
2887 ofp->next_pts++;
2888
2889 if (i == nb_frames_prev && frame)
2890 frame->flags &= ~AV_FRAME_FLAG_KEY;
2891 }
2892
2893 fgt->got_frame = 1;
2894 }
2895
2896 if (frame && frame_prev) {
2897 av_frame_unref(frame_prev);
2898 av_frame_move_ref(frame_prev, frame);
2899 }
2900
2901 if (!frame)
2902 return close_output(ofp, fgt);
2903
2904 return 0;
2905}
2906
2908 AVFrame *frame)
2909{
2912 FrameData *fd;
2913 int ret;
2914
2917 if (ret == AVERROR_EOF && !fgt->eof_out[ofp->ofilter.index]) {
2918 ret = fg_output_frame(ofp, fgt, NULL);
2919 return (ret < 0) ? ret : 1;
2920 } else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2921 return 1;
2922 } else if (ret < 0) {
2924 "Error in retrieving a frame from the filtergraph: %s\n",
2925 av_err2str(ret));
2926 return ret;
2927 }
2928
2929 if (fgt->eof_out[ofp->ofilter.index]) {
2931 return 0;
2932 }
2933
2935
2936 if (debug_ts)
2937 av_log(ofp, AV_LOG_INFO, "filter_raw -> pts:%s pts_time:%s time_base:%d/%d\n",
2938 av_ts2str(frame->pts), av_ts2timestr(frame->pts, &frame->time_base),
2939 frame->time_base.num, frame->time_base.den);
2940
2941 // Choose the output timebase the first time we get a frame.
2942 if (!ofp->tb_out_locked) {
2943 ret = choose_out_timebase(ofp, frame);
2944 if (ret < 0) {
2945 av_log(ofp, AV_LOG_ERROR, "Could not choose an output time base\n");
2947 return ret;
2948 }
2949 }
2950
2951 fd = frame_data(frame);
2952 if (!fd) {
2954 return AVERROR(ENOMEM);
2955 }
2956
2958 if (!fgt->got_frame) {
2959 ret = clone_side_data(&fd->side_data, &fd->nb_side_data,
2960 ofp->side_data, ofp->nb_side_data, 0);
2961 if (ret < 0) {
2963 return ret;
2964 }
2965 }
2966
2968
2969 // only use bits_per_raw_sample passed through from the decoder
2970 // if the filtergraph did not touch the frame data
2971 if (!fgp->is_meta)
2972 fd->bits_per_raw_sample = 0;
2973
2974 if (ofp->ofilter.type == AVMEDIA_TYPE_VIDEO) {
2975 if (!frame->duration) {
2977 if (fr.num > 0 && fr.den > 0)
2978 frame->duration = av_rescale_q(1, av_inv_q(fr), frame->time_base);
2979 }
2980
2981 fd->frame_rate_filter = ofp->fps.framerate;
2982 }
2983
2984 ret = fg_output_frame(ofp, fgt, frame);
2986 if (ret < 0)
2987 return ret;
2988
2989 return 0;
2990}
2991
2992/* retrieve all frames available at filtergraph outputs
2993 * and send them to consumers */
2995 AVFrame *frame)
2996{
2997 FilterGraphPriv *fgp = fgp_from_fg(fg);
2998
2999 // graph not configured, just select the input to request
3000 if (!fgt->graph) {
3001 for (int i = 0; i < fg->nb_inputs; i++) {
3003 if (ifp->format < 0 && !fgt->eof_in[i]) {
3004 fgt->next_in = i;
3005 return 0;
3006 }
3007 }
3008
3009 // This state - graph is not configured, but all inputs are either
3010 // initialized or EOF - should be unreachable because sending EOF to a
3011 // filter without even a fallback format should fail
3012 av_assert0(0);
3013 return AVERROR_BUG;
3014 }
3015
3016 if (fgp->nb_outputs_done < fg->nb_outputs) {
3017 int ret;
3018
3019 /* Reap all buffers present in the buffer sinks */
3020 for (int i = 0; i < fg->nb_outputs; i++) {
3022
3023 ret = 0;
3024 while (!ret) {
3025 ret = fg_output_step(ofp, fgt, frame);
3026 if (ret < 0)
3027 return ret;
3028 }
3029 }
3030
3031
3033 if (ret == AVERROR(EAGAIN)) {
3034 fgt->next_in = choose_input(fg, fgt);
3035 return 0;
3036 } else if (ret < 0) {
3037 if (ret == AVERROR_EOF)
3038 av_log(fg, AV_LOG_VERBOSE, "Filtergraph returned EOF, finishing\n");
3039 else
3040 av_log(fg, AV_LOG_ERROR,
3041 "Error requesting a frame from the filtergraph: %s\n",
3042 av_err2str(ret));
3043 return ret;
3044 }
3045 fgt->next_in = fg->nb_inputs;
3046
3047 // return so that scheduler can rate-control us
3048 return 0;
3049 }
3050
3051 return AVERROR_EOF;
3052}
3053
3055{
3056 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
3057 int64_t pts2;
3058
3059 /* subtitles seem to be usually muxed ahead of other streams;
3060 if not, subtracting a larger time here is necessary */
3061 pts2 = av_rescale_q(pts, tb, ifp->time_base) - 1;
3062
3063 /* do not send the heartbeat frame if the subtitle is already ahead */
3064 if (pts2 <= ifp->sub2video.last_pts)
3065 return;
3066
3067 if (pts2 >= ifp->sub2video.end_pts || ifp->sub2video.initialize)
3068 /* if we have hit the end of the current displayed subpicture,
3069 or if we need to initialize the system, update the
3070 overlaid subpicture and its start/end times */
3071 sub2video_update(ifp, pts2 + 1, NULL);
3072 else
3073 sub2video_push_ref(ifp, pts2);
3074}
3075
3077{
3078 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
3079 int ret;
3080
3081 if (buffer) {
3082 AVFrame *tmp;
3083
3084 if (!frame)
3085 return 0;
3086
3087 tmp = av_frame_alloc();
3088 if (!tmp)
3089 return AVERROR(ENOMEM);
3090
3092
3093 ret = av_fifo_write(ifp->frame_queue, &tmp, 1);
3094 if (ret < 0) {
3096 return ret;
3097 }
3098
3099 return 0;
3100 }
3101
3102 // heartbeat frame
3103 if (frame && !frame->buf[0]) {
3104 sub2video_heartbeat(ifilter, frame->pts, frame->time_base);
3105 return 0;
3106 }
3107
3108 if (!frame) {
3109 if (ifp->sub2video.end_pts < INT64_MAX)
3110 sub2video_update(ifp, INT64_MAX, NULL);
3111
3112 return av_buffersrc_add_frame(ifilter->filter, NULL);
3113 }
3114
3115 ifp->width = frame->width ? frame->width : ifp->width;
3116 ifp->height = frame->height ? frame->height : ifp->height;
3117
3118 sub2video_update(ifp, INT64_MIN, (const AVSubtitle*)frame->buf[0]->data);
3119
3120 return 0;
3121}
3122
3123static int send_eof(FilterGraphThread *fgt, InputFilter *ifilter,
3125{
3126 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
3127 int ret;
3128
3129 if (fgt->eof_in[ifilter->index])
3130 return 0;
3131
3132 fgt->eof_in[ifilter->index] = 1;
3133
3134 if (ifilter->filter) {
3135 pts = av_rescale_q_rnd(pts, tb, ifp->time_base,
3137
3139 if (ret < 0)
3140 return ret;
3141 } else {
3142 if (ifp->format < 0) {
3143 // the filtergraph was never configured, use the fallback parameters
3144 ifp->format = ifp->opts.fallback->format;
3145 ifp->sample_rate = ifp->opts.fallback->sample_rate;
3146 ifp->width = ifp->opts.fallback->width;
3147 ifp->height = ifp->opts.fallback->height;
3149 ifp->color_space = ifp->opts.fallback->colorspace;
3150 ifp->color_range = ifp->opts.fallback->color_range;
3151 ifp->alpha_mode = ifp->opts.fallback->alpha_mode;
3153 ifp->time_base = ifp->opts.fallback->time_base;
3154
3156 &ifp->opts.fallback->ch_layout);
3157 if (ret < 0)
3158 return ret;
3159
3161 ret = clone_side_data(&ifp->side_data, &ifp->nb_side_data,
3162 ifp->opts.fallback->side_data,
3163 ifp->opts.fallback->nb_side_data, 0);
3164 if (ret < 0)
3165 return ret;
3166
3167 if (ifilter_has_all_input_formats(ifilter->graph)) {
3168 ret = configure_filtergraph(ifilter->graph, fgt);
3169 if (ret < 0) {
3170 av_log(ifilter->graph, AV_LOG_ERROR, "Error initializing filters!\n");
3171 return ret;
3172 }
3173 }
3174 }
3175
3176 if (ifp->format < 0) {
3177 av_log(ifilter->graph, AV_LOG_ERROR,
3178 "Cannot determine format of input %s after EOF\n",
3179 ifp->opts.name);
3180 return AVERROR_INVALIDDATA;
3181 }
3182 }
3183
3184 return 0;
3185}
3186
3188 VIDEO_CHANGED = (1 << 0),
3189 AUDIO_CHANGED = (1 << 1),
3190 MATRIX_CHANGED = (1 << 2),
3193};
3194
3195static const char *unknown_if_null(const char *str)
3196{
3197 return str ? str : "unknown";
3198}
3199
3201 InputFilter *ifilter, AVFrame *frame, int force_reinit)
3202{
3203 FilterGraphPriv *fgp = fgp_from_fg(fg);
3204 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
3205 FrameData *fd;
3206 AVFrameSideData *sd;
3207 int need_reinit = 0, ret;
3208
3209 /* determine if the parameters for this input changed */
3210 switch (ifilter->type) {
3211 case AVMEDIA_TYPE_AUDIO:
3212 if (ifp->format != frame->format ||
3213 ifp->sample_rate != frame->sample_rate ||
3214 av_channel_layout_compare(&ifp->ch_layout, &frame->ch_layout))
3215 need_reinit |= AUDIO_CHANGED;
3216 break;
3217 case AVMEDIA_TYPE_VIDEO:
3218 if (ifp->format != frame->format ||
3219 ifp->width != frame->width ||
3220 ifp->height != frame->height ||
3221 ifp->color_space != frame->colorspace ||
3222 ifp->color_range != frame->color_range ||
3223 ifp->alpha_mode != frame->alpha_mode ||
3224 ifp->chroma_location != frame->chroma_location)
3225 need_reinit |= VIDEO_CHANGED;
3226 break;
3227 }
3228
3230 if (!ifp->displaymatrix_present ||
3231 memcmp(sd->data, ifp->displaymatrix, sizeof(ifp->displaymatrix)))
3232 need_reinit |= MATRIX_CHANGED;
3233 } else if (ifp->displaymatrix_present)
3234 need_reinit |= MATRIX_CHANGED;
3235
3237 if (!ifp->downmixinfo_present ||
3238 memcmp(sd->data, &ifp->downmixinfo, sizeof(ifp->downmixinfo)))
3239 need_reinit |= DOWNMIX_CHANGED;
3240 } else if (ifp->downmixinfo_present)
3241 need_reinit |= DOWNMIX_CHANGED;
3242
3244 if (!ifp->downmixmatrix_present ||
3245 sd->size != ifp->downmixmatrix_size || memcmp(sd->data, ifp->downmixmatrix->data, sd->size))
3246 need_reinit |= DOWNMIX_CHANGED;
3247 } else if (ifp->downmixmatrix_present)
3248 need_reinit |= DOWNMIX_CHANGED;
3249
3250 if (need_reinit && fgt->graph && (ifp->opts.flags & IFILTER_FLAG_DROPCHANGED)) {
3251 ifp->nb_dropped++;
3252 av_log_once(fg, AV_LOG_WARNING, AV_LOG_DEBUG, &ifp->drop_warned, "Avoiding reinit; dropping frame pts: %s bound for %s\n", av_ts2str(frame->pts), ifilter->name);
3254 return 0;
3255 }
3256
3257 if (!(ifp->opts.flags & IFILTER_FLAG_REINIT) && fgt->graph)
3258 need_reinit = 0;
3259
3260 if (!!ifp->hw_frames_ctx != !!frame->hw_frames_ctx ||
3261 (ifp->hw_frames_ctx && ifp->hw_frames_ctx->data != frame->hw_frames_ctx->data))
3262 need_reinit |= HWACCEL_CHANGED;
3263
3264 if (need_reinit) {
3265 ret = ifilter_parameters_from_frame(ifilter, frame);
3266 if (ret < 0)
3267 return ret;
3268
3269 /* Inputs bound to a filtergraph output will have some fields unset.
3270 * Handle them here */
3271 if (ifp->ofilter_src) {
3272 ret = ifilter_parameters_from_ofilter(ifilter, ifp->ofilter_src);
3273 if (ret < 0)
3274 return ret;
3275 }
3276 }
3277
3278 /* (re)init the graph if possible, otherwise buffer the frame and return */
3279 if (need_reinit || force_reinit || !fgt->graph) {
3281
3282 if (!tmp)
3283 return AVERROR(ENOMEM);
3284
3287
3288 ret = av_fifo_write(ifp->frame_queue, &tmp, 1);
3289 if (ret < 0)
3291
3292 return ret;
3293 }
3294
3295 ret = fgt->graph ? read_frames(fg, fgt, tmp) : 0;
3297 if (ret < 0)
3298 return ret;
3299
3300 if (fgt->graph) {
3301 AVBPrint reason;
3303 if (need_reinit & AUDIO_CHANGED) {
3304 const char *sample_format_name = av_get_sample_fmt_name(frame->format);
3305 av_bprintf(&reason, "audio parameters changed to %d Hz, ", frame->sample_rate);
3306 av_channel_layout_describe_bprint(&frame->ch_layout, &reason);
3307 av_bprintf(&reason, ", %s, ", unknown_if_null(sample_format_name));
3308 }
3309 if (need_reinit & VIDEO_CHANGED) {
3310 const char *pixel_format_name = av_get_pix_fmt_name(frame->format);
3311 const char *color_space_name = av_color_space_name(frame->colorspace);
3312 const char *color_range_name = av_color_range_name(frame->color_range);
3313 const char *alpha_mode = av_alpha_mode_name(frame->alpha_mode);
3314 const char *chroma_location = av_chroma_location_name(frame->chroma_location);
3315 av_bprintf(&reason, "video parameters changed to %s(%s, %s), %dx%d, %s alpha, %s chroma, ",
3316 unknown_if_null(pixel_format_name), unknown_if_null(color_range_name),
3317 unknown_if_null(color_space_name), frame->width, frame->height,
3318 unknown_if_null(alpha_mode), unknown_if_null(chroma_location));
3319 }
3320 if (need_reinit & MATRIX_CHANGED)
3321 av_bprintf(&reason, "display matrix changed, ");
3322 if (need_reinit & DOWNMIX_CHANGED)
3323 av_bprintf(&reason, "downmix medatata changed, ");
3324 if (need_reinit & HWACCEL_CHANGED)
3325 av_bprintf(&reason, "hwaccel changed, ");
3326 if (force_reinit)
3327 av_bprintf(&reason, "reinitialization arguments were provided, ");
3328 if (reason.len > 1)
3329 reason.str[reason.len - 2] = '\0'; // remove last comma
3330 av_log(fg, AV_LOG_INFO, "Reconfiguring filter graph%s%s\n", reason.len ? " because " : "", reason.str);
3331 } else {
3332 /* Choke all input to avoid buffering excessive frames while the
3333 * initial filter graph is being configured, and before we have a
3334 * preferred input */
3336 }
3337
3338 ret = configure_filtergraph(fg, fgt);
3339 if (ret < 0) {
3340 av_log(fg, AV_LOG_ERROR, "Error reinitializing filters!\n");
3341 return ret;
3342 }
3343 }
3344
3345 frame->pts = av_rescale_q(frame->pts, frame->time_base, ifp->time_base);
3346 frame->duration = av_rescale_q(frame->duration, frame->time_base, ifp->time_base);
3347 frame->time_base = ifp->time_base;
3348
3349 if (ifp->displaymatrix_applied)
3351
3352 fd = frame_data(frame);
3353 if (!fd)
3354 return AVERROR(ENOMEM);
3356
3359 if (ret < 0) {
3361 if (ret != AVERROR_EOF)
3362 av_log(fg, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret));
3363 return ret;
3364 }
3365
3366 return 0;
3367}
3368
3369static void fg_thread_set_name(const FilterGraph *fg)
3370{
3371 char name[16];
3372 if (filtergraph_is_simple(fg)) {
3374 snprintf(name, sizeof(name), "%cf%s",
3376 ofp->ofilter.output_name);
3377 } else {
3378 snprintf(name, sizeof(name), "fc%d", fg->index);
3379 }
3380
3382}
3383
3385{
3386 if (fgt->frame_queue_out) {
3387 AVFrame *frame;
3388 while (av_fifo_read(fgt->frame_queue_out, &frame, 1) >= 0)
3391 }
3392
3393 av_frame_free(&fgt->frame);
3394 av_freep(&fgt->eof_in);
3395 av_freep(&fgt->eof_out);
3396
3398
3399 memset(fgt, 0, sizeof(*fgt));
3400}
3401
3403{
3404 memset(fgt, 0, sizeof(*fgt));
3405
3406 fgt->frame = av_frame_alloc();
3407 if (!fgt->frame)
3408 goto fail;
3409
3410 fgt->eof_in = av_calloc(fg->nb_inputs, sizeof(*fgt->eof_in));
3411 if (!fgt->eof_in)
3412 goto fail;
3413
3414 fgt->eof_out = av_calloc(fg->nb_outputs, sizeof(*fgt->eof_out));
3415 if (!fgt->eof_out)
3416 goto fail;
3417
3419 if (!fgt->frame_queue_out)
3420 goto fail;
3421
3422 return 0;
3423
3424fail:
3425 fg_thread_uninit(fgt);
3426 return AVERROR(ENOMEM);
3427}
3428
3430{
3431 int ret, reinit = 0;
3432
3433 for (unsigned i = 0; i < fg->nb_outputs; i++) {
3435
3436 if (ofp->reinit_opts.pts == AV_NOPTS_VALUE && ofp->reinit_opts_fifo &&
3439 }
3440 if (ofp->reinit_opts.pts != AV_NOPTS_VALUE &&
3442 FrameData *fd = frame_data(fgt->frame);
3443 if (!fd)
3444 return AVERROR(ENOMEM);
3445
3447 ret = av_dict_copy(&fd->reinit_opts, ofp->reinit_opts.dict, 0);
3448 if (ret < 0)
3449 return ret;
3450
3451 av_opt_set_dict(ofp, &ofp->reinit_opts.dict);
3453
3456 else
3457 ofp->reinit_opts = (ReinitOpts){ .pts = AV_NOPTS_VALUE };
3458 reinit = 1;
3459 }
3460 }
3461
3462 return reinit;
3463}
3464
3465static int filter_thread(void *arg)
3466{
3467 FilterGraphPriv *fgp = arg;
3468 FilterGraph *fg = &fgp->fg;
3469
3471 int ret = 0, input_status = 0;
3472
3473 ret = fg_thread_init(&fgt, fg);
3474 if (ret < 0)
3475 goto finish;
3476
3478
3479 // if we have all input parameters the graph can now be configured
3481 ret = configure_filtergraph(fg, &fgt);
3482 if (ret < 0) {
3483 av_log(fg, AV_LOG_ERROR, "Error configuring filter graph: %s\n",
3484 av_err2str(ret));
3485 goto finish;
3486 }
3487 }
3488
3489 while (1) {
3490 InputFilter *ifilter;
3491 InputFilterPriv *ifp = NULL;
3492 enum FrameOpaque o;
3493 unsigned input_idx = fgt.next_in;
3494
3495 input_status = sch_filter_receive(fgp->sch, fgp->sch_idx,
3496 &input_idx, fgt.frame);
3497 if (input_status == AVERROR_EOF) {
3498 av_log(fg, AV_LOG_VERBOSE, "Filtering thread received EOF\n");
3499 break;
3500 } else if (input_status == AVERROR(EAGAIN)) {
3501 // should only happen when we didn't request any input
3502 av_assert0(input_idx == fg->nb_inputs);
3503 goto read_frames;
3504 }
3505 av_assert0(input_status >= 0);
3506
3507 o = (intptr_t)fgt.frame->opaque;
3508
3509 // message on the control stream
3510 if (input_idx == fg->nb_inputs) {
3512
3514
3515 fc = (FilterCommand*)fgt.frame->buf[0]->data;
3516 send_command(fg, fgt.graph, fc->time, fc->target, fc->command, fc->arg,
3517 fc->all_filters);
3518 av_frame_unref(fgt.frame);
3519 continue;
3520 }
3521
3522 // we received an input frame or EOF
3523 ifilter = fg->inputs[input_idx];
3524 ifp = ifp_from_ifilter(ifilter);
3525
3526 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
3527 int hb_frame = input_status >= 0 && o == FRAME_OPAQUE_SUB_HEARTBEAT;
3528 ret = sub2video_frame(ifilter, (fgt.frame->buf[0] || hb_frame) ? fgt.frame : NULL,
3529 !fgt.graph);
3530 } else if (fgt.frame->buf[0]) {
3531 ret = check_reinit(fg, &fgt);
3532 if (ret >= 0)
3533 ret = send_frame(fg, &fgt, ifilter, fgt.frame, ret);
3534 } else {
3536 ret = send_eof(&fgt, ifilter, fgt.frame->pts, fgt.frame->time_base);
3537 }
3538 av_frame_unref(fgt.frame);
3539 if (ret == AVERROR_EOF) {
3540 av_log(fg, AV_LOG_VERBOSE, "Input %u no longer accepts new data\n",
3541 input_idx);
3542 close_input(ifp);
3543 continue;
3544 }
3545 if (ret < 0)
3546 goto finish;
3547
3549 // retrieve all newly available frames
3550 ret = read_frames(fg, &fgt, fgt.frame);
3551 if (ret == AVERROR_EOF) {
3552 av_log(fg, AV_LOG_VERBOSE, "All consumers returned EOF\n");
3553 if (ifp && ifp->opts.flags & IFILTER_FLAG_DROPCHANGED)
3554 av_log(fg, AV_LOG_INFO, "Total changed input frames dropped : %"PRId64"\n", ifp->nb_dropped);
3555 break;
3556 } else if (ret < 0) {
3557 av_log(fg, AV_LOG_ERROR, "Error sending frames to consumers: %s\n",
3558 av_err2str(ret));
3559 goto finish;
3560 }
3561
3562 // ensure all inputs no longer accepting data are closed
3563 for (int i = 0; fgt.graph && i < fg->nb_inputs; i++) {
3566 close_input(ifp);
3567 }
3568 }
3569
3570 for (unsigned i = 0; i < fg->nb_outputs; i++) {
3572
3573 if (fgt.eof_out[i] || !fgt.graph)
3574 continue;
3575
3576 ret = fg_output_frame(ofp, &fgt, NULL);
3577 if (ret < 0)
3578 goto finish;
3579 }
3580
3581finish:
3582
3584 print_filtergraph(fg, fgt.graph);
3585
3586 // EOF is normal termination
3587 if (ret == AVERROR_EOF)
3588 ret = 0;
3589
3590 fg_thread_uninit(&fgt);
3591
3592 return ret;
3593}
3594
3595void fg_send_command(FilterGraph *fg, double time, const char *target,
3596 const char *command, const char *arg, int all_filters)
3597{
3598 FilterGraphPriv *fgp = fgp_from_fg(fg);
3599 AVBufferRef *buf;
3601
3602 fc = av_mallocz(sizeof(*fc));
3603 if (!fc)
3604 return;
3605
3606 buf = av_buffer_create((uint8_t*)fc, sizeof(*fc), filter_command_free, NULL, 0);
3607 if (!buf) {
3608 av_freep(&fc);
3609 return;
3610 }
3611
3612 fc->target = av_strdup(target);
3613 fc->command = av_strdup(command);
3614 fc->arg = av_strdup(arg);
3615 if (!fc->target || !fc->command || !fc->arg) {
3616 av_buffer_unref(&buf);
3617 return;
3618 }
3619
3620 fc->time = time;
3621 fc->all_filters = all_filters;
3622
3623 fgp->frame->buf[0] = buf;
3624 fgp->frame->opaque = (void*)(intptr_t)FRAME_OPAQUE_SEND_COMMAND;
3625
3626 sch_filter_command(fgp->sch, fgp->sch_idx, fgp->frame);
3627}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:97
static enum AVSampleFormat sample_fmts[]
Definition adpcmenc.c:933
static double val(void *priv, double ch)
Definition aeval.c:77
static const AVFilterPad inputs[]
Definition af_aap.c:299
static const AVFilterPad outputs[]
Definition af_aap.c:310
static const char *const format[]
Definition af_aiir.c:445
static FILE * out
static AVFormatContext * ctx
static void finish(void)
static AVDictionary * opts
int32_t
static int64_t fsize(FILE *f)
Definition audiomatch.c:29
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition avassert.h:58
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
Main libavfilter public API header.
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it.
Definition avio.c:691
int avio_open2(AVIOContext **s, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options)
Create and initialize a AVIOContext for accessing the resource indicated by url.
Definition avio.c:566
#define AVIO_FLAG_READ
read-only
Definition avio.h:617
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition aviobuf.c:326
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition aviobuf.c:615
char * av_asprintf(const char *fmt,...)
Definition avstring.c:115
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition avstring.c:103
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition bprint.c:121
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:68
AVBPrint public header.
#define AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_AUTOMATIC
memory buffer sink API for audio and video
Memory buffer source API.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define ss(width, name, subs,...)
Definition cbs_vp9.c:202
#define s(width, name)
Definition cbs_vp9.c:198
Public libavutil channel layout APIs header.
int stream_specifier_parse(StreamSpecifier *ss, const char *spec, int allow_remainder, void *logctx)
Parse a stream specifier string into a form suitable for matching.
Definition cmdutils.c:1009
void * allocate_array_elem(void *ptr, size_t elem_size, int *nb_elems)
Atomically add a new element to an array of pointers, i.e.
Definition cmdutils.c:1538
char * read_file_to_string(const char *filename)
Definition cmdutils.c:1569
unsigned stream_specifier_match(const StreamSpecifier *ss, const AVFormatContext *s, const AVStream *st, void *logctx)
Definition cmdutils.c:1224
double get_rotation(const int32_t *displaymatrix)
Definition cmdutils.c:1551
void stream_specifier_uninit(StreamSpecifier *ss)
Definition cmdutils.c:1000
#define av_clip
Definition common.h:100
#define FFSIGN(a)
Definition common.h:75
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static __device__ float fabs(float a)
static const int sample_rates[]
Definition dcaenc.h:34
static const uint16_t fc[]
Definition dcaenc.h:43
static AVFrame * frame
audio downmix medatata
const FrameData * frame_data_c(AVFrame *frame)
Definition ffmpeg.c:497
FrameData * frame_data(AVFrame *frame)
Get our axiliary frame data attached to the frame, allocating it if needed.
Definition ffmpeg.c:491
int nb_filtergraphs
Definition ffmpeg.c:115
InputFile ** input_files
Definition ffmpeg.c:108
const AVIOInterruptCB int_cb
Definition ffmpeg.c:322
int nb_input_files
Definition ffmpeg.c:109
FilterGraph ** filtergraphs
Definition ffmpeg.c:114
Decoder ** decoders
Definition ffmpeg.c:117
int nb_decoders
Definition ffmpeg.c:118
char * filter_nbthreads
Definition ffmpeg_opt.c:73
int debug_ts
Definition ffmpeg_opt.c:67
@ IFILTER_FLAG_CFR
Definition ffmpeg.h:254
@ IFILTER_FLAG_DROPCHANGED
Definition ffmpeg.h:256
@ IFILTER_FLAG_REINIT
Definition ffmpeg.h:253
@ IFILTER_FLAG_CROP
Definition ffmpeg.h:255
@ IFILTER_FLAG_AUTOROTATE
Definition ffmpeg.h:252
int view_specifier_parse(const char **pspec, ViewSpecifier *vs)
Definition ffmpeg_opt.c:306
int ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple, const ViewSpecifier *vs, InputFilterOptions *opts, SchedulerNode *src)
AVBufferRef * hw_device_for_filter(void)
Get a hardware device to be used with this filtergraph.
Definition ffmpeg_hw.c:298
@ LATENCY_PROBE_FILTER_POST
Definition ffmpeg.h:91
@ LATENCY_PROBE_FILTER_PRE
Definition ffmpeg.h:90
float dts_error_threshold
Definition ffmpeg_opt.c:57
@ VIEW_SPECIFIER_TYPE_NONE
Definition ffmpeg.h:105
int filter_complex_nbthreads
Definition ffmpeg_opt.c:74
float frame_drop_threshold
Definition ffmpeg_opt.c:59
FrameOpaque
Definition ffmpeg.h:75
@ FRAME_OPAQUE_SEND_COMMAND
Definition ffmpeg.h:78
@ FRAME_OPAQUE_SUB_HEARTBEAT
Definition ffmpeg.h:76
@ FRAME_OPAQUE_EOF
Definition ffmpeg.h:77
int print_graphs
Definition ffmpeg_opt.c:77
int auto_conversion_filters
Definition ffmpeg_opt.c:80
InputStream * ist_find_unused(enum AVMediaType type)
Find an unused input stream of given type.
@ OFILTER_FLAG_AUTOROTATE
Definition ffmpeg.h:291
@ OFILTER_FLAG_CROP
Definition ffmpeg.h:292
@ OFILTER_FLAG_AUDIO_24BIT
Definition ffmpeg.h:289
@ OFILTER_FLAG_AUTOSCALE
Definition ffmpeg.h:290
@ OFILTER_FLAG_DISABLE_CONVERT
Definition ffmpeg.h:287
VideoSyncMethod
Definition ffmpeg.h:56
@ VSYNC_VFR
Definition ffmpeg.h:60
@ VSYNC_PASSTHROUGH
Definition ffmpeg.h:58
@ VSYNC_CFR
Definition ffmpeg.h:59
@ VSYNC_VSCFR
Definition ffmpeg.h:61
char * print_graphs_file
Definition ffmpeg_opt.c:78
@ ENC_TIME_BASE_DEMUX
Definition ffmpeg.h:65
@ ENC_TIME_BASE_FILTER
Definition ffmpeg.h:66
int filter_buffered_frames
Definition ffmpeg_opt.c:75
int dec_filter_add(Decoder *dec, InputFilter *ifilter, InputFilterOptions *opts, const ViewSpecifier *vs, SchedulerNode *src)
ReinitReason
@ HWACCEL_CHANGED
@ DOWNMIX_CHANGED
@ AUDIO_CHANGED
@ VIDEO_CHANGED
@ MATRIX_CHANGED
static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter, int commit)
static int read_binary(void *logctx, const char *path, uint8_t **data, int *len)
static int ifilter_parameters_from_ofilter(InputFilter *ifilter, OutputFilter *ofilter)
static int choose_out_timebase(OutputFilterPriv *ofp, AVFrame *frame)
static int configure_input_filter(FilterGraph *fg, AVFilterGraph *graph, InputFilter *ifilter, AVFilterInOut *in)
static void fg_thread_set_name(const FilterGraph *fg)
static const FilterGraphPriv * cfgp_from_cfg(const FilterGraph *fg)
int fg_finalise_bindings(void)
static int bind_inputs(FilterGraph *fg, int commit)
static int configure_output_audio_filter(FilterGraphPriv *fgp, AVFilterGraph *graph, OutputFilter *ofilter, AVFilterInOut *out)
static int filter_thread(void *arg)
static void sub2video_prepare(InputFilterPriv *ifp)
static int ifilter_bind_dec(InputFilterPriv *ifp, Decoder *dec, const ViewSpecifier *vs)
static OutputFilterPriv * ofp_from_ofilter(OutputFilter *ofilter)
static FilterGraphPriv * fgp_from_fg(FilterGraph *fg)
static const AVClass fg_class
static void sub2video_push_ref(InputFilterPriv *ifp, int64_t pts)
static int configure_output_filter(FilterGraphPriv *fgp, AVFilterGraph *graph, OutputFilter *ofilter, AVFilterInOut *out)
void fg_send_command(FilterGraph *fg, double time, const char *target, const char *command, const char *arg, int all_filters)
static int fg_output_step(OutputFilterPriv *ofp, FilterGraphThread *fgt, AVFrame *frame)
static int choose_input(const FilterGraph *fg, const FilterGraphThread *fgt)
static int parse_reinit_opts(AVFifo **pout, const char *opts, void *logctx)
static int filter_is_buffersrc(const AVFilterContext *f)
static int configure_input_audio_filter(FilterGraph *fg, AVFilterGraph *graph, InputFilter *ifilter, AVFilterInOut *in)
static int graph_opts_apply(void *logctx, AVFilterGraphSegment *seg)
static OutputFilter * ofilter_alloc(FilterGraph *fg, enum AVMediaType type)
static int read_frames(FilterGraph *fg, FilterGraphThread *fgt, AVFrame *frame)
static int fg_output_frame(OutputFilterPriv *ofp, FilterGraphThread *fgt, AVFrame *frame)
static double adjust_frame_pts_to_encoder_tb(void *logctx, AVFrame *frame, AVRational tb_dst, int64_t start_time)
static int fg_thread_init(FilterGraphThread *fgt, const FilterGraph *fg)
static void fg_thread_uninit(FilterGraphThread *fgt)
static InputFilter * ifilter_alloc(FilterGraph *fg)
static void close_input(InputFilterPriv *ifp)
static int ofilter_bind_ifilter(OutputFilter *ofilter, InputFilterPriv *ifp, const OutputFilterOptions *opts)
static void sub2video_heartbeat(InputFilter *ifilter, int64_t pts, AVRational tb)
static int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
static int close_output(OutputFilterPriv *ofp, FilterGraphThread *fgt)
static void cleanup_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
static const char * unknown_if_null(const char *str)
static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h, AVSubtitleRect *r)
static int graph_parse(void *logctx, AVFilterGraph *graph, const char *desc, AVFilterInOut **inputs, AVFilterInOut **outputs, AVBufferRef *hw_device)
static int check_reinit(FilterGraph *fg, FilterGraphThread *fgt)
static char * describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in)
static const AVClass ofilter_class
static const char * fg_item_name(void *obj)
static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
int fg_create(FilterGraph **pfg, char **graph_desc, Scheduler *sch, const OutputFilterOptions *opts)
Create a new filtergraph in the global filtergraph list.
static int insert_trim(void *logctx, int64_t start_time, int64_t duration, AVFilterContext **last_filter, int *pad_idx, const char *filter_name)
static int sub2video_frame(InputFilter *ifilter, AVFrame *frame, int buffer)
#define AUTO_INSERT_FILTER(opt_name, filter_name, arg)
static int send_frame(FilterGraph *fg, FilterGraphThread *fgt, InputFilter *ifilter, AVFrame *frame, int force_reinit)
static int ifilter_has_all_input_formats(FilterGraph *fg)
static int ifilter_bind_ist(InputFilter *ifilter, InputStream *ist, const ViewSpecifier *vs)
static int configure_output_video_filter(FilterGraphPriv *fgp, AVFilterGraph *graph, OutputFilter *ofilter, AVFilterInOut *out)
int fg_create_simple(FilterGraph **pfg, InputStream *ist, char **graph_desc, Scheduler *sch, unsigned sched_idx_enc, const OutputFilterOptions *opts)
static int graph_is_meta(AVFilterGraph *graph)
int ofilter_bind_enc(OutputFilter *ofilter, unsigned sched_idx_enc, const OutputFilterOptions *opts)
static int sub2video_get_blank_frame(InputFilterPriv *ifp)
static void filter_command_free(void *opaque, uint8_t *data)
static int configure_input_video_filter(FilterGraph *fg, AVFilterGraph *graph, InputFilter *ifilter, AVFilterInOut *in)
static int send_eof(FilterGraphThread *fgt, InputFilter *ifilter, int64_t pts, AVRational tb)
static InputFilterPriv * ifp_from_ifilter(InputFilter *ifilter)
static int insert_filter(AVFilterContext **last_filter, int *pad_idx, const char *filter_name, const char *args)
#define DEF_CHOOSE_FORMAT(name, type, var, supported_list, none, printf_format, get_name)
int filtergraph_is_simple(const FilterGraph *fg)
static int filter_opt_apply(void *logctx, AVFilterContext *f, const char *key, const char *val)
static void video_sync_process(OutputFilterPriv *ofp, AVFrame *frame, int64_t *nb_frames, int64_t *nb_frames_prev)
static int set_channel_layout(OutputFilterPriv *f, const AVChannelLayout *layouts_allowed, const AVChannelLayout *layout_requested)
static void send_command(FilterGraph *fg, AVFilterGraph *graph, double time, const char *target, const char *command, const char *arg, int all_filters)
static int ifilter_bind_fg(InputFilterPriv *ifp, FilterGraph *fg_src, int out_idx)
static void sub2video_update(InputFilterPriv *ifp, int64_t heartbeat_pts, const AVSubtitle *sub)
void fg_free(FilterGraph **pfg)
static const AVOption ofilter_options[]
static const char * ofilter_item_name(void *obj)
const char * key
int sch_filter_send(Scheduler *sch, unsigned fg_idx, unsigned out_idx, AVFrame *frame)
Called by filtergraph tasks to send a filtered frame or EOF to consumers.
int sch_add_filtergraph(Scheduler *sch, unsigned nb_inputs, unsigned nb_outputs, SchThreadFunc func, void *ctx)
Add a filtergraph to the scheduler.
void sch_filter_receive_finish(Scheduler *sch, unsigned fg_idx, unsigned in_idx)
Called by filter tasks to signal that a filter input will no longer accept input.
void sch_remove_filtergraph(Scheduler *sch, int idx)
int sch_filter_receive(Scheduler *sch, unsigned fg_idx, unsigned *in_idx, AVFrame *frame)
Called by filtergraph tasks to obtain frames for filtering.
void sch_filter_choke_inputs(Scheduler *sch, unsigned fg_idx)
Called by filtergraph tasks to choke all filter inputs, preventing them from receiving more frames un...
int sch_connect(Scheduler *sch, SchedulerNode src, SchedulerNode dst)
int sch_filter_command(Scheduler *sch, unsigned fg_idx, AVFrame *frame)
#define SCH_FILTER_IN(filter, input)
#define SCH_ENC(encoder)
#define SCH_FILTER_OUT(filter, output)
static int clone_side_data(AVFrameSideData ***dst, int *nb_dst, AVFrameSideData *const *src, int nb_src, unsigned int flags)
Wrapper calling av_frame_side_data_clone() in a loop for all source entries.
static int64_t duration
Definition ffplay.c:399
static int64_t start_time
Definition ffplay.c:398
int print_filtergraph(FilterGraph *fg, AVFilterGraph *graph)
#define fail
Definition test.h:479
@ AV_OPT_TYPE_IMAGE_SIZE
Underlying C type is two consecutive integers.
Definition opt.h:302
@ AV_OPT_TYPE_PIXEL_FMT
Underlying C type is enum AVPixelFormat.
Definition opt.h:306
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition opt.h:285
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_CHLAYOUT
Underlying C type is AVChannelLayout.
Definition opt.h:330
@ SUBTITLE_BITMAP
A bitmap, pict will be set.
Definition avcodec.h:2058
@ AV_CODEC_ID_MPEG4
Definition codec_id.h:62
enum AVChromaLocation av_buffersink_get_chroma_location(const AVFilterContext *ctx)
int av_buffersink_get_sample_rate(const AVFilterContext *ctx)
int av_buffersink_get_format(const AVFilterContext *ctx)
AVRational av_buffersink_get_frame_rate(const AVFilterContext *ctx)
Definition buffersink.c:259
const AVFrameSideData *const * av_buffersink_get_side_data(const AVFilterContext *ctx, int *nb_side_data)
Definition buffersink.c:292
enum AVAlphaMode av_buffersink_get_alpha_mode(const AVFilterContext *ctx)
int av_buffersink_get_h(const AVFilterContext *ctx)
AVRational av_buffersink_get_sample_aspect_ratio(const AVFilterContext *ctx)
enum AVColorSpace av_buffersink_get_colorspace(const AVFilterContext *ctx)
int av_buffersink_get_ch_layout(const AVFilterContext *ctx, AVChannelLayout *out)
Definition buffersink.c:279
enum AVColorRange av_buffersink_get_color_range(const AVFilterContext *ctx)
AVRational av_buffersink_get_time_base(const AVFilterContext *ctx)
int av_buffersink_get_w(const AVFilterContext *ctx)
int attribute_align_arg av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags)
Get a frame with filtered data from sink and put it in frame.
Definition buffersink.c:138
#define AV_BUFFERSINK_FLAG_NO_REQUEST
Tell av_buffersink_get_buffer_ref() not to request a frame from its input.
Definition buffersink.h:93
int av_buffersrc_get_status(AVFilterContext *ctx)
Returns 0 or a negative AVERROR code.
Definition buffersrc.c:321
int av_buffersrc_parameters_set(AVFilterContext *ctx, AVBufferSrcParameters *param)
Initialize the buffersrc or abuffersrc filter with the provided parameters.
Definition buffersrc.c:131
int attribute_align_arg av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags)
Add a frame to the buffer source.
Definition buffersrc.c:221
int av_buffersrc_close(AVFilterContext *ctx, int64_t pts, unsigned flags)
Close the buffer source after EOF.
Definition buffersrc.c:312
int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame)
Add a frame to the buffer source.
Definition buffersrc.c:202
unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src)
Get the number of failed requests.
Definition buffersrc.c:373
AVBufferSrcParameters * av_buffersrc_parameters_alloc(void)
Allocate a new AVBufferSrcParameters instance.
Definition buffersrc.c:116
@ AV_BUFFERSRC_FLAG_KEEP_REF
Keep a reference to the frame.
Definition buffersrc.h:53
@ AV_BUFFERSRC_FLAG_PUSH
Immediately push the frame to the output.
Definition buffersrc.h:46
#define AVFILTER_FLAG_HWDEVICE
The filter can create hardware frames using AVFilterContext.hw_device_ctx.
Definition avfilter.h:193
int avfilter_init_str(AVFilterContext *filter, const char *args)
Initialize a filter with the supplied parameters.
Definition avfilter.c:965
int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
Check validity and configure all the links and formats in the graph.
const AVFilter * avfilter_get_by_name(const char *name)
Get a filter definition matching the given name.
Definition allfilters.c:656
void avfilter_inout_free(AVFilterInOut **inout)
Free the supplied list of AVFilterInOut and set *inout to NULL.
Definition graphparser.c:76
enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx)
Get the type of an AVFilterPad.
Definition avfilter.c:998
int avfilter_graph_segment_parse(AVFilterGraph *graph, const char *graph_str, int flags, AVFilterGraphSegment **seg)
Parse a textual filtergraph description into an intermediate form.
int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, int flags, double ts)
Queue a command for one or more filter instances.
void avfilter_graph_segment_free(AVFilterGraphSegment **seg)
Free the provided AVFilterGraphSegment and everything associated with it.
AVFilterContext * avfilter_graph_alloc_filter(AVFilterGraph *graph, const AVFilter *filter, const char *name)
Create a new filter instance in a filter graph.
const char * avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx)
Get the name of an AVFilterPad.
Definition avfilter.c:993
void avfilter_graph_free(AVFilterGraph **graph)
Free a graph, destroy its links, and set *graph to NULL.
int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options)
Initialize a filter with the supplied dictionary of options.
Definition avfilter.c:924
int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags)
Send a command to one or more filter instances.
int avfilter_graph_request_oldest(AVFilterGraph *graph)
Request a frame on the oldest sink link.
int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad)
Link two filters together.
Definition avfilter.c:149
int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt, const char *name, const char *args, void *opaque, AVFilterGraph *graph_ctx)
A convenience wrapper that allocates and initializes a filter in a single step.
#define AVFILTER_CMD_FLAG_ONE
Stop once a filter understood the command (for target=all for example), fast filters are favored auto...
Definition avfilter.h:452
int avfilter_graph_segment_apply(AVFilterGraphSegment *seg, int flags, AVFilterInOut **inputs, AVFilterInOut **outputs)
Apply all filter/link descriptions from a graph segment to the associated filtergraph.
int avfilter_graph_segment_create_filters(AVFilterGraphSegment *seg, int flags)
Create filters specified in a graph segment.
void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
Enable or disable automatic format conversion inside the graph.
AVFilterGraph * avfilter_graph_alloc(void)
Allocate a filter graph.
#define AVFILTER_FLAG_METADATA_ONLY
The filter is a "metadata" filter - it does not modify the frame data in any way.
Definition avfilter.h:188
@ AVFILTER_AUTO_CONVERT_NONE
all automatic conversions disabled
Definition avfilter.h:702
void av_channel_layout_default(AVChannelLayout *ch_layout, int nb_channels)
Get the default channel layout for a given number of channels.
int av_channel_layout_describe_bprint(const AVChannelLayout *channel_layout, AVBPrint *bp)
bprint variant of av_channel_layout_describe().
int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1)
Check whether two channel layouts are semantically the same, i.e.
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
int av_channel_layout_check(const AVChannelLayout *channel_layout)
Check whether a channel layout is valid, i.e.
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition bprint.h:218
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition bprint.c:234
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition bprint.c:129
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:140
int av_buffer_replace(AVBufferRef **pdst, const AVBufferRef *src)
Ensure dst refers to the same data as src.
Definition buffer.c:234
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition buffer.c:104
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition buffer.c:56
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:233
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition dict.c:42
int av_dict_get_string(const AVDictionary *m, char **buffer, const char key_val_sep, const char pairs_sep)
Get dictionary entries as a string.
Definition dict.c:260
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition dict.c:247
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition dict.c:86
int av_dict_parse_string(AVDictionary **pm, const char *str, const char *key_val_sep, const char *pairs_sep, int flags)
Parse the key/value pairs list and add the parsed entries to a dictionary.
Definition dict.c:210
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
Definition dict.c:37
#define AVERROR_FILTER_NOT_FOUND
Filter not found.
Definition error.h:60
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
#define AVERROR_OPTION_NOT_FOUND
Option not found.
Definition error.h:63
AVFifo * av_fifo_alloc2(size_t nb_elems, size_t elem_size, unsigned int flags)
Allocate and initialize an AVFifo with a given element size.
Definition fifo.c:47
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition fifo.c:286
#define AV_FIFO_FLAG_AUTO_GROW
Automatically resize the FIFO on writes, so that the data fits.
Definition fifo.h:63
size_t av_fifo_can_read(const AVFifo *f)
Definition fifo.c:87
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
Definition fifo.c:188
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition fifo.c:240
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition frame.h:694
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition frame.c:496
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition frame.c:659
void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
Remove and free all side data instances of the given type.
Definition frame.c:725
void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd)
Free all side data entries and their contents, then zeroes out the values which the pointers are poin...
Definition side_data.c:140
#define AV_FRAME_SIDE_DATA_FLAG_REPLACE
Don't add a new entry if another of the same type exists.
Definition frame.h:1105
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
Definition frame.c:206
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
Definition frame.c:523
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition frame.c:278
void av_frame_side_data_remove(AVFrameSideData ***sd, int *nb_sd, enum AVFrameSideDataType type)
Remove and free all side data instances of the given type from an array.
Definition side_data.c:109
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
const AVSideDataDescriptor * av_frame_side_data_desc(enum AVFrameSideDataType type)
Definition side_data.c:69
int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd, const AVFrameSideData *src, unsigned int flags)
Add a new side data entry to an array based on existing side data, taking a reference towards the con...
Definition side_data.c:255
static const AVFrameSideData * av_frame_side_data_get(AVFrameSideData *const *sd, const int nb_sd, enum AVFrameSideDataType type)
Wrapper around av_frame_side_data_get_c() to workaround the limitation that for any type T the conver...
Definition frame.h:1203
@ AV_SIDE_DATA_PROP_GLOBAL
The side data type can be used in stream-global structures.
Definition frame.h:348
@ AV_FRAME_DATA_DOWNMIX_MATRIX
Metadata relevant to a downmix procedure in the form of a remixig matrix.
Definition frame.h:307
@ AV_FRAME_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition frame.h:85
@ AV_FRAME_DATA_DOWNMIX_INFO
Metadata relevant to a downmix procedure.
Definition frame.h:73
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition log.h:204
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition rational.c:35
int av_find_nearest_q_idx(AVRational q, const AVRational *q_list)
Find the value in a list of rationals nearest a given reference rational.
Definition rational.c:144
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition rational.h:159
int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, enum AVRounding rnd)
Rescale a 64-bit integer by 2 rational numbers with specified rounding.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
@ AV_ROUND_PASS_MINMAX
Flag telling rescaling functions to pass INT64_MIN/MAX through unchanged, avoiding special cases for ...
@ AV_ROUND_NEAR_INF
Round to nearest and halfway cases away from zero.
int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem)
Add an element to a dynamic array.
Definition mem.c:419
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition utils.c:28
AVMediaType
Definition avutil.h:198
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_SUBTITLE
Definition avutil.h:203
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
const char * av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
Return the name of sample_fmt, or NULL if sample_fmt is not recognized.
Definition samplefmt.c:52
AVSampleFormat
Audio sample formats.
Definition samplefmt.h:55
@ AV_SAMPLE_FMT_NONE
Definition samplefmt.h:56
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
Definition avstring.c:179
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition avstring.c:36
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition avstring.c:85
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition avutil.h:263
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
#define AV_OPT_SEARCH_CHILDREN
Search in possible children of the given object first.
Definition opt.h:604
const AVOption * av_opt_find(void *obj, const char *name, const char *unit, int opt_flags, int search_flags)
Look for an option in an object.
Definition opt.c:2071
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
Definition opt.c:1758
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
Definition opt.c:938
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition opt.c:891
int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags)
Definition opt.c:953
int av_opt_set_dict(void *obj, AVDictionary **options)
Set all the options from a given dictionary on an object.
Definition opt.c:2066
int a
const pixel * src2
if(svq3)
#define r
Definition input.c:42
#define b
Definition input.c:43
#define av_log2
Definition intmath.h:84
#define extra_bits(eb)
Definition intrax8.c:120
static void reinit(Jpeg2000EncoderContext *s)
Definition j2kenc.c:1459
uint32_t type
Definition jpegmpfenc.c:80
const char * arg
Definition jacosubdec.c:65
Macro definitions for various function/variable attributes.
#define av_fallthrough
Definition attributes.h:67
static int ff_thread_setname(const char *name)
Definition thread.h:216
static enum AVPixelFormat pix_fmts[]
Definition libkvazaar.c:296
#define lrintf(x)
Definition libm_mips.h:74
const char * desc
Definition libsvtav1.c:83
uint8_t w
Definition llvidencdsp.c:39
void av_log_once(void *avcl, int initial_level, int subsequent_level, int *state, const char *fmt,...)
Definition log.c:450
@ AV_CLASS_CATEGORY_FILTER
Definition log.h:36
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:370
Memory handling functions.
static const char * obj
Definition mscl.c:57
const char data[16]
Definition mxf.c:149
#define av_strdup(s)
Definition ops_static.c:55
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
const char * av_color_space_name(enum AVColorSpace space)
Definition pixdesc.c:3884
const char * av_color_range_name(enum AVColorRange range)
Definition pixdesc.c:3800
const char * av_alpha_mode_name(enum AVAlphaMode mode)
Definition pixdesc.c:3949
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition pixdesc.c:3404
const char * av_chroma_location_name(enum AVChromaLocation location)
Definition pixdesc.c:3905
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3484
#define AV_PIX_FMT_FLAG_HWACCEL
Pixel format is an HW accelerated format.
Definition pixdesc.h:128
pixel format definitions
AVChromaLocation
Location of chroma samples.
Definition pixfmt.h:807
@ AVCHROMA_LOC_UNSPECIFIED
Definition pixfmt.h:808
AVColorRange
Visual content value range.
Definition pixfmt.h:753
@ AVCOL_RANGE_UNSPECIFIED
Definition pixfmt.h:754
AVAlphaMode
Correlation between the alpha channel and color values.
Definition pixfmt.h:821
@ AVALPHA_MODE_UNSPECIFIED
Unknown alpha handling, or no alpha channel.
Definition pixfmt.h:822
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
#define AV_PIX_FMT_RGB32
Definition pixfmt.h:520
AVColorSpace
YUV colorspace type.
Definition pixfmt.h:711
@ AVCOL_SPC_UNSPECIFIED
Definition pixfmt.h:714
const char * name
Definition qsvenc.c:142
#define FF_ARRAY_ELEMS(a)
#define median3(a, b, c)
Definition speexdec.c:617
#define atomic_fetch_add(object, operand)
Definition stdatomic.h:312
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
This structure contains the parameters describing the frames that will be passed to this filter.
Definition buffersrc.h:73
AVRational frame_rate
Video only, the frame rate of the input video.
Definition buffersrc.h:100
AVFrameSideData ** side_data
Definition buffersrc.h:124
enum AVColorRange color_range
Definition buffersrc.h:122
int format
video: the pixel format, value corresponds to enum AVPixelFormat audio: the sample format,...
Definition buffersrc.h:78
int width
Video only, the display dimensions of the input frames.
Definition buffersrc.h:87
enum AVColorSpace color_space
Video only, the YUV colorspace and range.
Definition buffersrc.h:121
enum AVAlphaMode alpha_mode
Video only, the alpha mode.
Definition buffersrc.h:130
AVRational time_base
The timebase to be used for the timestamps on the input frames.
Definition buffersrc.h:82
AVBufferRef * hw_frames_ctx
Video with a hwaccel pixel format only.
Definition buffersrc.h:106
AVRational sample_aspect_ratio
Video only, the sample (pixel) aspect ratio.
Definition buffersrc.h:92
enum AVChromaLocation chroma_location
Video only, the chroma sample location.
Definition buffersrc.h:135
An AVChannelLayout holds information about the channel layout of audio data.
enum AVChannelOrder order
Channel order used in this layout.
int nb_channels
Number of channels in this layout.
Describe the class of an AVClass context structure.
Definition log.h:76
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
char * key
Definition dict.h:91
char * value
Definition dict.h:92
This structure describes optional metadata relevant to a downmix procedure.
Definition fifo.c:35
A filterchain is a list of filter specifications.
Definition avfilter.h:915
size_t nb_filters
Definition avfilter.h:917
AVFilterParams ** filters
Definition avfilter.h:916
An instance of a filter.
Definition avfilter.h:279
A parsed representation of a filtergraph segment.
Definition avfilter.h:929
AVFilterChain ** chains
A list of filter chain contained in this segment.
Definition avfilter.h:940
unsigned nb_filters
Definition avfilter.h:575
char * scale_sws_opts
sws options to use for the auto-inserted scale filters
Definition avfilter.h:577
AVFilterContext ** filters
Definition avfilter.h:574
int nb_threads
Maximum number of threads used by filters in this graph.
Definition avfilter.h:598
A linked-list of the inputs/outputs of the filter chain.
Definition avfilter.h:729
AVFilterContext * filter_ctx
filter context associated to this input/output
Definition avfilter.h:734
int pad_idx
index of the filt_ctx pad to use for linking
Definition avfilter.h:737
struct AVFilterInOut * next
next input/input in the list, NULL if this is the last
Definition avfilter.h:740
A filter pad used for either input or output.
Definition filters.h:40
Parameters describing a filter to be created in a filtergraph.
Definition avfilter.h:848
Filter definition.
Definition avfilter.h:221
Format I/O context.
Definition avformat.h:1337
Structure to hold side data for an AVFrame.
Definition frame.h:334
size_t size
Definition frame.h:337
uint8_t * data
Definition frame.h:336
AVBufferRef * buf
Definition frame.h:339
This structure describes decoded (raw) audio or video data.
Definition frame.h:479
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition frame.h:581
enum AVChromaLocation chroma_location
Definition frame.h:743
int width
Definition frame.h:551
AVRational time_base
Time base for the timestamps in this frame.
Definition frame.h:596
void * opaque
Frame owner's private data.
Definition frame.h:617
int height
Definition frame.h:551
AVFrameSideData ** side_data
Definition frame.h:676
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition frame.h:723
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition frame.h:656
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition frame.h:576
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition frame.h:730
int nb_side_data
Definition frame.h:677
enum AVColorSpace colorspace
YUV colorspace type.
Definition frame.h:741
enum AVAlphaMode alpha_mode
Indicates how the alpha channel of the video is to be handled.
Definition frame.h:834
int sample_rate
Sample rate of the audio data.
Definition frame.h:642
AVChannelLayout ch_layout
Channel layout of the audio data.
Definition frame.h:822
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition frame.h:566
Bytestream IO Context.
Definition avio.h:160
AVOption.
Definition opt.h:428
enum AVOptionType type
Definition opt.h:444
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
This struct describes the properties of a side data type.
Definition frame.h:382
Stream structure.
Definition avformat.h:768
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:791
int index
stream index in AVFormatContext
Definition avformat.h:774
uint32_t start_display_time
Definition avcodec.h:2104
uint32_t end_display_time
Definition avcodec.h:2105
unsigned num_rects
Definition avcodec.h:2106
AVSubtitleRect ** rects
Definition avcodec.h:2107
int64_t pts
Same as packet pts, in AV_TIME_BASE.
Definition avcodec.h:2108
enum AVMediaType type
Definition ffmpeg.h:457
AVFrame * last_frame
const AVRational * framerate_supported
int64_t frames_prev_hist[3]
uint64_t dup_warning
AVRational framerate
enum VideoSyncMethod vsync_method
AVRational framerate_max
unsigned nb_outputs_done
AVFrame * frame_enc
Scheduler * sch
FilterGraph fg
AVFifo * frame_queue_out
AVFilterGraph * graph
const AVClass * class
Definition ffmpeg.h:403
int index
Definition ffmpeg.h:404
int nb_outputs
Definition ffmpeg.h:409
int is_internal
Definition ffmpeg.h:414
OutputFilter ** outputs
Definition ffmpeg.h:408
int nb_inputs
Definition ffmpeg.h:407
const char * graph_desc
Definition ffmpeg.h:416
InputFilter ** inputs
Definition ffmpeg.h:406
struct FrameData::@304126211346234154321045014345346376220164157123 dec
AVRational frame_rate_filter
Definition ffmpeg.h:720
int64_t wallclock[LATENCY_PROBE_NB]
Definition ffmpeg.h:724
int nb_side_data
Definition ffmpeg.h:729
int bits_per_raw_sample
Definition ffmpeg.h:722
AVFrameSideData ** side_data
Definition ffmpeg.h:728
AVDictionary * reinit_opts
Definition ffmpeg.h:731
AVRational tb
Definition ffmpeg.h:717
int index
Definition ffmpeg.h:514
uint8_t * name
Definition ffmpeg.h:263
AVRational framerate
Definition ffmpeg.h:270
int64_t trim_end_us
Definition ffmpeg.h:261
unsigned flags
Definition ffmpeg.h:281
int64_t trim_start_us
Definition ffmpeg.h:260
unsigned crop_bottom
Definition ffmpeg.h:273
unsigned crop_right
Definition ffmpeg.h:275
AVFrame * fallback
Definition ffmpeg.h:283
unsigned crop_left
Definition ffmpeg.h:274
unsigned crop_top
Definition ffmpeg.h:272
InputFilterOptions opts
AVChannelLayout ch_layout
AVFrameSideData ** side_data
AVDownmixInfo downmixinfo
struct InputFilterPriv::@246267011247332065017016360253132152152335164263 sub2video
AVRational sample_aspect_ratio
AVBufferRef * hw_frames_ctx
InputFilter ifilter
int32_t displaymatrix[9]
enum AVColorSpace color_space
AVRational time_base
AVBufferRef * downmixmatrix
OutputFilter * ofilter_src
enum AVAlphaMode alpha_mode
enum AVColorRange color_range
enum AVChromaLocation chroma_location
unsigned int initialize
marks if sub2video_update should force an initialization
enum AVMediaType type_src
size_t downmixmatrix_size
uint8_t * name
Definition ffmpeg.h:363
AVFilterContext * filter
Definition ffmpeg.h:369
uint8_t * linklabel
Definition ffmpeg.h:375
char * input_name
Definition ffmpeg.h:371
enum AVMediaType type
Definition ffmpeg.h:367
struct FilterGraph * graph
Definition ffmpeg.h:362
int index
Definition ffmpeg.h:364
int index
Definition ffmpeg.h:474
struct InputFile * file
Definition ffmpeg.h:472
AVCodecParameters * par
Codec parameters - to be used by the decoding/streamcopy code.
Definition ffmpeg.h:484
AVStream * st
Definition ffmpeg.h:476
enum AVColorRange * color_ranges
enum AVChromaLocation chroma_location
AVRational enc_timebase
enum AVPixelFormat * pix_fmts
ReinitOpts reinit_opts
AVFifo * reinit_opts_fifo
AVDictionary * swr_opts
AVChannelLayout ch_layout
enum AVChromaLocation * chroma_locations
enum AVColorSpace color_space
OutputFilter ofilter
enum AVAlphaMode alpha_mode
FPSConvContext fps
enum AVColorRange color_range
AVRational sample_aspect_ratio
enum AVSampleFormat * sample_fmts
int32_t displaymatrix[9]
const int * sample_rates
const AVChannelLayout * ch_layouts
AVDictionary * sws_opts
enum AVAlphaMode * alpha_modes
enum AVColorSpace * color_spaces
AVFrameSideData ** side_data
atomic_uint_least64_t nb_frames_drop
Definition ffmpeg.h:399
AVFilterContext * filter
Definition ffmpeg.h:385
char * output_name
Definition ffmpeg.h:387
uint8_t * name
Definition ffmpeg.h:382
uint8_t * linklabel
Definition ffmpeg.h:392
atomic_uint_least64_t nb_frames_dup
Definition ffmpeg.h:398
struct FilterGraph * graph
Definition ffmpeg.h:381
char * apad
Definition ffmpeg.h:394
const AVClass * class
Definition ffmpeg.h:379
enum AVMediaType type
Definition ffmpeg.h:396
AVDictionary * dict
#define llrint
Definition tablegen.h:47
#define av_free(p)
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
void(* filter)(uint8_t *src, ptrdiff_t stride, int qscale)
Definition h263dsp.c:29
#define src
Definition vp8dsp.c:248
static char buffer[20]
Definition seek.c:32
#define width
Definition dsp.h:99
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition time.c:57
timestamp utils, mostly useful for debugging/logging purposes
#define av_ts2str(ts)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition timestamp.h:54
#define av_ts2timestr(ts, tb)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition timestamp.h:83
static int64_t pts
static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
color_range
float delta
int len
static double c[64]