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
202#define NEEDED_EXPLICIT 1
203#define NEEDED_INTERNAL 2
205
206 /* desired output stream properties */
215
216 unsigned crop_top;
217 unsigned crop_bottom;
218 unsigned crop_left;
219 unsigned crop_right;
220
223
224 // time base in which the output is sent to our downstream
225 // does not need to match the filtersink's timebase
227 // at least one frame with the above timebase was sent
228 // to our downstream, so it cannot change anymore
230
232
235
236 // those are only set if no format is specified and the encoder gives us multiple options
237 // They point directly to the relevant lists of the encoder.
238 union {
241 };
243 const int *sample_rates;
248
250
254 // offset for output timestamps, in AV_TIME_BASE_Q
258
261
262 unsigned flags;
264
266{
267 return (OutputFilterPriv*)ofilter;
268}
269
270typedef struct FilterCommand {
271 char *target;
272 char *command;
273 char *arg;
274
275 double time;
278
279static void filter_command_free(void *opaque, uint8_t *data)
280{
282
283 av_freep(&fc->target);
284 av_freep(&fc->command);
285 av_freep(&fc->arg);
286
287 av_free(data);
288}
289
291{
293 int ret;
294
296
297 frame->width = ifp->width;
298 frame->height = ifp->height;
299 frame->format = ifp->format;
300 frame->colorspace = ifp->color_space;
301 frame->color_range = ifp->color_range;
302 frame->alpha_mode = ifp->alpha_mode;
303 frame->chroma_location = ifp->chroma_location;
304
306 if (ret < 0)
307 return ret;
308
309 memset(frame->data[0], 0, frame->height * frame->linesize[0]);
310
311 return 0;
312}
313
314static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h,
316{
317 uint32_t *pal, *dst2;
318 uint8_t *src, *src2;
319 int x, y;
320
321 if (r->type != SUBTITLE_BITMAP) {
322 av_log(NULL, AV_LOG_WARNING, "sub2video: non-bitmap subtitle\n");
323 return;
324 }
325 if (r->x < 0 || r->x + r->w > w || r->y < 0 || r->y + r->h > h) {
326 av_log(NULL, AV_LOG_WARNING, "sub2video: rectangle (%d %d %d %d) overflowing %d %d\n",
327 r->x, r->y, r->w, r->h, w, h
328 );
329 return;
330 }
331
332 dst += r->y * dst_linesize + r->x * 4;
333 src = r->data[0];
334 pal = (uint32_t *)r->data[1];
335 for (y = 0; y < r->h; y++) {
336 dst2 = (uint32_t *)dst;
337 src2 = src;
338 for (x = 0; x < r->w; x++)
339 *(dst2++) = pal[*(src2++)];
340 dst += dst_linesize;
341 src += r->linesize[0];
342 }
343}
344
346{
348 int ret;
349
350 av_assert1(frame->data[0]);
351 ifp->sub2video.last_pts = frame->pts = pts;
355 if (ret != AVERROR_EOF && ret < 0)
357 "Error while add the frame to buffer source(%s).\n",
358 av_err2str(ret));
359}
360
361static void sub2video_update(InputFilterPriv *ifp, int64_t heartbeat_pts,
362 const AVSubtitle *sub)
363{
365 uint8_t *dst;
366 int dst_linesize;
367 int num_rects;
368 int64_t pts, end_pts;
369
370 if (sub) {
371 pts = av_rescale_q(sub->pts + sub->start_display_time * 1000LL,
373 end_pts = av_rescale_q(sub->pts + sub->end_display_time * 1000LL,
375 num_rects = sub->num_rects;
376 } else {
377 /* If we are initializing the system, utilize current heartbeat
378 PTS as the start time, and show until the following subpicture
379 is received. Otherwise, utilize the previous subpicture's end time
380 as the fall-back value. */
381 pts = ifp->sub2video.initialize ?
382 heartbeat_pts : ifp->sub2video.end_pts;
383 end_pts = INT64_MAX;
384 num_rects = 0;
385 }
386 if (sub2video_get_blank_frame(ifp) < 0) {
388 "Impossible to get a blank canvas.\n");
389 return;
390 }
391 dst = frame->data [0];
392 dst_linesize = frame->linesize[0];
393 for (int i = 0; i < num_rects; i++)
394 sub2video_copy_rect(dst, dst_linesize, frame->width, frame->height, sub->rects[i]);
396 ifp->sub2video.end_pts = end_pts;
397 ifp->sub2video.initialize = 0;
398}
399
400/* Define a function for appending a list of allowed formats
401 * to an AVBPrint. If nonempty, the list will have a header. */
402#define DEF_CHOOSE_FORMAT(name, type, var, supported_list, none, printf_format, get_name) \
403static void choose_ ## name (OutputFilterPriv *ofp, AVBPrint *bprint) \
404{ \
405 if (ofp->var == none && !ofp->supported_list) \
406 return; \
407 av_bprintf(bprint, #name "="); \
408 if (ofp->var != none) { \
409 av_bprintf(bprint, printf_format, get_name(ofp->var)); \
410 } else { \
411 const type *p; \
412 \
413 for (p = ofp->supported_list; *p != none; p++) { \
414 av_bprintf(bprint, printf_format "|", get_name(*p)); \
415 } \
416 if (bprint->len > 0) \
417 bprint->str[--bprint->len] = '\0'; \
418 } \
419 av_bprint_chars(bprint, ':', 1); \
420}
421
424
427
429 "%d", )
430
431DEF_CHOOSE_FORMAT(color_spaces, enum AVColorSpace, color_space, color_spaces,
433
434DEF_CHOOSE_FORMAT(color_ranges, enum AVColorRange, color_range, color_ranges,
436
437DEF_CHOOSE_FORMAT(alpha_modes, enum AVAlphaMode, alpha_mode, alpha_modes,
439
440DEF_CHOOSE_FORMAT(chroma_locations, enum AVChromaLocation, chroma_location,
441 chroma_locations, AVCHROMA_LOC_UNSPECIFIED, "%s",
443
444static void choose_channel_layouts(OutputFilterPriv *ofp, AVBPrint *bprint)
445{
446 if (av_channel_layout_check(&ofp->ch_layout)) {
447 av_bprintf(bprint, "channel_layouts=");
448 av_channel_layout_describe_bprint(&ofp->ch_layout, bprint);
449 } else if (ofp->ch_layouts) {
450 const AVChannelLayout *p;
451
452 av_bprintf(bprint, "channel_layouts=");
453 for (p = ofp->ch_layouts; p->nb_channels; p++) {
454 av_channel_layout_describe_bprint(p, bprint);
455 av_bprintf(bprint, "|");
456 }
457 if (bprint->len > 0)
458 bprint->str[--bprint->len] = '\0';
459 } else
460 return;
461 av_bprint_chars(bprint, ':', 1);
462}
463
464static int read_binary(void *logctx, const char *path,
465 uint8_t **data, int *len)
466{
467 AVIOContext *io = NULL;
469 int ret;
470
471 *data = NULL;
472 *len = 0;
473
475 if (ret < 0) {
476 av_log(logctx, AV_LOG_ERROR, "Cannot open file '%s': %s\n",
478 return ret;
479 }
480
481 fsize = avio_size(io);
482 if (fsize < 0 || fsize > INT_MAX) {
483 av_log(logctx, AV_LOG_ERROR, "Cannot obtain size of file %s\n", path);
484 ret = AVERROR(EIO);
485 goto fail;
486 }
487
488 *data = av_malloc(fsize);
489 if (!*data) {
490 ret = AVERROR(ENOMEM);
491 goto fail;
492 }
493
494 ret = avio_read(io, *data, fsize);
495 if (ret != fsize) {
496 av_log(logctx, AV_LOG_ERROR, "Error reading file %s\n", path);
497 ret = ret < 0 ? ret : AVERROR(EIO);
498 goto fail;
499 }
500
501 *len = fsize;
502
503 ret = 0;
504fail:
505 avio_close(io);
506 if (ret < 0) {
507 av_freep(data);
508 *len = 0;
509 }
510 return ret;
511}
512
513static int filter_opt_apply(void *logctx, AVFilterContext *f,
514 const char *key, const char *val)
515{
516 const AVOption *o = NULL;
517 int ret;
518
520 if (ret >= 0)
521 return 0;
522
523 if (ret == AVERROR_OPTION_NOT_FOUND && key[0] == '/')
525 if (!o)
526 goto err_apply;
527
528 // key is a valid option name prefixed with '/'
529 // interpret value as a path from which to load the actual option value
530 key++;
531
532 if (o->type == AV_OPT_TYPE_BINARY) {
533 uint8_t *data;
534 int len;
535
536 ret = read_binary(logctx, val, &data, &len);
537 if (ret < 0)
538 goto err_load;
539
541 av_freep(&data);
542 } else {
544 if (!data) {
545 ret = AVERROR(EIO);
546 goto err_load;
547 }
548
550 av_freep(&data);
551 }
552 if (ret < 0)
553 goto err_apply;
554
555 return 0;
556
557err_apply:
558 av_log(logctx, AV_LOG_ERROR,
559 "Error applying option '%s' to filter '%s': %s\n",
560 key, f->filter->name, av_err2str(ret));
561 return ret;
562err_load:
563 av_log(logctx, AV_LOG_ERROR,
564 "Error loading value for option '%s' from file '%s'\n",
565 key, val);
566 return ret;
567}
568
569static int graph_opts_apply(void *logctx, AVFilterGraphSegment *seg)
570{
571 for (size_t i = 0; i < seg->nb_chains; i++) {
572 AVFilterChain *ch = seg->chains[i];
573
574 for (size_t j = 0; j < ch->nb_filters; j++) {
575 AVFilterParams *p = ch->filters[j];
576 const AVDictionaryEntry *e = NULL;
577
578 av_assert0(p->filter);
579
580 while ((e = av_dict_iterate(p->opts, e))) {
581 int ret = filter_opt_apply(logctx, p->filter, e->key, e->value);
582 if (ret < 0)
583 return ret;
584 }
585
586 av_dict_free(&p->opts);
587 }
588 }
589
590 return 0;
591}
592
593static int graph_parse(void *logctx,
594 AVFilterGraph *graph, const char *desc,
596 AVBufferRef *hw_device)
597{
599 int ret;
600
601 *inputs = NULL;
602 *outputs = NULL;
603
604 ret = avfilter_graph_segment_parse(graph, desc, 0, &seg);
605 if (ret < 0)
606 return ret;
607
609 if (ret < 0)
610 goto fail;
611
612 if (hw_device) {
613 for (int i = 0; i < graph->nb_filters; i++) {
614 AVFilterContext *f = graph->filters[i];
615
616 if (!(f->filter->flags & AVFILTER_FLAG_HWDEVICE))
617 continue;
618 f->hw_device_ctx = av_buffer_ref(hw_device);
619 if (!f->hw_device_ctx) {
620 ret = AVERROR(ENOMEM);
621 goto fail;
622 }
623 }
624 }
625
626 ret = graph_opts_apply(logctx, seg);
627 if (ret < 0)
628 goto fail;
629
631
632fail:
634 return ret;
635}
636
637// Filters can be configured only if the formats of all inputs are known.
639{
640 for (int i = 0; i < fg->nb_inputs; i++) {
642 if (ifp->format < 0)
643 return 0;
644 }
645 return 1;
646}
647
648static int filter_thread(void *arg);
649
650static char *describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in)
651{
653 AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads;
654 int nb_pads = in ? ctx->nb_inputs : ctx->nb_outputs;
655
656 if (nb_pads > 1)
657 return av_strdup(ctx->filter->name);
658 return av_asprintf("%s:%s", ctx->filter->name,
659 avfilter_pad_get_name(pads, inout->pad_idx));
660}
661
662static const char *ofilter_item_name(void *obj)
663{
664 OutputFilterPriv *ofp = obj;
665 return ofp->log_name;
666}
667
668static const AVOption ofilter_options[] = {
669 {"video_size", "set video size", offsetof(OutputFilterPriv, width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, INT_MAX },
670 {"pixel_format", "set pixel format", offsetof(OutputFilterPriv, format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX },
671 {"colorspace", "color space", offsetof(OutputFilterPriv, color_space), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 0, INT_MAX },
672 {"color_range", "color range", offsetof(OutputFilterPriv, color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, INT_MAX },
673 {"alpha_mode", "color range", offsetof(OutputFilterPriv, alpha_mode), AV_OPT_TYPE_INT, {.i64 = AVALPHA_MODE_UNSPECIFIED }, 0, INT_MAX },
674 {"chroma_location", "chroma sample location", offsetof(OutputFilterPriv, chroma_location), AV_OPT_TYPE_INT, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, INT_MAX },
675 {"ar", "set audio sampling rate (in Hz)", offsetof(OutputFilterPriv, sample_rate), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX },
676 {"ch_layout", NULL, offsetof(OutputFilterPriv, ch_layout), AV_OPT_TYPE_CHLAYOUT, {.str = NULL }, 0, 0 },
677 { NULL },
678};
679
680static const AVClass ofilter_class = {
681 .class_name = "OutputFilter",
682 .version = LIBAVUTIL_VERSION_INT,
683 .item_name = ofilter_item_name,
684 .option = ofilter_options,
685 .parent_log_context_offset = offsetof(OutputFilterPriv, log_parent),
686 .category = AV_CLASS_CATEGORY_FILTER,
687};
688
690{
691 OutputFilterPriv *ofp;
692 OutputFilter *ofilter;
693
694 ofp = allocate_array_elem(&fg->outputs, sizeof(*ofp), &fg->nb_outputs);
695 if (!ofp)
696 return NULL;
697
698 ofilter = &ofp->ofilter;
699 ofilter->class = &ofilter_class;
700 ofp->log_parent = fg;
701 ofilter->graph = fg;
702 ofilter->type = type;
704 ofp->reinit_opts = (ReinitOpts){ .pts = AV_NOPTS_VALUE };
705 ofilter->index = fg->nb_outputs - 1;
706
707 snprintf(ofp->log_name, sizeof(ofp->log_name), "%co%d",
708 av_get_media_type_string(type)[0], ofilter->index);
709
710 return ofilter;
711}
712
713static int ifilter_bind_ist(InputFilter *ifilter, InputStream *ist,
714 const ViewSpecifier *vs)
715{
716 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
717 FilterGraphPriv *fgp = fgp_from_fg(ifilter->graph);
719 int ret;
720
721 av_assert0(!ifp->bound);
722 ifp->bound = 1;
723
724 if (ifilter->type != ist->par->codec_type &&
725 !(ifilter->type == AVMEDIA_TYPE_VIDEO && ist->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
726 av_log(fgp, AV_LOG_ERROR, "Tried to connect %s stream to %s filtergraph input\n",
728 return AVERROR(EINVAL);
729 }
730
731 ifp->type_src = ist->st->codecpar->codec_type;
732
734 if (!ifp->opts.fallback)
735 return AVERROR(ENOMEM);
736
737 ret = ist_filter_add(ist, ifilter, filtergraph_is_simple(ifilter->graph),
738 vs, &ifp->opts, &src);
739 if (ret < 0)
740 return ret;
741
742 ifilter->input_name = av_strdup(ifp->opts.name);
743 if (!ifilter->input_name)
744 return AVERROR(EINVAL);
745
746 ret = sch_connect(fgp->sch,
747 src, SCH_FILTER_IN(fgp->sch_idx, ifilter->index));
748 if (ret < 0)
749 return ret;
750
751 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
753 if (!ifp->sub2video.frame)
754 return AVERROR(ENOMEM);
755
756 ifp->width = ifp->opts.sub2video_width;
757 ifp->height = ifp->opts.sub2video_height;
758
759 /* rectangles are AV_PIX_FMT_PAL8, but we have no guarantee that the
760 palettes for all rectangles are identical or compatible */
762
764
765 av_log(fgp, AV_LOG_VERBOSE, "sub2video: using %dx%d canvas\n",
766 ifp->width, ifp->height);
767 }
768
769 return 0;
770}
771
773 const ViewSpecifier *vs)
774{
777 int ret;
778
779 av_assert0(!ifp->bound);
780 ifp->bound = 1;
781
782 if (ifp->ifilter.type != dec->type) {
783 av_log(fgp, AV_LOG_ERROR, "Tried to connect %s decoder to %s filtergraph input\n",
785 return AVERROR(EINVAL);
786 }
787
788 ifp->type_src = ifp->ifilter.type;
789
790 ret = dec_filter_add(dec, &ifp->ifilter, &ifp->opts, vs, &src);
791 if (ret < 0)
792 return ret;
793
794 ifp->ifilter.input_name = av_strdup(ifp->opts.name);
795 if (!ifp->ifilter.input_name)
796 return AVERROR(EINVAL);
797
798 ret = sch_connect(fgp->sch, src, SCH_FILTER_IN(fgp->sch_idx, ifp->ifilter.index));
799 if (ret < 0)
800 return ret;
801
802 return 0;
803}
804
805static int set_channel_layout(OutputFilterPriv *f, const AVChannelLayout *layouts_allowed,
806 const AVChannelLayout *layout_requested)
807{
808 int i, err;
809
810 if (layout_requested->order != AV_CHANNEL_ORDER_UNSPEC) {
811 /* Pass the layout through for all orders but UNSPEC */
812 err = av_channel_layout_copy(&f->ch_layout, layout_requested);
813 if (err < 0)
814 return err;
815 return 0;
816 }
817
818 /* Requested layout is of order UNSPEC */
819 if (!layouts_allowed) {
820 /* Use the default native layout for the requested amount of channels when the
821 encoder doesn't have a list of supported layouts */
822 av_channel_layout_default(&f->ch_layout, layout_requested->nb_channels);
823 return 0;
824 }
825 /* Encoder has a list of supported layouts. Pick the first layout in it with the
826 same amount of channels as the requested layout */
827 for (i = 0; layouts_allowed[i].nb_channels; i++) {
828 if (layouts_allowed[i].nb_channels == layout_requested->nb_channels)
829 break;
830 }
831 if (layouts_allowed[i].nb_channels) {
832 /* Use it if one is found */
833 err = av_channel_layout_copy(&f->ch_layout, &layouts_allowed[i]);
834 if (err < 0)
835 return err;
836 return 0;
837 }
838 /* If no layout for the amount of channels requested was found, use the default
839 native layout for it. */
840 av_channel_layout_default(&f->ch_layout, layout_requested->nb_channels);
841
842 return 0;
843}
844
845static int parse_reinit_opts(AVFifo **pout, const char *opts, void *logctx)
846{
847 AVFifo *out;
848 int ret = AVERROR_BUG;
849 char *ptr, *str, *substr = NULL;
850 const char *token;
851
852 str = av_strdup(opts);
853 if (!str)
854 return AVERROR(ENOMEM);
855
857 if (!out) {
858 ret = AVERROR(ENOMEM);
859 goto end;
860 }
861
862 token = av_strtok(str, ",", &ptr);
863 while (token) {
864 ReinitOpts o = { 0 };
865 const char *subtoken;
866 char *subptr, *endptr;
867
868 substr = av_strdup(token);
869 if (!substr) {
870 ret = AVERROR(ENOMEM);
871 goto end;
872 }
873 subtoken = av_strtok(substr, "|", &subptr);
874 if (subtoken && subptr) {
875 if (!av_strstart(subtoken, "pts=", &subtoken)) {
876 av_log(logctx, AV_LOG_ERROR, "Invalid reinit identifier\n");
877 ret = AVERROR(ENOMEM);
878 goto end;
879 }
880 o.pts = strtoll(subtoken, &endptr, 0);
881 if (*endptr || o.pts < 0) {
882 ret = AVERROR(EINVAL);
883 goto end;
884 }
885 ret = av_dict_parse_string(&o.dict, subptr, "=", ":", 0);
886 if (ret < 0) {
887 av_log(logctx, AV_LOG_ERROR, "Error parsing encoder options\n");
888 goto end;
889 }
890 ret = av_fifo_write(out, &o, 1);
891 if (ret < 0) {
892 av_dict_free(&o.dict);
893 goto end;
894 }
895 } else {
896 ret = AVERROR(EINVAL);
897 goto end;
898 }
899 av_freep(&substr);
900 if (ptr)
901 ptr += strspn(ptr, " \n\t\r");
902 token = av_strtok(NULL, ",", &ptr);
903 }
904
905 ret = 0;
906end:
907 *pout = out;
908 av_free(substr);
909 av_free(str);
910
911 return ret;
912}
913
914int ofilter_bind_enc(OutputFilter *ofilter, unsigned sched_idx_enc,
916{
917 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
918 FilterGraph *fg = ofilter->graph;
919 FilterGraphPriv *fgp = fgp_from_fg(fg);
920 int ret;
921
922 av_assert0(!ofilter->bound);
923 av_assert0(!opts->enc ||
924 ofilter->type == opts->enc->type);
925
926 ofp->needed = NEEDED_EXPLICIT;
927 ofilter->bound = 1;
928 av_freep(&ofilter->linklabel);
929
930 ofp->flags |= opts->flags;
931 ofp->ts_offset = opts->ts_offset;
932 ofp->enc_timebase = opts->output_tb;
933
934 ofp->trim_start_us = opts->trim_start_us;
935 ofp->trim_duration_us = opts->trim_duration_us;
936
937 ofilter->output_name = av_strdup(opts->name);
938 if (!ofilter->output_name)
939 return AVERROR(EINVAL);
940
941 if (opts->reinit_opts) {
942 ret = parse_reinit_opts(&ofp->reinit_opts_fifo, opts->reinit_opts, ofilter);
943 if (ret < 0)
944 return ret;
945 }
946
947 ret = av_dict_copy(&ofp->sws_opts, opts->sws_opts, 0);
948 if (ret < 0)
949 return ret;
950
951 ret = av_dict_copy(&ofp->swr_opts, opts->swr_opts, 0);
952 if (ret < 0)
953 return ret;
954
955 if (opts->flags & OFILTER_FLAG_AUDIO_24BIT)
956 av_dict_set(&ofp->swr_opts, "output_sample_bits", "24", 0);
957
958 if (fgp->is_simple) {
959 // for simple filtergraph there is just one output,
960 // so use only graph-level information for logging
961 ofp->log_parent = NULL;
962 av_strlcpy(ofp->log_name, fgp->log_name, sizeof(ofp->log_name));
963 } else
964 av_strlcatf(ofp->log_name, sizeof(ofp->log_name), "->%s", ofilter->output_name);
965
966 switch (ofilter->type) {
968 ofp->width = opts->width;
969 ofp->height = opts->height;
970 if (opts->format != AV_PIX_FMT_NONE) {
971 ofp->format = opts->format;
972 } else
973 ofp->pix_fmts = opts->pix_fmts;
974
975 if (opts->color_space != AVCOL_SPC_UNSPECIFIED)
976 ofp->color_space = opts->color_space;
977 else
978 ofp->color_spaces = opts->color_spaces;
979
980 if (opts->color_range != AVCOL_RANGE_UNSPECIFIED)
981 ofp->color_range = opts->color_range;
982 else
983 ofp->color_ranges = opts->color_ranges;
984
985 if (opts->alpha_mode != AVALPHA_MODE_UNSPECIFIED)
986 ofp->alpha_mode = opts->alpha_mode;
987 else
988 ofp->alpha_modes = opts->alpha_modes;
989
990 if (opts->chroma_location != AVCHROMA_LOC_UNSPECIFIED)
991 ofp->chroma_location = opts->chroma_location;
992 else
993 ofp->chroma_locations = opts->chroma_locations;
994
996
998 if (!ofp->fps.last_frame)
999 return AVERROR(ENOMEM);
1000
1001 ofp->fps.vsync_method = opts->vsync_method;
1002 ofp->fps.framerate = opts->frame_rate;
1003 ofp->fps.framerate_max = opts->max_frame_rate;
1004 ofp->fps.framerate_supported = opts->frame_rates;
1005
1006 // reduce frame rate for mpeg4 to be within the spec limits
1007 if (opts->enc && opts->enc->id == AV_CODEC_ID_MPEG4)
1008 ofp->fps.framerate_clip = 65535;
1009
1010 ofp->fps.dup_warning = 1000;
1011
1012 break;
1013 case AVMEDIA_TYPE_AUDIO:
1014 if (opts->format != AV_SAMPLE_FMT_NONE) {
1015 ofp->format = opts->format;
1016 } else {
1017 ofp->sample_fmts = opts->sample_fmts;
1018 }
1019 if (opts->sample_rate) {
1020 ofp->sample_rate = opts->sample_rate;
1021 } else
1022 ofp->sample_rates = opts->sample_rates;
1023 if (opts->ch_layout.nb_channels) {
1024 int ret = set_channel_layout(ofp, opts->ch_layouts, &opts->ch_layout);
1025 if (ret < 0)
1026 return ret;
1027 } else {
1028 ofp->ch_layouts = opts->ch_layouts;
1029 }
1030 break;
1031 }
1032
1033 ret = sch_connect(fgp->sch, SCH_FILTER_OUT(fgp->sch_idx, ofilter->index),
1034 SCH_ENC(sched_idx_enc));
1035 if (ret < 0)
1036 return ret;
1037
1038 return 0;
1039}
1040
1043{
1044 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1045
1046 av_assert0(!ofilter->bound);
1047 av_assert0(ofilter->type == ifp->ifilter.type);
1048
1049 ofilter->bound = 1;
1050 av_freep(&ofilter->linklabel);
1051
1052 ofilter->output_name = av_strdup(opts->name);
1053 if (!ofilter->output_name)
1054 return AVERROR(EINVAL);
1055
1056 ifp->ofilter_src = ofilter;
1057
1058 av_strlcatf(ofp->log_name, sizeof(ofp->log_name), "->%s", ofilter->output_name);
1059
1060 return 0;
1061}
1062
1063static int ifilter_bind_fg(InputFilterPriv *ifp, FilterGraph *fg_src, int out_idx)
1064{
1066 OutputFilter *ofilter_src = fg_src->outputs[out_idx];
1068 char name[32];
1069 int ret;
1070
1071 av_assert0(!ifp->bound);
1072 ifp->bound = 1;
1073
1074 if (ifp->ifilter.type != ofilter_src->type) {
1075 av_log(fgp, AV_LOG_ERROR, "Tried to connect %s output to %s input\n",
1076 av_get_media_type_string(ofilter_src->type),
1078 return AVERROR(EINVAL);
1079 }
1080
1081 ifp->type_src = ifp->ifilter.type;
1082
1083 memset(&opts, 0, sizeof(opts));
1084
1085 snprintf(name, sizeof(name), "fg:%d:%d", fgp->fg.index, ifp->ifilter.index);
1086 opts.name = name;
1087
1088 ret = ofilter_bind_ifilter(ofilter_src, ifp, &opts);
1089 if (ret < 0)
1090 return ret;
1091
1092 ret = sch_connect(fgp->sch, SCH_FILTER_OUT(fg_src->index, out_idx),
1093 SCH_FILTER_IN(fgp->sch_idx, ifp->ifilter.index));
1094 if (ret < 0)
1095 return ret;
1096
1097 return 0;
1098}
1099
1101{
1102 InputFilterPriv *ifp;
1103 InputFilter *ifilter;
1104
1105 ifp = allocate_array_elem(&fg->inputs, sizeof(*ifp), &fg->nb_inputs);
1106 if (!ifp)
1107 return NULL;
1108
1109 ifilter = &ifp->ifilter;
1110 ifilter->graph = fg;
1111
1112 ifp->frame = av_frame_alloc();
1113 if (!ifp->frame)
1114 return NULL;
1115
1116 ifilter->index = fg->nb_inputs - 1;
1117 ifp->format = -1;
1122
1124 if (!ifp->frame_queue)
1125 return NULL;
1126
1127 return ifilter;
1128}
1129
1131{
1132 FilterGraph *fg = *pfg;
1133 FilterGraphPriv *fgp;
1134
1135 if (!fg)
1136 return;
1137 fgp = fgp_from_fg(fg);
1138
1139 for (int j = 0; j < fg->nb_inputs; j++) {
1140 InputFilter *ifilter = fg->inputs[j];
1141 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1142
1143 if (ifp->frame_queue) {
1144 AVFrame *frame;
1145 while (av_fifo_read(ifp->frame_queue, &frame, 1) >= 0)
1148 }
1150
1151 av_frame_free(&ifp->frame);
1153
1156 av_freep(&ifilter->linklabel);
1157 av_freep(&ifp->opts.name);
1160 av_freep(&ifilter->name);
1161 av_freep(&ifilter->input_name);
1162 av_freep(&fg->inputs[j]);
1163 }
1164 av_freep(&fg->inputs);
1165 for (int j = 0; j < fg->nb_outputs; j++) {
1166 OutputFilter *ofilter = fg->outputs[j];
1167 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1168
1170 av_dict_free(&ofp->sws_opts);
1171 av_dict_free(&ofp->swr_opts);
1172
1173 av_freep(&ofilter->linklabel);
1174 av_freep(&ofilter->name);
1175 av_freep(&ofilter->output_name);
1176 av_freep(&ofilter->apad);
1178 if (ofp->reinit_opts_fifo) {
1179 while (av_fifo_read(ofp->reinit_opts_fifo, &ofp->reinit_opts, 1) >= 0)
1182 }
1185 av_freep(&fg->outputs[j]);
1186 }
1187 av_freep(&fg->outputs);
1188 av_freep(&fg->graph_desc);
1189
1190 av_frame_free(&fgp->frame);
1191 av_frame_free(&fgp->frame_enc);
1192
1193 av_freep(pfg);
1194}
1195
1196static const char *fg_item_name(void *obj)
1197{
1198 const FilterGraphPriv *fgp = obj;
1199
1200 return fgp->log_name;
1201}
1202
1203static const AVClass fg_class = {
1204 .class_name = "FilterGraph",
1205 .version = LIBAVUTIL_VERSION_INT,
1206 .item_name = fg_item_name,
1207 .category = AV_CLASS_CATEGORY_FILTER,
1208};
1209
1210int fg_create(FilterGraph **pfg, char **graph_desc, Scheduler *sch,
1212{
1213 FilterGraphPriv *fgp;
1214 FilterGraph *fg;
1215
1217 AVFilterGraph *graph;
1218 int ret = 0;
1219
1220 fgp = av_mallocz(sizeof(*fgp));
1221 if (!fgp) {
1222 av_freep(graph_desc);
1223 return AVERROR(ENOMEM);
1224 }
1225 fg = &fgp->fg;
1226
1227 if (pfg) {
1228 *pfg = fg;
1229 fg->index = -1;
1230 } else {
1232 if (ret < 0) {
1233 av_freep(graph_desc);
1234 av_freep(&fgp);
1235 return ret;
1236 }
1237
1238 fg->index = nb_filtergraphs - 1;
1239 }
1240
1241 fg->class = &fg_class;
1242 fg->graph_desc = *graph_desc;
1244 fgp->nb_threads = -1;
1245 fgp->sch = sch;
1246
1247 *graph_desc = NULL;
1248
1249 snprintf(fgp->log_name, sizeof(fgp->log_name), "fc#%d", fg->index);
1250
1251 fgp->frame = av_frame_alloc();
1252 fgp->frame_enc = av_frame_alloc();
1253 if (!fgp->frame || !fgp->frame_enc)
1254 return AVERROR(ENOMEM);
1255
1256 /* this graph is only used for determining the kinds of inputs
1257 * and outputs we have, and is discarded on exit from this function */
1258 graph = avfilter_graph_alloc();
1259 if (!graph)
1260 return AVERROR(ENOMEM);;
1261 graph->nb_threads = 1;
1262
1263 ret = graph_parse(fg, graph, fg->graph_desc, &inputs, &outputs,
1265 if (ret < 0)
1266 goto fail;
1267
1268 for (AVFilterInOut *cur = inputs; cur; cur = cur->next) {
1269 InputFilter *const ifilter = ifilter_alloc(fg);
1270
1271 if (!ifilter) {
1272 ret = AVERROR(ENOMEM);
1273 goto fail;
1274 }
1275
1276 ifilter->linklabel = cur->name;
1277 cur->name = NULL;
1278
1279 ifilter->type = avfilter_pad_get_type(cur->filter_ctx->input_pads,
1280 cur->pad_idx);
1281
1282 if (ifilter->type != AVMEDIA_TYPE_VIDEO && ifilter->type != AVMEDIA_TYPE_AUDIO) {
1283 av_log(fg, AV_LOG_FATAL, "Only video and audio filters supported "
1284 "currently.\n");
1285 ret = AVERROR(ENOSYS);
1286 goto fail;
1287 }
1288
1289 ifilter->name = describe_filter_link(fg, cur, 1);
1290 if (!ifilter->name) {
1291 ret = AVERROR(ENOMEM);
1292 goto fail;
1293 }
1294 }
1295
1296 for (AVFilterInOut *cur = outputs; cur; cur = cur->next) {
1297 const enum AVMediaType type = avfilter_pad_get_type(cur->filter_ctx->output_pads,
1298 cur->pad_idx);
1299 OutputFilter *const ofilter = ofilter_alloc(fg, type);
1300 OutputFilterPriv *ofp;
1301
1302 if (!ofilter) {
1303 ret = AVERROR(ENOMEM);
1304 goto fail;
1305 }
1306 ofp = ofp_from_ofilter(ofilter);
1307
1308 ofilter->linklabel = cur->name;
1309 cur->name = NULL;
1310
1311 ofilter->name = describe_filter_link(fg, cur, 0);
1312 if (!ofilter->name) {
1313 ret = AVERROR(ENOMEM);
1314 goto fail;
1315 }
1316
1317 // opts should only be needed in this function to fill fields from filtergraphs
1318 // whose output is meant to be treated as if it was stream, e.g. merged HEIF
1319 // tile groups.
1320 if (opts) {
1321 ofp->flags = opts->flags;
1322 ofp->side_data = opts->side_data;
1323 ofp->nb_side_data = opts->nb_side_data;
1324
1325 ofp->crop_top = opts->crop_top;
1326 ofp->crop_bottom = opts->crop_bottom;
1327 ofp->crop_left = opts->crop_left;
1328 ofp->crop_right = opts->crop_right;
1329
1332 if (sd)
1333 memcpy(ofp->displaymatrix, sd->data, sizeof(ofp->displaymatrix));
1334 }
1335 }
1336
1337 if (!fg->nb_outputs) {
1338 av_log(fg, AV_LOG_FATAL, "A filtergraph has zero outputs, this is not supported\n");
1339 ret = AVERROR(ENOSYS);
1340 goto fail;
1341 }
1342
1344 filter_thread, fgp);
1345 if (ret < 0)
1346 goto fail;
1347 fgp->sch_idx = ret;
1348
1349fail:
1352 avfilter_graph_free(&graph);
1353
1354 if (ret < 0)
1355 return ret;
1356
1357 return 0;
1358}
1359
1361 InputStream *ist,
1362 char **graph_desc,
1363 Scheduler *sch, unsigned sched_idx_enc,
1365{
1366 const enum AVMediaType type = ist->par->codec_type;
1367 FilterGraph *fg;
1368 FilterGraphPriv *fgp;
1369 int ret;
1370
1371 ret = fg_create(pfg, graph_desc, sch, NULL);
1372 if (ret < 0)
1373 return ret;
1374 fg = *pfg;
1375 fgp = fgp_from_fg(fg);
1376
1377 fgp->is_simple = 1;
1378
1379 snprintf(fgp->log_name, sizeof(fgp->log_name), "%cf%s",
1381
1382 if (fg->nb_inputs != 1 || fg->nb_outputs != 1) {
1383 av_log(fg, AV_LOG_ERROR, "Simple filtergraph '%s' was expected "
1384 "to have exactly 1 input and 1 output. "
1385 "However, it had %d input(s) and %d output(s). Please adjust, "
1386 "or use a complex filtergraph (-filter_complex) instead.\n",
1387 *graph_desc, fg->nb_inputs, fg->nb_outputs);
1388 return AVERROR(EINVAL);
1389 }
1390 if (fg->outputs[0]->type != type) {
1391 av_log(fg, AV_LOG_ERROR, "Filtergraph has a %s output, cannot connect "
1392 "it to %s output stream\n",
1395 return AVERROR(EINVAL);
1396 }
1397
1398 ret = ifilter_bind_ist(fg->inputs[0], ist, opts->vs);
1399 if (ret < 0)
1400 return ret;
1401
1402 ret = ofilter_bind_enc(fg->outputs[0], sched_idx_enc, opts);
1403 if (ret < 0)
1404 return ret;
1405
1406 if (opts->nb_threads >= 0)
1407 fgp->nb_threads = opts->nb_threads;
1408
1409 return 0;
1410}
1411
1412static int fg_complex_bind_input(FilterGraph *fg, InputFilter *ifilter, int commit)
1413{
1414 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1415 InputStream *ist = NULL;
1416 enum AVMediaType type = ifilter->type;
1417 ViewSpecifier vs = { .type = VIEW_SPECIFIER_TYPE_NONE };
1418 const char *spec;
1419 char *p;
1420 int i, ret;
1421
1422 if (ifilter->linklabel && !strncmp(ifilter->linklabel, "dec:", 4)) {
1423 // bind to a standalone decoder
1424 int dec_idx;
1425
1426 dec_idx = strtol(ifilter->linklabel + 4, &p, 0);
1427 if (dec_idx < 0 || dec_idx >= nb_decoders) {
1428 av_log(fg, AV_LOG_ERROR, "Invalid decoder index %d in filtergraph description %s\n",
1429 dec_idx, fg->graph_desc);
1430 return AVERROR(EINVAL);
1431 }
1432
1433 if (type == AVMEDIA_TYPE_VIDEO) {
1434 spec = *p == ':' ? p + 1 : p;
1435 ret = view_specifier_parse(&spec, &vs);
1436 if (ret < 0)
1437 return ret;
1438 }
1439
1440 ret = ifilter_bind_dec(ifp, decoders[dec_idx], &vs);
1441 if (ret < 0)
1442 av_log(fg, AV_LOG_ERROR, "Error binding a decoder to filtergraph input %s\n",
1443 ifilter->name);
1444 return ret;
1445 } else if (ifilter->linklabel) {
1448 AVStream *st = NULL;
1449 int file_idx;
1450
1451 // try finding an unbound filtergraph output with this label
1452 for (int i = 0; i < nb_filtergraphs; i++) {
1453 FilterGraph *fg_src = filtergraphs[i];
1454
1455 if (fg == fg_src)
1456 continue;
1457
1458 for (int j = 0; j < fg_src->nb_outputs; j++) {
1459 OutputFilter *ofilter = fg_src->outputs[j];
1460
1461 if (!ofilter->bound && ofilter->linklabel &&
1462 !strcmp(ofilter->linklabel, ifilter->linklabel)) {
1463 if (commit) {
1465 "Binding input with label '%s' to filtergraph output %d:%d\n",
1466 ifilter->linklabel, i, j);
1467
1468 ret = ifilter_bind_fg(ifp, fg_src, j);
1469 if (ret < 0) {
1470 av_log(fg, AV_LOG_ERROR, "Error binding filtergraph input %s\n",
1471 ifilter->linklabel);
1472 return ret;
1473 }
1474 } else
1476 return 0;
1477 }
1478 }
1479 }
1480
1481 // bind to an explicitly specified demuxer stream
1482 file_idx = strtol(ifilter->linklabel, &p, 0);
1483 if (file_idx < 0 || file_idx >= nb_input_files) {
1484 av_log(fg, AV_LOG_FATAL, "Invalid file index %d in filtergraph description %s.\n",
1485 file_idx, fg->graph_desc);
1486 return AVERROR(EINVAL);
1487 }
1488 s = input_files[file_idx]->ctx;
1489
1490 ret = stream_specifier_parse(&ss, *p == ':' ? p + 1 : p, 1, fg);
1491 if (ret < 0) {
1492 av_log(fg, AV_LOG_ERROR, "Invalid stream specifier: %s\n", p);
1493 return ret;
1494 }
1495
1496 if (type == AVMEDIA_TYPE_VIDEO) {
1497 spec = ss.remainder ? ss.remainder : "";
1498 ret = view_specifier_parse(&spec, &vs);
1499 if (ret < 0) {
1501 return ret;
1502 }
1503 }
1504
1505 for (i = 0; i < s->nb_streams; i++) {
1506 enum AVMediaType stream_type = s->streams[i]->codecpar->codec_type;
1507 if (stream_type != type &&
1508 !(stream_type == AVMEDIA_TYPE_SUBTITLE &&
1509 type == AVMEDIA_TYPE_VIDEO /* sub2video hack */))
1510 continue;
1511 if (stream_specifier_match(&ss, s, s->streams[i], fg)) {
1512 st = s->streams[i];
1513 break;
1514 }
1515 }
1517 if (!st) {
1518 av_log(fg, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s "
1519 "matches no streams.\n", p, fg->graph_desc);
1520 return AVERROR(EINVAL);
1521 }
1522 ist = input_files[file_idx]->streams[st->index];
1523
1524 if (commit)
1526 "Binding input with label '%s' to input stream %d:%d\n",
1527 ifilter->linklabel, ist->file->index, ist->index);
1528 } else {
1529 // try finding an unbound filtergraph output
1530 for (int i = 0; i < nb_filtergraphs; i++) {
1531 FilterGraph *fg_src = filtergraphs[i];
1532
1533 if (fg == fg_src)
1534 continue;
1535
1536 for (int j = 0; j < fg_src->nb_outputs; j++) {
1537 OutputFilter *ofilter = fg_src->outputs[j];
1538
1539 if (!ofilter->bound) {
1540 if (commit) {
1542 "Binding unlabeled filtergraph input to filtergraph output %d:%d\n", i, j);
1543
1544 ret = ifilter_bind_fg(ifp, fg_src, j);
1545 if (ret < 0) {
1546 av_log(fg, AV_LOG_ERROR, "Error binding filtergraph input %d:%d\n", i, j);
1547 return ret;
1548 }
1549 } else
1551 return 0;
1552 }
1553 }
1554 }
1555
1556 ist = ist_find_unused(type);
1557 if (!ist) {
1558 av_log(fg, AV_LOG_FATAL,
1559 "Cannot find an unused %s input stream to feed the "
1560 "unlabeled input pad %s.\n",
1562 return AVERROR(EINVAL);
1563 }
1564
1565 if (commit)
1567 "Binding unlabeled input %d to input stream %d:%d\n",
1568 ifilter->index, ist->file->index, ist->index);
1569 }
1570 av_assert0(ist);
1571
1572 if (commit) {
1573 ret = ifilter_bind_ist(ifilter, ist, &vs);
1574 if (ret < 0) {
1575 av_log(fg, AV_LOG_ERROR,
1576 "Error binding an input stream to complex filtergraph input %s.\n",
1577 ifilter->name);
1578 return ret;
1579 }
1580 }
1581
1582 return 0;
1583}
1584
1585static int bind_inputs(FilterGraph *fg, int commit)
1586{
1587 // bind filtergraph inputs to input streams or other filtergraphs
1588 for (int i = 0; i < fg->nb_inputs; i++) {
1590 int ret;
1591
1592 if (ifp->bound)
1593 continue;
1594
1595 ret = fg_complex_bind_input(fg, &ifp->ifilter, commit);
1596 if (ret < 0)
1597 return ret;
1598 }
1599
1600 return 0;
1601}
1602
1604{
1605 int ret;
1606
1607retry:
1608 for (int i = 0; i < nb_filtergraphs; i++) {
1609 FilterGraph *fg = filtergraphs[i];
1610 for (int j = 0; j < fg->nb_outputs; j++) {
1611 OutputFilter *output = fg->outputs[j];
1613 }
1614 }
1615 for (int i = 0; i < nb_filtergraphs; i++) {
1617 if (ret < 0)
1618 return ret;
1619 }
1620
1621 // check that all outputs were marked as needed to be bound
1622 for (int i = nb_filtergraphs - 1; i >= 0; i--) {
1623 FilterGraph *fg = filtergraphs[i];
1625
1626 for (int j = 0; j < fg->nb_outputs; j++) {
1627 OutputFilter *output = fg->outputs[j];
1628 if (!ofp_from_ofilter(output)->needed) {
1629 if (!fg->is_internal) {
1630 av_log(fg, AV_LOG_FATAL,
1631 "Filter '%s' has output %d (%s) unconnected\n",
1632 output->name, j,
1633 output->linklabel ? (const char *)output->linklabel : "unlabeled");
1634 return AVERROR(EINVAL);
1635 }
1636
1637 av_log(fg, AV_LOG_DEBUG,
1638 "Internal filter '%s' has output %d (%s) unconnected. Removing graph\n",
1639 output->name, j,
1640 output->linklabel ? (const char *)output->linklabel : "unlabeled");
1644 if (nb_filtergraphs > 0)
1645 memmove(&filtergraphs[i],
1646 &filtergraphs[i + 1],
1647 (nb_filtergraphs - i) * sizeof(*filtergraphs));
1648 goto retry;
1649 }
1650 }
1651 }
1652
1653 for (int i = 0; i < nb_filtergraphs; i++) {
1655 if (ret < 0)
1656 return ret;
1657 }
1658
1659 return 0;
1660}
1661
1663 AVFilterContext **last_filter, int *pad_idx,
1664 const char *filter_name)
1665{
1666 AVFilterGraph *graph = (*last_filter)->graph;
1668 const AVFilter *trim;
1669 enum AVMediaType type = avfilter_pad_get_type((*last_filter)->output_pads, *pad_idx);
1670 const char *name = (type == AVMEDIA_TYPE_VIDEO) ? "trim" : "atrim";
1671 int ret = 0;
1672
1673 if (duration == INT64_MAX && start_time == AV_NOPTS_VALUE)
1674 return 0;
1675
1676 trim = avfilter_get_by_name(name);
1677 if (!trim) {
1678 av_log(logctx, AV_LOG_ERROR, "%s filter not present, cannot limit "
1679 "recording time.\n", name);
1681 }
1682
1683 ctx = avfilter_graph_alloc_filter(graph, trim, filter_name);
1684 if (!ctx)
1685 return AVERROR(ENOMEM);
1686
1687 if (duration != INT64_MAX) {
1688 ret = av_opt_set_int(ctx, "durationi", duration,
1690 }
1691 if (ret >= 0 && start_time != AV_NOPTS_VALUE) {
1692 ret = av_opt_set_int(ctx, "starti", start_time,
1694 }
1695 if (ret < 0) {
1696 av_log(ctx, AV_LOG_ERROR, "Error configuring the %s filter", name);
1697 return ret;
1698 }
1699
1701 if (ret < 0)
1702 return ret;
1703
1704 ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
1705 if (ret < 0)
1706 return ret;
1707
1708 *last_filter = ctx;
1709 *pad_idx = 0;
1710 return 0;
1711}
1712
1713static int insert_filter(AVFilterContext **last_filter, int *pad_idx,
1714 const char *filter_name, const char *args)
1715{
1716 AVFilterGraph *graph = (*last_filter)->graph;
1717 const AVFilter *filter = avfilter_get_by_name(filter_name);
1719 int ret;
1720
1721 if (!filter)
1722 return AVERROR_BUG;
1723
1725 filter,
1726 filter_name, args, NULL, graph);
1727 if (ret < 0)
1728 return ret;
1729
1730 ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
1731 if (ret < 0)
1732 return ret;
1733
1734 *last_filter = ctx;
1735 *pad_idx = 0;
1736 return 0;
1737}
1738
1740 OutputFilter *ofilter, AVFilterInOut *out)
1741{
1742 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1743 AVFilterContext *last_filter = out->filter_ctx;
1744 AVBPrint bprint;
1745 int pad_idx = out->pad_idx;
1746 int ret;
1747 char name[255];
1748
1749 snprintf(name, sizeof(name), "out_%s", ofilter->output_name);
1751 avfilter_get_by_name("buffersink"),
1752 name, NULL, NULL, graph);
1753
1754 if (ret < 0)
1755 return ret;
1756
1757 if (ofp->flags & OFILTER_FLAG_CROP) {
1758 char crop_buf[64];
1759 snprintf(crop_buf, sizeof(crop_buf), "w=iw-%u-%u:h=ih-%u-%u:x=%u:y=%u",
1760 ofp->crop_left, ofp->crop_right,
1761 ofp->crop_top, ofp->crop_bottom,
1762 ofp->crop_left, ofp->crop_top);
1763 ret = insert_filter(&last_filter, &pad_idx, "crop", crop_buf);
1764 if (ret < 0)
1765 return ret;
1766 }
1767
1768 if (ofp->flags & OFILTER_FLAG_AUTOROTATE) {
1769 int32_t *displaymatrix = ofp->displaymatrix;
1770 double theta;
1771
1772 theta = get_rotation(displaymatrix);
1773
1774 if (fabs(theta - 90) < 1.0) {
1775 ret = insert_filter(&last_filter, &pad_idx, "transpose",
1776 displaymatrix[3] > 0 ? "cclock_flip" : "clock");
1777 } else if (fabs(theta - 180) < 1.0) {
1778 if (displaymatrix[0] < 0) {
1779 ret = insert_filter(&last_filter, &pad_idx, "hflip", NULL);
1780 if (ret < 0)
1781 return ret;
1782 }
1783 if (displaymatrix[4] < 0) {
1784 ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
1785 }
1786 } else if (fabs(theta - 270) < 1.0) {
1787 ret = insert_filter(&last_filter, &pad_idx, "transpose",
1788 displaymatrix[3] < 0 ? "clock_flip" : "cclock");
1789 } else if (fabs(theta) > 1.0) {
1790 char rotate_buf[64];
1791 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
1792 ret = insert_filter(&last_filter, &pad_idx, "rotate", rotate_buf);
1793 } else if (fabs(theta) < 1.0) {
1794 if (displaymatrix && displaymatrix[4] < 0) {
1795 ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
1796 }
1797 }
1798 if (ret < 0)
1799 return ret;
1800
1802 }
1803
1804 if ((ofp->width || ofp->height) && (ofp->flags & OFILTER_FLAG_AUTOSCALE) &&
1805 // skip add scale for hardware format
1806 !(ofp->format != AV_PIX_FMT_NONE &&
1808 char args[255];
1810 const AVDictionaryEntry *e = NULL;
1811
1812 snprintf(args, sizeof(args), "%d:%d",
1813 ofp->width, ofp->height);
1814
1815 while ((e = av_dict_iterate(ofp->sws_opts, e))) {
1816 av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
1817 }
1818
1819 snprintf(name, sizeof(name), "scaler_out_%s", ofilter->output_name);
1821 name, args, NULL, graph)) < 0)
1822 return ret;
1823 if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
1824 return ret;
1825
1826 last_filter = filter;
1827 pad_idx = 0;
1828 }
1829
1831 ofp->format != AV_PIX_FMT_NONE || !ofp->pix_fmts);
1833 choose_pix_fmts(ofp, &bprint);
1834 choose_color_spaces(ofp, &bprint);
1835 choose_color_ranges(ofp, &bprint);
1836 choose_alpha_modes(ofp, &bprint);
1837 choose_chroma_locations(ofp, &bprint);
1838 if (!av_bprint_is_complete(&bprint))
1839 return AVERROR(ENOMEM);
1840
1841 if (bprint.len) {
1843
1845 avfilter_get_by_name("format"),
1846 "format", bprint.str, NULL, graph);
1847 av_bprint_finalize(&bprint, NULL);
1848 if (ret < 0)
1849 return ret;
1850 if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
1851 return ret;
1852
1853 last_filter = filter;
1854 pad_idx = 0;
1855 }
1856
1857 snprintf(name, sizeof(name), "trim_out_%s", ofilter->output_name);
1859 &last_filter, &pad_idx, name);
1860 if (ret < 0)
1861 return ret;
1862
1863
1864 if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
1865 return ret;
1866
1867 return 0;
1868}
1869
1871 OutputFilter *ofilter, AVFilterInOut *out)
1872{
1873 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
1874 AVFilterContext *last_filter = out->filter_ctx;
1875 int pad_idx = out->pad_idx;
1876 AVBPrint args;
1877 char name[255];
1878 int ret;
1879
1880 snprintf(name, sizeof(name), "out_%s", ofilter->output_name);
1882 avfilter_get_by_name("abuffersink"),
1883 name, NULL, NULL, graph);
1884 if (ret < 0)
1885 return ret;
1886
1887#define AUTO_INSERT_FILTER(opt_name, filter_name, arg) do { \
1888 AVFilterContext *filt_ctx; \
1889 \
1890 av_log(ofilter, AV_LOG_INFO, opt_name " is forwarded to lavfi " \
1891 "similarly to -af " filter_name "=%s.\n", arg); \
1892 \
1893 ret = avfilter_graph_create_filter(&filt_ctx, \
1894 avfilter_get_by_name(filter_name), \
1895 filter_name, arg, NULL, graph); \
1896 if (ret < 0) \
1897 goto fail; \
1898 \
1899 ret = avfilter_link(last_filter, pad_idx, filt_ctx, 0); \
1900 if (ret < 0) \
1901 goto fail; \
1902 \
1903 last_filter = filt_ctx; \
1904 pad_idx = 0; \
1905} while (0)
1907
1908 choose_sample_fmts(ofp, &args);
1909 choose_sample_rates(ofp, &args);
1910 choose_channel_layouts(ofp, &args);
1911 if (!av_bprint_is_complete(&args)) {
1912 ret = AVERROR(ENOMEM);
1913 goto fail;
1914 }
1915 if (args.len) {
1917
1918 snprintf(name, sizeof(name), "format_out_%s", ofilter->output_name);
1920 avfilter_get_by_name("aformat"),
1921 name, args.str, NULL, graph);
1922 if (ret < 0)
1923 goto fail;
1924
1925 ret = avfilter_link(last_filter, pad_idx, format, 0);
1926 if (ret < 0)
1927 goto fail;
1928
1929 last_filter = format;
1930 pad_idx = 0;
1931 }
1932
1933 if (ofilter->apad)
1934 AUTO_INSERT_FILTER("-apad", "apad", ofilter->apad);
1935
1936 snprintf(name, sizeof(name), "trim for output %s", ofilter->output_name);
1938 &last_filter, &pad_idx, name);
1939 if (ret < 0)
1940 goto fail;
1941
1942 if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
1943 goto fail;
1944fail:
1945 av_bprint_finalize(&args, NULL);
1946
1947 return ret;
1948}
1949
1951 OutputFilter *ofilter, AVFilterInOut *out)
1952{
1953 switch (ofilter->type) {
1954 case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fgp, graph, ofilter, out);
1955 case AVMEDIA_TYPE_AUDIO: return configure_output_audio_filter(fgp, graph, ofilter, out);
1956 default: av_assert0(0); return 0;
1957 }
1958}
1959
1961{
1962 ifp->sub2video.last_pts = INT64_MIN;
1963 ifp->sub2video.end_pts = INT64_MIN;
1964
1965 /* sub2video structure has been (re-)initialized.
1966 Mark it as such so that the system will be
1967 initialized with the first received heartbeat. */
1968 ifp->sub2video.initialize = 1;
1969}
1970
1972 InputFilter *ifilter, AVFilterInOut *in)
1973{
1974 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
1975
1976 AVFilterContext *last_filter;
1977 const AVFilter *buffer_filt = avfilter_get_by_name("buffer");
1978 const AVPixFmtDescriptor *desc;
1979 char name[255];
1980 int ret, pad_idx = 0;
1982 if (!par)
1983 return AVERROR(ENOMEM);
1984
1985 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE)
1986 sub2video_prepare(ifp);
1987
1988 snprintf(name, sizeof(name), "graph %d input from stream %s", fg->index,
1989 ifp->opts.name);
1990
1991 ifilter->filter = avfilter_graph_alloc_filter(graph, buffer_filt, name);
1992 if (!ifilter->filter) {
1993 ret = AVERROR(ENOMEM);
1994 goto fail;
1995 }
1996
1997 par->format = ifp->format;
1998 par->time_base = ifp->time_base;
1999 par->frame_rate = ifp->opts.framerate;
2000 par->width = ifp->width;
2001 par->height = ifp->height;
2003 ifp->sample_aspect_ratio : (AVRational){ 0, 1 };
2004 par->color_space = ifp->color_space;
2005 par->color_range = ifp->color_range;
2006 par->alpha_mode = ifp->alpha_mode;
2007 par->chroma_location = ifp->chroma_location;
2008 par->hw_frames_ctx = ifp->hw_frames_ctx;
2009 par->side_data = ifp->side_data;
2010 par->nb_side_data = ifp->nb_side_data;
2011
2012 ret = av_buffersrc_parameters_set(ifilter->filter, par);
2013 if (ret < 0)
2014 goto fail;
2015 av_freep(&par);
2016
2017 ret = avfilter_init_dict(ifilter->filter, NULL);
2018 if (ret < 0)
2019 goto fail;
2020
2021 last_filter = ifilter->filter;
2022
2025
2026 if ((ifp->opts.flags & IFILTER_FLAG_CROP)) {
2027 char crop_buf[64];
2028 snprintf(crop_buf, sizeof(crop_buf), "w=iw-%u-%u:h=ih-%u-%u:x=%u:y=%u",
2029 ifp->opts.crop_left, ifp->opts.crop_right,
2030 ifp->opts.crop_top, ifp->opts.crop_bottom,
2031 ifp->opts.crop_left, ifp->opts.crop_top);
2032 ret = insert_filter(&last_filter, &pad_idx, "crop", crop_buf);
2033 if (ret < 0)
2034 return ret;
2035 }
2036
2037 // TODO: insert hwaccel enabled filters like transpose_vaapi into the graph
2038 ifp->displaymatrix_applied = 0;
2039 if ((ifp->opts.flags & IFILTER_FLAG_AUTOROTATE) &&
2040 !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
2041 int32_t *displaymatrix = ifp->displaymatrix;
2042 double theta;
2043
2044 theta = get_rotation(displaymatrix);
2045
2046 if (fabs(theta - 90) < 1.0) {
2047 ret = insert_filter(&last_filter, &pad_idx, "transpose",
2048 displaymatrix[3] > 0 ? "cclock_flip" : "clock");
2049 } else if (fabs(theta - 180) < 1.0) {
2050 if (displaymatrix[0] < 0) {
2051 ret = insert_filter(&last_filter, &pad_idx, "hflip", NULL);
2052 if (ret < 0)
2053 return ret;
2054 }
2055 if (displaymatrix[4] < 0) {
2056 ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
2057 }
2058 } else if (fabs(theta - 270) < 1.0) {
2059 ret = insert_filter(&last_filter, &pad_idx, "transpose",
2060 displaymatrix[3] < 0 ? "clock_flip" : "cclock");
2061 } else if (fabs(theta) > 1.0) {
2062 char rotate_buf[64];
2063 snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
2064 ret = insert_filter(&last_filter, &pad_idx, "rotate", rotate_buf);
2065 } else if (fabs(theta) < 1.0) {
2066 if (displaymatrix && displaymatrix[4] < 0) {
2067 ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
2068 }
2069 }
2070 if (ret < 0)
2071 return ret;
2072
2073 ifp->displaymatrix_applied = 1;
2074 }
2075
2076 snprintf(name, sizeof(name), "trim_in_%s", ifp->opts.name);
2078 &last_filter, &pad_idx, name);
2079 if (ret < 0)
2080 return ret;
2081
2082 if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
2083 return ret;
2084 return 0;
2085fail:
2086 av_freep(&par);
2087
2088 return ret;
2089}
2090
2092 InputFilter *ifilter, AVFilterInOut *in)
2093{
2094 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2095 AVFilterContext *last_filter;
2097 const AVFilter *abuffer_filt = avfilter_get_by_name("abuffer");
2098 AVBPrint args;
2099 char name[255];
2100 int ret, pad_idx = 0;
2101
2103 av_bprintf(&args, "time_base=%d/%d:sample_rate=%d:sample_fmt=%s",
2104 ifp->time_base.num, ifp->time_base.den,
2105 ifp->sample_rate,
2109 av_bprintf(&args, ":channel_layout=");
2111 } else
2112 av_bprintf(&args, ":channels=%d", ifp->ch_layout.nb_channels);
2113 snprintf(name, sizeof(name), "graph_%d_in_%s", fg->index, ifp->opts.name);
2114
2115 if ((ret = avfilter_graph_create_filter(&ifilter->filter, abuffer_filt,
2116 name, args.str, NULL,
2117 graph)) < 0)
2118 return ret;
2120 if (!par)
2121 return AVERROR(ENOMEM);
2122 par->side_data = ifp->side_data;
2123 par->nb_side_data = ifp->nb_side_data;
2124 ret = av_buffersrc_parameters_set(ifilter->filter, par);
2125 av_free(par);
2126 if (ret < 0)
2127 return ret;
2128 last_filter = ifilter->filter;
2129
2130 snprintf(name, sizeof(name), "trim for input stream %s", ifp->opts.name);
2132 &last_filter, &pad_idx, name);
2133 if (ret < 0)
2134 return ret;
2135
2136 if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
2137 return ret;
2138
2139 return 0;
2140}
2141
2143 InputFilter *ifilter, AVFilterInOut *in)
2144{
2145 switch (ifilter->type) {
2146 case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, graph, ifilter, in);
2147 case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, graph, ifilter, in);
2148 default: av_assert0(0); return 0;
2149 }
2150}
2151
2153{
2154 for (int i = 0; i < fg->nb_outputs; i++)
2155 fg->outputs[i]->filter = NULL;
2156 for (int i = 0; i < fg->nb_inputs; i++)
2157 fg->inputs[i]->filter = NULL;
2159}
2160
2162{
2163 return f->nb_inputs == 0 &&
2164 (!strcmp(f->filter->name, "buffer") ||
2165 !strcmp(f->filter->name, "abuffer"));
2166}
2167
2169{
2170 for (unsigned i = 0; i < graph->nb_filters; i++) {
2171 const AVFilterContext *f = graph->filters[i];
2172
2173 /* in addition to filters flagged as meta, also
2174 * disregard sinks and buffersources (but not other sources,
2175 * since they introduce data we are not aware of)
2176 */
2177 if (!((f->filter->flags & AVFILTER_FLAG_METADATA_ONLY) ||
2178 f->nb_outputs == 0 ||
2180 return 0;
2181 }
2182 return 1;
2183}
2184
2185static int sub2video_frame(InputFilter *ifilter, AVFrame *frame, int buffer);
2186
2188{
2189 FilterGraphPriv *fgp = fgp_from_fg(fg);
2190 AVBufferRef *hw_device;
2191 AVFilterInOut *inputs, *outputs, *cur;
2192 int ret = AVERROR_BUG, i, simple = filtergraph_is_simple(fg);
2193 int have_input_eof = 0;
2194 const char *graph_desc = fg->graph_desc;
2195
2196 cleanup_filtergraph(fg, fgt);
2197 fgt->graph = avfilter_graph_alloc();
2198 if (!fgt->graph)
2199 return AVERROR(ENOMEM);
2200
2201 if (simple) {
2203
2204 if (filter_nbthreads) {
2205 ret = av_opt_set(fgt->graph, "threads", filter_nbthreads, 0);
2206 if (ret < 0)
2207 goto fail;
2208 } else if (fgp->nb_threads >= 0) {
2209 ret = av_opt_set_int(fgt->graph, "threads", fgp->nb_threads, 0);
2210 if (ret < 0)
2211 return ret;
2212 }
2213
2214 if (av_dict_count(ofp->sws_opts)) {
2216 &fgt->graph->scale_sws_opts,
2217 '=', ':');
2218 if (ret < 0)
2219 goto fail;
2220 }
2221
2222 if (av_dict_count(ofp->swr_opts)) {
2223 char *args;
2224 ret = av_dict_get_string(ofp->swr_opts, &args, '=', ':');
2225 if (ret < 0)
2226 goto fail;
2227 av_opt_set(fgt->graph, "aresample_swr_opts", args, 0);
2228 av_free(args);
2229 }
2230 } else {
2232 }
2233
2235 ret = av_opt_set_int(fgt->graph, "max_buffered_frames", filter_buffered_frames, 0);
2236 if (ret < 0)
2237 return ret;
2238 }
2239
2240 hw_device = hw_device_for_filter();
2241
2242 ret = graph_parse(fg, fgt->graph, graph_desc, &inputs, &outputs, hw_device);
2243 if (ret < 0)
2244 goto fail;
2245
2246 for (cur = inputs, i = 0; cur; cur = cur->next, i++)
2247 if ((ret = configure_input_filter(fg, fgt->graph, fg->inputs[i], cur)) < 0) {
2250 goto fail;
2251 }
2253
2254 for (cur = outputs, i = 0; cur; cur = cur->next, i++) {
2255 ret = configure_output_filter(fgp, fgt->graph, fg->outputs[i], cur);
2256 if (ret < 0) {
2258 goto fail;
2259 }
2260 }
2262
2263 if (fgp->disable_conversions)
2265 if ((ret = avfilter_graph_config(fgt->graph, NULL)) < 0)
2266 goto fail;
2267
2268 fgp->is_meta = graph_is_meta(fgt->graph);
2269
2270 /* limit the lists of allowed formats to the ones selected, to
2271 * make sure they stay the same if the filtergraph is reconfigured later */
2272 for (int i = 0; i < fg->nb_outputs; i++) {
2273 const AVFrameSideData *const *sd;
2274 int nb_sd;
2275 OutputFilter *ofilter = fg->outputs[i];
2276 OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
2277 AVFilterContext *sink = ofilter->filter;
2278
2279 ofp->format = av_buffersink_get_format(sink);
2280
2281 ofp->width = av_buffersink_get_w(sink);
2282 ofp->height = av_buffersink_get_h(sink);
2287
2288 // If the timing parameters are not locked yet, get the tentative values
2289 // here but don't lock them. They will only be used if no output frames
2290 // are ever produced.
2291 if (!ofp->tb_out_locked) {
2293 if (ofp->fps.framerate.num <= 0 && ofp->fps.framerate.den <= 0 &&
2294 fr.num > 0 && fr.den > 0)
2295 ofp->fps.framerate = fr;
2297 }
2299
2303 if (ret < 0)
2304 goto fail;
2305 sd = av_buffersink_get_side_data(sink, &nb_sd);
2306 if (nb_sd)
2307 for (int j = 0; j < nb_sd; j++) {
2310 if (ret < 0) {
2312 goto fail;
2313 }
2314 }
2315 }
2316
2317 for (int i = 0; i < fg->nb_inputs; i++) {
2318 InputFilter *ifilter = fg->inputs[i];
2320 AVFrame *tmp;
2321 while (av_fifo_read(ifp->frame_queue, &tmp, 1) >= 0) {
2322 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
2323 ret = sub2video_frame(&ifp->ifilter, tmp, !fgt->graph);
2324 } else {
2325 if (ifp->type_src == AVMEDIA_TYPE_VIDEO) {
2326 if (ifp->displaymatrix_applied)
2328 }
2329 ret = av_buffersrc_add_frame(ifilter->filter, tmp);
2330 }
2332 if (ret < 0)
2333 goto fail;
2334 }
2335 }
2336
2337 /* send the EOFs for the finished inputs */
2338 for (int i = 0; i < fg->nb_inputs; i++) {
2339 InputFilter *ifilter = fg->inputs[i];
2340 if (fgt->eof_in[i]) {
2342 if (ret < 0)
2343 goto fail;
2344 have_input_eof = 1;
2345 }
2346 }
2347
2348 if (have_input_eof) {
2349 // make sure the EOF propagates to the end of the graph
2351 if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
2352 goto fail;
2353 }
2354
2355 return 0;
2356fail:
2357 cleanup_filtergraph(fg, fgt);
2358 return ret;
2359}
2360
2362{
2363 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2364 AVFrameSideData *sd;
2365 int ret;
2366
2367 ret = av_buffer_replace(&ifp->hw_frames_ctx, frame->hw_frames_ctx);
2368 if (ret < 0)
2369 return ret;
2370
2371 ifp->time_base = (ifilter->type == AVMEDIA_TYPE_AUDIO) ? (AVRational){ 1, frame->sample_rate } :
2373 frame->time_base;
2374
2375 ifp->format = frame->format;
2376
2377 ifp->width = frame->width;
2378 ifp->height = frame->height;
2379 ifp->sample_aspect_ratio = frame->sample_aspect_ratio;
2380 ifp->color_space = frame->colorspace;
2381 ifp->color_range = frame->color_range;
2382 ifp->alpha_mode = frame->alpha_mode;
2383 ifp->chroma_location = frame->chroma_location;
2384
2385 ifp->sample_rate = frame->sample_rate;
2386 ret = av_channel_layout_copy(&ifp->ch_layout, &frame->ch_layout);
2387 if (ret < 0)
2388 return ret;
2389
2391 for (int i = 0; i < frame->nb_side_data; i++) {
2392 const AVSideDataDescriptor *desc = av_frame_side_data_desc(frame->side_data[i]->type);
2393
2394 if (!(desc->props & AV_SIDE_DATA_PROP_GLOBAL))
2395 continue;
2396
2398 &ifp->nb_side_data,
2399 frame->side_data[i], 0);
2400 if (ret < 0)
2401 return ret;
2402 }
2403
2405 if (sd) {
2406 memcpy(ifp->displaymatrix, sd->data, sizeof(ifp->displaymatrix));
2407 if ((ifp->opts.flags & IFILTER_FLAG_AUTOROTATE) &&
2410 }
2411 ifp->displaymatrix_present = !!sd;
2412
2413 /* Copy downmix related side data to InputFilterPriv so it may be propagated
2414 * to the filter chain even though it's not "global", as filters like aresample
2415 * require this information during init and not when remixing a frame */
2417 if (sd) {
2419 &ifp->nb_side_data, sd, 0);
2420 if (ret < 0)
2421 return ret;
2422 memcpy(&ifp->downmixinfo, sd->data, sizeof(ifp->downmixinfo));
2423 }
2424 ifp->downmixinfo_present = !!sd;
2426 if (sd) {
2428 &ifp->nb_side_data, sd, 0);
2429 if (ret < 0)
2430 return ret;
2431 ret = av_buffer_replace(&ifp->downmixmatrix, sd->buf);
2432 if (ret < 0)
2433 return ret;
2434 ifp->downmixmatrix_size = sd->size;
2435 }
2436 ifp->downmixmatrix_present = !!sd;
2437
2438 return 0;
2439}
2440
2442{
2443 const OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
2444 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
2445
2446 if (!ifp->opts.framerate.num) {
2447 ifp->opts.framerate = ofp->fps.framerate;
2448 if (ifp->opts.framerate.num > 0 && ifp->opts.framerate.den > 0)
2449 ifp->opts.flags |= IFILTER_FLAG_CFR;
2450 }
2451
2452 for (int i = 0; i < ofp->nb_side_data; i++) {
2455 if (ret < 0)
2456 return ret;
2457 }
2458
2459 return 0;
2460}
2461
2463{
2464 const FilterGraphPriv *fgp = cfgp_from_cfg(fg);
2465 return fgp->is_simple;
2466}
2467
2469 double time, const char *target,
2470 const char *command, const char *arg, int all_filters)
2471{
2472 int ret;
2473
2474 if (!graph)
2475 return;
2476
2477 if (time < 0) {
2478 char response[4096];
2479 ret = avfilter_graph_send_command(graph, target, command, arg,
2480 response, sizeof(response),
2481 all_filters ? 0 : AVFILTER_CMD_FLAG_ONE);
2482 fprintf(stderr, "Command reply for stream %d: ret:%d res:\n%s",
2483 fg->index, ret, response);
2484 } else if (!all_filters) {
2485 fprintf(stderr, "Queuing commands only on filters supporting the specific command is unsupported\n");
2486 } else {
2487 ret = avfilter_graph_queue_command(graph, target, command, arg, 0, time);
2488 if (ret < 0)
2489 fprintf(stderr, "Queuing command failed with error %s\n", av_err2str(ret));
2490 }
2491}
2492
2493static int choose_input(const FilterGraph *fg, const FilterGraphThread *fgt)
2494{
2495 int nb_requests, nb_requests_max = -1;
2496 int best_input = -1;
2497
2498 for (int i = 0; i < fg->nb_inputs; i++) {
2499 InputFilter *ifilter = fg->inputs[i];
2500
2501 if (fgt->eof_in[i])
2502 continue;
2503
2504 nb_requests = av_buffersrc_get_nb_failed_requests(ifilter->filter);
2505 if (nb_requests > nb_requests_max) {
2506 nb_requests_max = nb_requests;
2507 best_input = i;
2508 }
2509 }
2510
2511 av_assert0(best_input >= 0);
2512
2513 return best_input;
2514}
2515
2517{
2518 OutputFilter *ofilter = &ofp->ofilter;
2519 FPSConvContext *fps = &ofp->fps;
2520 AVRational tb = (AVRational){ 0, 0 };
2521 AVRational fr;
2522 const FrameData *fd;
2523
2524 fd = frame_data_c(frame);
2525
2526 // apply -enc_time_base
2527 if (ofp->enc_timebase.num == ENC_TIME_BASE_DEMUX &&
2528 (fd->dec.tb.num <= 0 || fd->dec.tb.den <= 0)) {
2529 av_log(ofp, AV_LOG_ERROR,
2530 "Demuxing timebase not available - cannot use it for encoding\n");
2531 return AVERROR(EINVAL);
2532 }
2533
2534 switch (ofp->enc_timebase.num) {
2535 case 0: break;
2536 case ENC_TIME_BASE_DEMUX: tb = fd->dec.tb; break;
2537 case ENC_TIME_BASE_FILTER: tb = frame->time_base; break;
2538 default: tb = ofp->enc_timebase; break;
2539 }
2540
2541 if (ofilter->type == AVMEDIA_TYPE_AUDIO) {
2542 tb = tb.num ? tb : (AVRational){ 1, frame->sample_rate };
2543 goto finish;
2544 }
2545
2546 fr = fps->framerate;
2547 if (!fr.num) {
2549 if (fr_sink.num > 0 && fr_sink.den > 0)
2550 fr = fr_sink;
2551 }
2552
2553 if (fps->vsync_method == VSYNC_CFR || fps->vsync_method == VSYNC_VSCFR) {
2554 if (!fr.num && !fps->framerate_max.num) {
2555 fr = (AVRational){25, 1};
2557 "No information "
2558 "about the input framerate is available. Falling "
2559 "back to a default value of 25fps. Use the -r option "
2560 "if you want a different framerate.\n");
2561 }
2562
2563 if (fps->framerate_max.num &&
2564 (av_q2d(fr) > av_q2d(fps->framerate_max) ||
2565 !fr.den))
2566 fr = fps->framerate_max;
2567 }
2568
2569 if (fr.num > 0) {
2570 if (fps->framerate_supported) {
2571 int idx = av_find_nearest_q_idx(fr, fps->framerate_supported);
2572 fr = fps->framerate_supported[idx];
2573 }
2574 if (fps->framerate_clip) {
2575 av_reduce(&fr.num, &fr.den,
2576 fr.num, fr.den, fps->framerate_clip);
2577 }
2578 }
2579
2580 if (!(tb.num > 0 && tb.den > 0))
2581 tb = av_inv_q(fr);
2582 if (!(tb.num > 0 && tb.den > 0))
2583 tb = frame->time_base;
2584
2585 fps->framerate = fr;
2586finish:
2587 ofp->tb_out = tb;
2588 ofp->tb_out_locked = 1;
2589
2590 return 0;
2591}
2592
2593static double adjust_frame_pts_to_encoder_tb(void *logctx, AVFrame *frame,
2595{
2596 double float_pts = AV_NOPTS_VALUE; // this is identical to frame.pts but with higher precision
2597
2598 AVRational tb = tb_dst;
2599 AVRational filter_tb = frame->time_base;
2600 const int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16);
2601
2602 if (frame->pts == AV_NOPTS_VALUE)
2603 goto early_exit;
2604
2605 tb.den <<= extra_bits;
2606 float_pts = av_rescale_q(frame->pts, filter_tb, tb) -
2608 float_pts /= 1 << extra_bits;
2609 // when float_pts is not exactly an integer,
2610 // avoid exact midpoints to reduce the chance of rounding differences, this
2611 // can be removed in case the fps code is changed to work with integers
2612 if (float_pts != llrint(float_pts))
2613 float_pts += FFSIGN(float_pts) * 1.0 / (1<<17);
2614
2615 frame->pts = av_rescale_q(frame->pts, filter_tb, tb_dst) -
2617 frame->time_base = tb_dst;
2618
2619early_exit:
2620
2621 if (debug_ts) {
2622 av_log(logctx, AV_LOG_INFO,
2623 "filter -> pts:%s pts_time:%s exact:%f time_base:%d/%d\n",
2624 frame ? av_ts2str(frame->pts) : "NULL",
2625 av_ts2timestr(frame->pts, &tb_dst),
2626 float_pts, tb_dst.num, tb_dst.den);
2627 }
2628
2629 return float_pts;
2630}
2631
2633{
2634 int64_t max2, min2, m;
2635
2636 if (a >= b) {
2637 max2 = a;
2638 min2 = b;
2639 } else {
2640 max2 = b;
2641 min2 = a;
2642 }
2643 m = (c >= max2) ? max2 : c;
2644
2645 return (m >= min2) ? m : min2;
2646}
2647
2648
2649/* Convert frame timestamps to the encoder timebase and decide how many times
2650 * should this (and possibly previous) frame be repeated in order to conform to
2651 * desired target framerate (if any).
2652 */
2654 int64_t *nb_frames, int64_t *nb_frames_prev)
2655{
2656 OutputFilter *ofilter = &ofp->ofilter;
2657 FPSConvContext *fps = &ofp->fps;
2658 double delta0, delta, sync_ipts, duration;
2659
2660 if (!frame) {
2661 *nb_frames_prev = *nb_frames = median3(fps->frames_prev_hist[0],
2662 fps->frames_prev_hist[1],
2663 fps->frames_prev_hist[2]);
2664
2665 if (!*nb_frames && fps->last_dropped) {
2666 atomic_fetch_add(&ofilter->nb_frames_drop, 1);
2667 fps->last_dropped++;
2668 }
2669
2670 goto finish;
2671 }
2672
2673 duration = frame->duration * av_q2d(frame->time_base) / av_q2d(ofp->tb_out);
2674
2675 sync_ipts = adjust_frame_pts_to_encoder_tb(ofilter->graph, frame,
2676 ofp->tb_out, ofp->ts_offset);
2677 /* delta0 is the "drift" between the input frame and
2678 * where it would fall in the output. */
2679 delta0 = sync_ipts - ofp->next_pts;
2680 delta = delta0 + duration;
2681
2682 // tracks the number of times the PREVIOUS frame should be duplicated,
2683 // mostly for variable framerate (VFR)
2684 *nb_frames_prev = 0;
2685 /* by default, we output a single frame */
2686 *nb_frames = 1;
2687
2688 if (delta0 < 0 &&
2689 delta > 0 &&
2691 if (delta0 < -0.6) {
2692 av_log(ofp, AV_LOG_VERBOSE, "Past duration %f too large\n", -delta0);
2693 } else
2694 av_log(ofp, AV_LOG_DEBUG, "Clipping frame in rate conversion by %f\n", -delta0);
2695 sync_ipts = ofp->next_pts;
2696 duration += delta0;
2697 delta0 = 0;
2698 }
2699
2700 switch (fps->vsync_method) {
2701 case VSYNC_VSCFR:
2702 if (fps->frame_number == 0 && delta0 >= 0.5) {
2703 av_log(ofp, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta0));
2704 delta = duration;
2705 delta0 = 0;
2706 ofp->next_pts = llrint(sync_ipts);
2707 }
2709 case VSYNC_CFR:
2710 // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
2712 *nb_frames = 0;
2713 } else if (delta < -1.1)
2714 *nb_frames = 0;
2715 else if (delta > 1.1) {
2716 *nb_frames = llrintf(delta);
2717 if (delta0 > 1.1)
2718 *nb_frames_prev = llrintf(delta0 - 0.6);
2719 }
2720 frame->duration = 1;
2721 break;
2722 case VSYNC_VFR:
2723 if (delta <= -0.6)
2724 *nb_frames = 0;
2725 else if (delta > 0.6)
2726 ofp->next_pts = llrint(sync_ipts);
2727 frame->duration = llrint(duration);
2728 break;
2729 case VSYNC_PASSTHROUGH:
2730 ofp->next_pts = llrint(sync_ipts);
2731 frame->duration = llrint(duration);
2732 break;
2733 default:
2734 av_assert0(0);
2735 }
2736
2737finish:
2738 memmove(fps->frames_prev_hist + 1,
2739 fps->frames_prev_hist,
2740 sizeof(fps->frames_prev_hist[0]) * (FF_ARRAY_ELEMS(fps->frames_prev_hist) - 1));
2741 fps->frames_prev_hist[0] = *nb_frames_prev;
2742
2743 if (*nb_frames_prev == 0 && fps->last_dropped) {
2744 atomic_fetch_add(&ofilter->nb_frames_drop, 1);
2746 "*** dropping frame %"PRId64" at ts %"PRId64"\n",
2747 fps->frame_number, fps->last_frame->pts);
2748 }
2749 if (*nb_frames > (*nb_frames_prev && fps->last_dropped) + (*nb_frames > *nb_frames_prev)) {
2750 uint64_t nb_frames_dup;
2751 if (*nb_frames > dts_error_threshold * 30) {
2752 av_log(ofp, AV_LOG_ERROR, "%"PRId64" frame duplication too large, skipping\n", *nb_frames - 1);
2753 atomic_fetch_add(&ofilter->nb_frames_drop, 1);
2754 *nb_frames = 0;
2755 return;
2756 }
2757 nb_frames_dup = atomic_fetch_add(&ofilter->nb_frames_dup,
2758 *nb_frames - (*nb_frames_prev && fps->last_dropped) - (*nb_frames > *nb_frames_prev));
2759 av_log(ofp, AV_LOG_VERBOSE, "*** %"PRId64" dup!\n", *nb_frames - 1);
2760 if (nb_frames_dup > fps->dup_warning) {
2761 av_log(ofp, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", fps->dup_warning);
2762 fps->dup_warning *= 10;
2763 }
2764 }
2765
2766 fps->last_dropped = *nb_frames == *nb_frames_prev && frame;
2767 fps->dropped_keyframe |= fps->last_dropped && (frame->flags & AV_FRAME_FLAG_KEY);
2768}
2769
2771{
2773
2774 if (!ifp->eof) {
2776 ifp->eof = 1;
2777 }
2778}
2779
2781{
2783 int ret;
2784
2785 // we are finished and no frames were ever seen at this output,
2786 // at least initialize the encoder with a dummy frame
2787 if (!fgt->got_frame) {
2788 AVFrame *frame = fgt->frame;
2789 FrameData *fd;
2790
2791 frame->time_base = ofp->tb_out;
2792 frame->format = ofp->format;
2793
2794 frame->width = ofp->width;
2795 frame->height = ofp->height;
2796 frame->sample_aspect_ratio = ofp->sample_aspect_ratio;
2797
2798 frame->sample_rate = ofp->sample_rate;
2799 if (ofp->ch_layout.nb_channels) {
2800 ret = av_channel_layout_copy(&frame->ch_layout, &ofp->ch_layout);
2801 if (ret < 0)
2802 return ret;
2803 }
2804
2805 fd = frame_data(frame);
2806 if (!fd)
2807 return AVERROR(ENOMEM);
2808
2811 ofp->side_data, ofp->nb_side_data, 0);
2812 if (ret < 0)
2813 return ret;
2814
2815 fd->frame_rate_filter = ofp->fps.framerate;
2816
2817 av_assert0(!frame->buf[0]);
2818
2820 "No filtered frames for output stream, trying to "
2821 "initialize anyway.\n");
2822
2823 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, frame);
2824 if (ret < 0) {
2826 return ret;
2827 }
2828 }
2829
2830 fgt->eof_out[ofp->ofilter.index] = 1;
2831
2832 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, NULL);
2833 return (ret == AVERROR_EOF) ? 0 : ret;
2834}
2835
2837 AVFrame *frame)
2838{
2840 AVFrame *frame_prev = ofp->fps.last_frame;
2841 enum AVMediaType type = ofp->ofilter.type;
2842
2843 int64_t nb_frames = !!frame, nb_frames_prev = 0;
2844
2845 if (type == AVMEDIA_TYPE_VIDEO && (frame || fgt->got_frame))
2846 video_sync_process(ofp, frame, &nb_frames, &nb_frames_prev);
2847
2848 for (int64_t i = 0; i < nb_frames; i++) {
2849 AVFrame *frame_out;
2850 int ret;
2851
2852 if (type == AVMEDIA_TYPE_VIDEO) {
2853 AVFrame *frame_in = (i < nb_frames_prev && frame_prev->buf[0]) ?
2854 frame_prev : frame;
2855 if (!frame_in)
2856 break;
2857
2858 frame_out = fgp->frame_enc;
2859 ret = av_frame_ref(frame_out, frame_in);
2860 if (ret < 0)
2861 return ret;
2862
2863 frame_out->pts = ofp->next_pts;
2864
2865 if (ofp->fps.dropped_keyframe) {
2866 frame_out->flags |= AV_FRAME_FLAG_KEY;
2867 ofp->fps.dropped_keyframe = 0;
2868 }
2869 } else {
2870 frame->pts = (frame->pts == AV_NOPTS_VALUE) ? ofp->next_pts :
2871 av_rescale_q(frame->pts, frame->time_base, ofp->tb_out) -
2873
2874 frame->time_base = ofp->tb_out;
2875 frame->duration = av_rescale_q(frame->nb_samples,
2876 (AVRational){ 1, frame->sample_rate },
2877 ofp->tb_out);
2878
2879 ofp->next_pts = frame->pts + frame->duration;
2880
2881 frame_out = frame;
2882 }
2883
2884 // send the frame to consumers
2885 ret = sch_filter_send(fgp->sch, fgp->sch_idx, ofp->ofilter.index, frame_out);
2886 if (ret < 0) {
2887 av_frame_unref(frame_out);
2888
2889 if (!fgt->eof_out[ofp->ofilter.index]) {
2890 fgt->eof_out[ofp->ofilter.index] = 1;
2891 fgp->nb_outputs_done++;
2892 }
2893
2894 return ret == AVERROR_EOF ? 0 : ret;
2895 }
2896
2897 if (type == AVMEDIA_TYPE_VIDEO) {
2898 ofp->fps.frame_number++;
2899 ofp->next_pts++;
2900
2901 if (i == nb_frames_prev && frame)
2902 frame->flags &= ~AV_FRAME_FLAG_KEY;
2903 }
2904
2905 fgt->got_frame = 1;
2906 }
2907
2908 if (frame && frame_prev) {
2909 av_frame_unref(frame_prev);
2910 av_frame_move_ref(frame_prev, frame);
2911 }
2912
2913 if (!frame)
2914 return close_output(ofp, fgt);
2915
2916 return 0;
2917}
2918
2920 AVFrame *frame)
2921{
2923 FilterGraph *fg = &fgp->fg;
2925 FrameData *fd;
2926 int ret;
2927
2930 if (ret == AVERROR_EOF && !fgt->eof_out[ofp->ofilter.index]) {
2931 ret = fg_output_frame(ofp, fgt, NULL);
2932 return (ret < 0) ? ret : 1;
2933 } else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2934 return 1;
2935 } else if (ret < 0) {
2937 "Error in retrieving a frame from the filtergraph: %s\n",
2938 av_err2str(ret));
2939 return ret;
2940 }
2941
2942 if (fgt->eof_out[ofp->ofilter.index]) {
2944 return 0;
2945 }
2946
2948
2949 if (debug_ts)
2950 av_log(ofp, AV_LOG_INFO, "filter_raw -> pts:%s pts_time:%s time_base:%d/%d\n",
2951 av_ts2str(frame->pts), av_ts2timestr(frame->pts, &frame->time_base),
2952 frame->time_base.num, frame->time_base.den);
2953
2954 // Choose the output timebase the first time we get a frame.
2955 if (!ofp->tb_out_locked) {
2957 if (ret < 0) {
2958 av_log(ofp, AV_LOG_ERROR, "Could not choose an output time base\n");
2960 return ret;
2961 }
2962 }
2963
2964 fd = frame_data(frame);
2965 if (!fd) {
2967 return AVERROR(ENOMEM);
2968 }
2969
2971 if (!fgt->got_frame) {
2973 ofp->side_data, ofp->nb_side_data, 0);
2974 if (ret < 0) {
2976 return ret;
2977 }
2978 }
2979
2980 // Copy global side data to the output frame for the cases the
2981 // filtergraph is internal (e.g. created to merge a Tile Grid)
2982 // which don't come from a decoder that would have already
2983 // copied said side data from the global decoder context.
2984 if (fg->is_internal) {
2985 ret = clone_side_data(&frame->side_data, &frame->nb_side_data,
2986 ofp->side_data, ofp->nb_side_data,
2988 if (ret < 0 && ret != AVERROR(EEXIST)) {
2990 return ret;
2991 }
2992 }
2993
2995
2996 // only use bits_per_raw_sample passed through from the decoder
2997 // if the filtergraph did not touch the frame data
2998 if (!fgp->is_meta)
2999 fd->bits_per_raw_sample = 0;
3000
3001 if (ofp->ofilter.type == AVMEDIA_TYPE_VIDEO) {
3002 if (!frame->duration) {
3004 if (fr.num > 0 && fr.den > 0)
3005 frame->duration = av_rescale_q(1, av_inv_q(fr), frame->time_base);
3006 }
3007
3008 fd->frame_rate_filter = ofp->fps.framerate;
3009 }
3010
3011 ret = fg_output_frame(ofp, fgt, frame);
3013 if (ret < 0)
3014 return ret;
3015
3016 return 0;
3017}
3018
3019/* retrieve all frames available at filtergraph outputs
3020 * and send them to consumers */
3022 AVFrame *frame)
3023{
3024 FilterGraphPriv *fgp = fgp_from_fg(fg);
3025
3026 // graph not configured, just select the input to request
3027 if (!fgt->graph) {
3028 for (int i = 0; i < fg->nb_inputs; i++) {
3030 if (ifp->format < 0 && !fgt->eof_in[i]) {
3031 fgt->next_in = i;
3032 return 0;
3033 }
3034 }
3035
3036 // This state - graph is not configured, but all inputs are either
3037 // initialized or EOF - should be unreachable because sending EOF to a
3038 // filter without even a fallback format should fail
3039 av_assert0(0);
3040 return AVERROR_BUG;
3041 }
3042
3043 if (fgp->nb_outputs_done < fg->nb_outputs) {
3044 int ret;
3045
3046 /* Reap all buffers present in the buffer sinks */
3047 for (int i = 0; i < fg->nb_outputs; i++) {
3049
3050 ret = 0;
3051 while (!ret) {
3052 ret = fg_output_step(ofp, fgt, frame);
3053 if (ret < 0)
3054 return ret;
3055 }
3056 }
3057
3058
3060 if (ret == AVERROR(EAGAIN)) {
3061 fgt->next_in = choose_input(fg, fgt);
3062 return 0;
3063 } else if (ret < 0) {
3064 if (ret == AVERROR_EOF)
3065 av_log(fg, AV_LOG_VERBOSE, "Filtergraph returned EOF, finishing\n");
3066 else
3067 av_log(fg, AV_LOG_ERROR,
3068 "Error requesting a frame from the filtergraph: %s\n",
3069 av_err2str(ret));
3070 return ret;
3071 }
3072 fgt->next_in = fg->nb_inputs;
3073
3074 // return so that scheduler can rate-control us
3075 return 0;
3076 }
3077
3078 return AVERROR_EOF;
3079}
3080
3082{
3083 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
3084 int64_t pts2;
3085
3086 /* subtitles seem to be usually muxed ahead of other streams;
3087 if not, subtracting a larger time here is necessary */
3088 pts2 = av_rescale_q(pts, tb, ifp->time_base) - 1;
3089
3090 /* do not send the heartbeat frame if the subtitle is already ahead */
3091 if (pts2 <= ifp->sub2video.last_pts)
3092 return;
3093
3094 if (pts2 >= ifp->sub2video.end_pts || ifp->sub2video.initialize)
3095 /* if we have hit the end of the current displayed subpicture,
3096 or if we need to initialize the system, update the
3097 overlaid subpicture and its start/end times */
3098 sub2video_update(ifp, pts2 + 1, NULL);
3099 else
3100 sub2video_push_ref(ifp, pts2);
3101}
3102
3104{
3105 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
3106 int ret;
3107
3108 if (buffer) {
3109 // queue a NULL entry for EOF, so it is not lost when
3110 // the queue is replayed after configuring the graph
3111 AVFrame *tmp = NULL;
3112
3113 if (frame) {
3114 tmp = av_frame_alloc();
3115 if (!tmp)
3116 return AVERROR(ENOMEM);
3117
3119 }
3120
3121 ret = av_fifo_write(ifp->frame_queue, &tmp, 1);
3122 if (ret < 0) {
3124 return ret;
3125 }
3126
3127 return 0;
3128 }
3129
3130 // heartbeat frame
3131 if (frame && !frame->buf[0]) {
3132 sub2video_heartbeat(ifilter, frame->pts, frame->time_base);
3133 return 0;
3134 }
3135
3136 if (!frame) {
3137 if (ifp->sub2video.end_pts < INT64_MAX)
3138 sub2video_update(ifp, INT64_MAX, NULL);
3139
3140 return av_buffersrc_add_frame(ifilter->filter, NULL);
3141 }
3142
3143 ifp->width = frame->width ? frame->width : ifp->width;
3144 ifp->height = frame->height ? frame->height : ifp->height;
3145
3146 sub2video_update(ifp, INT64_MIN, (const AVSubtitle*)frame->buf[0]->data);
3147
3148 return 0;
3149}
3150
3151static int send_eof(FilterGraphThread *fgt, InputFilter *ifilter,
3153{
3154 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
3155 int ret;
3156
3157 if (fgt->eof_in[ifilter->index])
3158 return 0;
3159
3160 fgt->eof_in[ifilter->index] = 1;
3161
3162 if (ifilter->filter) {
3163 pts = av_rescale_q_rnd(pts, tb, ifp->time_base,
3165
3167 if (ret < 0)
3168 return ret;
3169 } else {
3170 if (ifp->format < 0) {
3171 // the filtergraph was never configured, use the fallback parameters
3172 ifp->format = ifp->opts.fallback->format;
3173 ifp->sample_rate = ifp->opts.fallback->sample_rate;
3174 ifp->width = ifp->opts.fallback->width;
3175 ifp->height = ifp->opts.fallback->height;
3177 ifp->color_space = ifp->opts.fallback->colorspace;
3178 ifp->color_range = ifp->opts.fallback->color_range;
3179 ifp->alpha_mode = ifp->opts.fallback->alpha_mode;
3181 ifp->time_base = ifp->opts.fallback->time_base;
3182
3184 &ifp->opts.fallback->ch_layout);
3185 if (ret < 0)
3186 return ret;
3187
3190 ifp->opts.fallback->side_data,
3191 ifp->opts.fallback->nb_side_data, 0);
3192 if (ret < 0)
3193 return ret;
3194
3195 if (ifilter_has_all_input_formats(ifilter->graph)) {
3196 ret = configure_filtergraph(ifilter->graph, fgt);
3197 if (ret < 0) {
3198 av_log(ifilter->graph, AV_LOG_ERROR, "Error initializing filters!\n");
3199 return ret;
3200 }
3201 }
3202 }
3203
3204 if (ifp->format < 0) {
3205 av_log(ifilter->graph, AV_LOG_ERROR,
3206 "Cannot determine format of input %s after EOF\n",
3207 ifp->opts.name);
3208 return AVERROR_INVALIDDATA;
3209 }
3210 }
3211
3212 return 0;
3213}
3214
3216 VIDEO_CHANGED = (1 << 0),
3217 AUDIO_CHANGED = (1 << 1),
3218 MATRIX_CHANGED = (1 << 2),
3221};
3222
3223static const char *unknown_if_null(const char *str)
3224{
3225 return str ? str : "unknown";
3226}
3227
3229 InputFilter *ifilter, AVFrame *frame, int force_reinit)
3230{
3231 FilterGraphPriv *fgp = fgp_from_fg(fg);
3232 InputFilterPriv *ifp = ifp_from_ifilter(ifilter);
3233 FrameData *fd;
3234 AVFrameSideData *sd;
3235 int need_reinit = 0, ret;
3236
3237 /* determine if the parameters for this input changed */
3238 switch (ifilter->type) {
3239 case AVMEDIA_TYPE_AUDIO:
3240 if (ifp->format != frame->format ||
3241 ifp->sample_rate != frame->sample_rate ||
3242 av_channel_layout_compare(&ifp->ch_layout, &frame->ch_layout))
3243 need_reinit |= AUDIO_CHANGED;
3244 break;
3245 case AVMEDIA_TYPE_VIDEO:
3246 if (ifp->format != frame->format ||
3247 ifp->width != frame->width ||
3248 ifp->height != frame->height ||
3249 ifp->color_space != frame->colorspace ||
3250 ifp->color_range != frame->color_range ||
3251 ifp->alpha_mode != frame->alpha_mode ||
3252 ifp->chroma_location != frame->chroma_location)
3253 need_reinit |= VIDEO_CHANGED;
3254 break;
3255 }
3256
3258 if (!ifp->displaymatrix_present ||
3259 memcmp(sd->data, ifp->displaymatrix, sizeof(ifp->displaymatrix)))
3260 need_reinit |= MATRIX_CHANGED;
3261 } else if (ifp->displaymatrix_present)
3262 need_reinit |= MATRIX_CHANGED;
3263
3265 if (!ifp->downmixinfo_present ||
3266 memcmp(sd->data, &ifp->downmixinfo, sizeof(ifp->downmixinfo)))
3267 need_reinit |= DOWNMIX_CHANGED;
3268 } else if (ifp->downmixinfo_present)
3269 need_reinit |= DOWNMIX_CHANGED;
3270
3272 if (!ifp->downmixmatrix_present ||
3273 sd->size != ifp->downmixmatrix_size || memcmp(sd->data, ifp->downmixmatrix->data, sd->size))
3274 need_reinit |= DOWNMIX_CHANGED;
3275 } else if (ifp->downmixmatrix_present)
3276 need_reinit |= DOWNMIX_CHANGED;
3277
3278 if (need_reinit && fgt->graph && (ifp->opts.flags & IFILTER_FLAG_DROPCHANGED)) {
3279 ifp->nb_dropped++;
3280 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);
3282 return 0;
3283 }
3284
3285 if (!(ifp->opts.flags & IFILTER_FLAG_REINIT) && fgt->graph)
3286 need_reinit = 0;
3287
3288 if (!!ifp->hw_frames_ctx != !!frame->hw_frames_ctx ||
3289 (ifp->hw_frames_ctx && ifp->hw_frames_ctx->data != frame->hw_frames_ctx->data))
3290 need_reinit |= HWACCEL_CHANGED;
3291
3292 if (need_reinit) {
3294 if (ret < 0)
3295 return ret;
3296
3297 /* Inputs bound to a filtergraph output will have some fields unset.
3298 * Handle them here */
3299 if (ifp->ofilter_src) {
3301 if (ret < 0)
3302 return ret;
3303 }
3304 }
3305
3306 /* (re)init the graph if possible, otherwise buffer the frame and return */
3307 if (need_reinit || force_reinit || !fgt->graph) {
3309
3310 if (!tmp)
3311 return AVERROR(ENOMEM);
3312
3315
3316 ret = av_fifo_write(ifp->frame_queue, &tmp, 1);
3317 if (ret < 0)
3319
3320 return ret;
3321 }
3322
3323 ret = fgt->graph ? read_frames(fg, fgt, tmp) : 0;
3325 if (ret < 0)
3326 return ret;
3327
3328 if (fgt->graph) {
3329 AVBPrint reason;
3331 if (need_reinit & AUDIO_CHANGED) {
3332 const char *sample_format_name = av_get_sample_fmt_name(frame->format);
3333 av_bprintf(&reason, "audio parameters changed to %d Hz, ", frame->sample_rate);
3334 av_channel_layout_describe_bprint(&frame->ch_layout, &reason);
3335 av_bprintf(&reason, ", %s, ", unknown_if_null(sample_format_name));
3336 }
3337 if (need_reinit & VIDEO_CHANGED) {
3338 const char *pixel_format_name = av_get_pix_fmt_name(frame->format);
3339 const char *color_space_name = av_color_space_name(frame->colorspace);
3340 const char *color_range_name = av_color_range_name(frame->color_range);
3341 const char *alpha_mode = av_alpha_mode_name(frame->alpha_mode);
3342 const char *chroma_location = av_chroma_location_name(frame->chroma_location);
3343 av_bprintf(&reason, "video parameters changed to %s(%s, %s), %dx%d, %s alpha, %s chroma, ",
3344 unknown_if_null(pixel_format_name), unknown_if_null(color_range_name),
3345 unknown_if_null(color_space_name), frame->width, frame->height,
3346 unknown_if_null(alpha_mode), unknown_if_null(chroma_location));
3347 }
3348 if (need_reinit & MATRIX_CHANGED)
3349 av_bprintf(&reason, "display matrix changed, ");
3350 if (need_reinit & DOWNMIX_CHANGED)
3351 av_bprintf(&reason, "downmix medatata changed, ");
3352 if (need_reinit & HWACCEL_CHANGED)
3353 av_bprintf(&reason, "hwaccel changed, ");
3354 if (force_reinit)
3355 av_bprintf(&reason, "reinitialization arguments were provided, ");
3356 if (reason.len > 1)
3357 reason.str[reason.len - 2] = '\0'; // remove last comma
3358 av_log(fg, AV_LOG_INFO, "Reconfiguring filter graph%s%s\n", reason.len ? " because " : "", reason.str);
3359 } else {
3360 /* Choke all input to avoid buffering excessive frames while the
3361 * initial filter graph is being configured, and before we have a
3362 * preferred input */
3364 }
3365
3366 ret = configure_filtergraph(fg, fgt);
3367 if (ret < 0) {
3368 av_log(fg, AV_LOG_ERROR, "Error reinitializing filters!\n");
3369 return ret;
3370 }
3371 }
3372
3373 frame->pts = av_rescale_q(frame->pts, frame->time_base, ifp->time_base);
3374 frame->duration = av_rescale_q(frame->duration, frame->time_base, ifp->time_base);
3375 frame->time_base = ifp->time_base;
3376
3377 if (ifp->displaymatrix_applied)
3379
3380 fd = frame_data(frame);
3381 if (!fd)
3382 return AVERROR(ENOMEM);
3384
3387 if (ret < 0) {
3389 if (ret != AVERROR_EOF)
3390 av_log(fg, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret));
3391 return ret;
3392 }
3393
3394 return 0;
3395}
3396
3397static void fg_thread_set_name(const FilterGraph *fg)
3398{
3399 char name[16];
3400 if (filtergraph_is_simple(fg)) {
3402 snprintf(name, sizeof(name), "%cf%s",
3404 ofp->ofilter.output_name);
3405 } else {
3406 snprintf(name, sizeof(name), "fc%d", fg->index);
3407 }
3408
3410}
3411
3413{
3414 if (fgt->frame_queue_out) {
3415 AVFrame *frame;
3416 while (av_fifo_read(fgt->frame_queue_out, &frame, 1) >= 0)
3419 }
3420
3421 av_frame_free(&fgt->frame);
3422 av_freep(&fgt->eof_in);
3423 av_freep(&fgt->eof_out);
3424
3426
3427 memset(fgt, 0, sizeof(*fgt));
3428}
3429
3431{
3432 memset(fgt, 0, sizeof(*fgt));
3433
3434 fgt->frame = av_frame_alloc();
3435 if (!fgt->frame)
3436 goto fail;
3437
3438 fgt->eof_in = av_calloc(fg->nb_inputs, sizeof(*fgt->eof_in));
3439 if (!fgt->eof_in)
3440 goto fail;
3441
3442 fgt->eof_out = av_calloc(fg->nb_outputs, sizeof(*fgt->eof_out));
3443 if (!fgt->eof_out)
3444 goto fail;
3445
3447 if (!fgt->frame_queue_out)
3448 goto fail;
3449
3450 return 0;
3451
3452fail:
3453 fg_thread_uninit(fgt);
3454 return AVERROR(ENOMEM);
3455}
3456
3458{
3459 int ret, reinit = 0;
3460
3461 for (unsigned i = 0; i < fg->nb_outputs; i++) {
3463
3464 if (ofp->reinit_opts.pts == AV_NOPTS_VALUE && ofp->reinit_opts_fifo &&
3467 }
3468 if (ofp->reinit_opts.pts != AV_NOPTS_VALUE &&
3470 FrameData *fd = frame_data(fgt->frame);
3471 if (!fd)
3472 return AVERROR(ENOMEM);
3473
3475 ret = av_dict_copy(&fd->reinit_opts, ofp->reinit_opts.dict, 0);
3476 if (ret < 0)
3477 return ret;
3478
3479 av_opt_set_dict(ofp, &ofp->reinit_opts.dict);
3481
3484 else
3485 ofp->reinit_opts = (ReinitOpts){ .pts = AV_NOPTS_VALUE };
3486 reinit = 1;
3487 }
3488 }
3489
3490 return reinit;
3491}
3492
3493static int filter_thread(void *arg)
3494{
3495 FilterGraphPriv *fgp = arg;
3496 FilterGraph *fg = &fgp->fg;
3497
3499 int ret = 0, input_status = 0;
3500
3501 ret = fg_thread_init(&fgt, fg);
3502 if (ret < 0)
3503 goto finish;
3504
3506
3507 // if we have all input parameters the graph can now be configured
3509 ret = configure_filtergraph(fg, &fgt);
3510 if (ret < 0) {
3511 av_log(fg, AV_LOG_ERROR, "Error configuring filter graph: %s\n",
3512 av_err2str(ret));
3513 goto finish;
3514 }
3515 }
3516
3517 while (1) {
3518 InputFilter *ifilter;
3519 InputFilterPriv *ifp = NULL;
3520 enum FrameOpaque o;
3521 unsigned input_idx = fgt.next_in;
3522
3523 input_status = sch_filter_receive(fgp->sch, fgp->sch_idx,
3524 &input_idx, fgt.frame);
3525 if (input_status == AVERROR_EOF) {
3526 av_log(fg, AV_LOG_VERBOSE, "Filtering thread received EOF\n");
3527 break;
3528 } else if (input_status == AVERROR(EAGAIN)) {
3529 // should only happen when we didn't request any input
3530 av_assert0(input_idx == fg->nb_inputs);
3531 goto read_frames;
3532 }
3533 av_assert0(input_status >= 0);
3534
3535 o = (intptr_t)fgt.frame->opaque;
3536
3537 // message on the control stream
3538 if (input_idx == fg->nb_inputs) {
3540
3542
3543 fc = (FilterCommand*)fgt.frame->buf[0]->data;
3544 send_command(fg, fgt.graph, fc->time, fc->target, fc->command, fc->arg,
3545 fc->all_filters);
3546 av_frame_unref(fgt.frame);
3547 continue;
3548 }
3549
3550 // we received an input frame or EOF
3551 ifilter = fg->inputs[input_idx];
3552 ifp = ifp_from_ifilter(ifilter);
3553
3554 if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
3555 int hb_frame = input_status >= 0 && o == FRAME_OPAQUE_SUB_HEARTBEAT;
3556 ret = sub2video_frame(ifilter, (fgt.frame->buf[0] || hb_frame) ? fgt.frame : NULL,
3557 !fgt.graph);
3558 } else if (fgt.frame->buf[0]) {
3559 ret = check_reinit(fg, &fgt);
3560 if (ret >= 0)
3561 ret = send_frame(fg, &fgt, ifilter, fgt.frame, ret);
3562 } else {
3564 ret = send_eof(&fgt, ifilter, fgt.frame->pts, fgt.frame->time_base);
3565 }
3566 av_frame_unref(fgt.frame);
3567 if (ret == AVERROR_EOF) {
3568 av_log(fg, AV_LOG_VERBOSE, "Input %u no longer accepts new data\n",
3569 input_idx);
3570 close_input(ifp);
3571 continue;
3572 }
3573 if (ret < 0)
3574 goto finish;
3575
3577 // retrieve all newly available frames
3578 ret = read_frames(fg, &fgt, fgt.frame);
3579 if (ret == AVERROR_EOF) {
3580 av_log(fg, AV_LOG_VERBOSE, "All consumers returned EOF\n");
3581 if (ifp && ifp->opts.flags & IFILTER_FLAG_DROPCHANGED)
3582 av_log(fg, AV_LOG_INFO, "Total changed input frames dropped : %"PRId64"\n", ifp->nb_dropped);
3583 break;
3584 } else if (ret < 0) {
3585 av_log(fg, AV_LOG_ERROR, "Error sending frames to consumers: %s\n",
3586 av_err2str(ret));
3587 goto finish;
3588 }
3589
3590 // ensure all inputs no longer accepting data are closed
3591 for (int i = 0; fgt.graph && i < fg->nb_inputs; i++) {
3594 close_input(ifp);
3595 }
3596 }
3597
3598 for (unsigned i = 0; i < fg->nb_outputs; i++) {
3600
3601 if (fgt.eof_out[i] || !fgt.graph)
3602 continue;
3603
3604 ret = fg_output_frame(ofp, &fgt, NULL);
3605 if (ret < 0)
3606 goto finish;
3607 }
3608
3609finish:
3610
3612 print_filtergraph(fg, fgt.graph);
3613
3614 // EOF is normal termination
3615 if (ret == AVERROR_EOF)
3616 ret = 0;
3617
3618 fg_thread_uninit(&fgt);
3619
3620 return ret;
3621}
3622
3623void fg_send_command(FilterGraph *fg, double time, const char *target,
3624 const char *command, const char *arg, int all_filters)
3625{
3626 FilterGraphPriv *fgp = fgp_from_fg(fg);
3627 AVBufferRef *buf;
3629
3630 fc = av_mallocz(sizeof(*fc));
3631 if (!fc)
3632 return;
3633
3634 buf = av_buffer_create((uint8_t*)fc, sizeof(*fc), filter_command_free, NULL, 0);
3635 if (!buf) {
3636 av_freep(&fc);
3637 return;
3638 }
3639
3640 fc->target = av_strdup(target);
3641 fc->command = av_strdup(command);
3642 fc->arg = av_strdup(arg);
3643 if (!fc->target || !fc->command || !fc->arg) {
3644 av_buffer_unref(&buf);
3645 return;
3646 }
3647
3648 fc->time = time;
3649 fc->all_filters = all_filters;
3650
3651 fgp->frame->buf[0] = buf;
3652 fgp->frame->opaque = (void*)(intptr_t)FRAME_OPAQUE_SEND_COMMAND;
3653
3654 sch_filter_command(fgp->sch, fgp->sch_idx, fgp->frame);
3655}
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:630
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:620
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:1541
char * read_file_to_string(const char *filename)
Definition cmdutils.c:1572
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:1554
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)
#define NEEDED_EXPLICIT
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)
#define NEEDED_INTERNAL
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:359
char * path
Definition ffplay.c:385
int ret
Definition ffplay.c:391
static int64_t start_time
Definition ffplay.c:358
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:2060
@ 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:968
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:1001
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:996
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:927
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:236
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition dict.c:43
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:286
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition dict.c:250
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:87
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:213
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
Definition dict.c:38
#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:499
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition frame.c:662
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:728
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:209
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
Definition frame.c:526
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:281
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:65
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:53
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:2075
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
Definition opt.c:1762
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
Definition opt.c:942
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition opt.c:895
int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int search_flags)
Definition opt.c:957
int av_opt_set_dict(void *obj, AVDictionary **options)
Set all the options from a given dictionary on an object.
Definition opt.c:2070
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:1455
uint32_t type
Definition jpegmpfenc.c:80
const char * arg
Definition jacosubdec.c:66
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:456
@ 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:1401
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:2106
uint32_t end_display_time
Definition avcodec.h:2107
unsigned num_rects
Definition avcodec.h:2108
AVSubtitleRect ** rects
Definition avcodec.h:2109
int64_t pts
Same as packet pts, in AV_TIME_BASE.
Definition avcodec.h:2110
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:33
#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]