Commit 57cce83d49 for ffmpeg
commit 57cce83d4938906f4b7c50ba24d9721e3b5c3c1a
Author: Niklas Haas <git@haasn.dev>
Date: Thu Oct 29 13:26:56 2026 +0100
avfilter: add avfilter_graph_set_max_buffered_frames()
This is a new API that offers two improvements over the existing field:
1. It allows setting a different limit per media type
2. It allows updating the limit after the graph has been configured, as
long as this would not cause already existing frames to exceed the limit
I'm not sure if the second point is ever useful, but it's easy to implement
regardless.
Because the old field will be deprecated, the new API just overrides the old
value wholesale. The alternative was to respect both (i.e. use the smaller
of the two limits); but this way, callers can use the new API to e.g.
selectively uncap the limit on audio frames while remaining backwards
compatible with older libavfilter.
Explicitly set limits are tracked separately, so that avfilter_graph_config()
re-derives all other limits from the old field on every call.
Signed-off-by: Niklas Haas <git@haasn.dev>
diff --git a/doc/APIchanges b/doc/APIchanges
index 8ce9c22d68..031025e979 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,9 @@ The last version increases of all libraries were on 2026-06-23.
API changes, most recent first:
+2026-10-xx - xxxxxxxxxx - lavfi 12.11.100 - avfilter.h
+ Add avfilter_graph_set_max_buffered_frames().
+
2026-10-xx - d19f86ff4c4 - lavf 63.14.102 - avformat.h
After avformat_seek_file(), the first packet of an audio stream carries
AV_PKT_DATA_SKIP_SAMPLES for the larger of the rest of the priming and the
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index e9a6ea8775..23977679fe 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -703,6 +703,23 @@ enum {
AVFILTER_AUTO_CONVERT_NONE = -1, /**< all automatic conversions disabled */
};
+/**
+ * Set the maximum number of combined buffered frames of a given media type in
+ * the filtergraph. When set, this overrides the value inherited from
+ * AVFilterGraph.max_buffered_frames for that media type.
+ *
+ * @param graph the filter graph
+ * @param type the media type to set the limit for
+ * @param frames the maximum number of buffered frames, or zero to disable
+ * @return >= 0 in case of success, or a negative error
+ *
+ * @note This will return AVERROR(EINVAL) if the requested limit is lower
+ * than the number of frames already buffered.
+ */
+int avfilter_graph_set_max_buffered_frames(AVFilterGraph *graph,
+ enum AVMediaType type,
+ unsigned frames);
+
/**
* Check validity and configure all the links and formats in the graph.
*
diff --git a/libavfilter/avfilter_internal.h b/libavfilter/avfilter_internal.h
index 42940dcb45..73fa13e0d1 100644
--- a/libavfilter/avfilter_internal.h
+++ b/libavfilter/avfilter_internal.h
@@ -155,6 +155,8 @@ typedef struct FFFilterGraph {
void *thread;
avfilter_execute_func *thread_execute;
FFFrameQueueGlobal frame_queues[AVMEDIA_TYPE_NB];
+ /* set by avfilter_graph_set_max_buffered_frames() */
+ uint8_t max_queued_set[AVMEDIA_TYPE_NB];
} FFFilterGraph;
static inline FFFilterGraph *fffiltergraph(AVFilterGraph *graph)
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 9729ef5fba..304589e50b 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -165,6 +165,23 @@ void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
fffiltergraph(graph)->disable_auto_convert = flags;
}
+int avfilter_graph_set_max_buffered_frames(AVFilterGraph *graph,
+ enum AVMediaType type,
+ unsigned frames)
+{
+ FFFilterGraph *graphi = fffiltergraph(graph);
+ if (type < 0 || type >= FF_ARRAY_ELEMS(graphi->frame_queues))
+ return AVERROR(EINVAL);
+
+ FFFrameQueueGlobal *fqg = &graphi->frame_queues[type];
+ size_t max_queued = frames ? frames : SIZE_MAX;
+ if (fqg->queued > max_queued)
+ return AVERROR(EINVAL);
+ fqg->max_queued = max_queued;
+ graphi->max_queued_set[type] = 1;
+ return 0;
+}
+
AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph,
const AVFilter *filter,
const char *name)
@@ -1461,9 +1478,14 @@ int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
FFFilterGraph *graphi = fffiltergraph(graphctx);
int ret;
+ size_t max_queued = graphctx->max_buffered_frames;
+ if (!max_queued)
+ max_queued = SIZE_MAX;
+
for (int i = 0; i < FF_ARRAY_ELEMS(graphi->frame_queues); i++) {
- const size_t max_queued = graphctx->max_buffered_frames;
- if (max_queued)
+ /* only infer the value from graphctx->max_buffered_frames if it was
+ * not already set by avfilter_graph_set_max_buffered_frames() */
+ if (!graphi->max_queued_set[i])
graphi->frame_queues[i].max_queued = max_queued;
}
if ((ret = graph_check_validity(graphctx, log_ctx)))
diff --git a/libavfilter/version.h b/libavfilter/version.h
index 4a69d6be98..8f4a7a9cd3 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -31,7 +31,7 @@
#include "version_major.h"
-#define LIBAVFILTER_VERSION_MINOR 10
+#define LIBAVFILTER_VERSION_MINOR 11
#define LIBAVFILTER_VERSION_MICRO 100