aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2024-09-25 17:34:13 +0200
committerAnton Khirnov <anton@khirnov.net>2024-09-30 09:10:19 +0200
commit1efcdbc54d9659351c01faed59fec666ed1df3c9 (patch)
treecc86020c17835e75094f790d8f7fa53c29b8b63b
parent9d3cdf8fa602bc092c6a9168416d2c7ffbd1adf6 (diff)
downloadffmpeg-1efcdbc54d9659351c01faed59fec666ed1df3c9.tar.gz
lavfi/buffersink: add array-type options to replace "int-list" ones
"int-list" options are a hack that provides rudimentary support for array-type options by treating them as byte arrays (i.e. AV_OPT_TYPE_BINARY). Since we now have proper array-type options, they should replace "int-list" everywhere (which happens to be just buffersink).
-rw-r--r--doc/APIchanges18
-rw-r--r--libavfilter/buffersink.c162
-rw-r--r--libavfilter/buffersink.h21
-rw-r--r--libavfilter/version.h2
-rw-r--r--libavfilter/version_major.h1
5 files changed, 175 insertions, 29 deletions
diff --git a/doc/APIchanges b/doc/APIchanges
index ddd4e6c9e0..a79353f79b 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,24 @@ The last version increases of all libraries were on 2024-03-07
API changes, most recent first:
+2024-09-xx - xxxxxxxxxx - lavfi 10.6.100
+ Buffersink now has array-type options
+ - pixel_formats
+ - colorspaces
+ - colorranges
+ replacing the int-list options
+ - pix_fmts
+ - color_spaces
+ - color_ranges
+ abuffersink now has array-type options
+ - sample_formats
+ - samplerates
+ - channel_layouts
+ replacing the int-list/string options
+ - sample_fmts
+ - sample_rates
+ - ch_layouts
+
-------- 8< --------- FFmpeg 7.1 was cut here -------- 8< ---------
2024-09-23 - 6940a6de2f0 - lavu 59.38.100 - frame.h
diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c
index af4dc38792..0cfac2abd5 100644
--- a/libavfilter/buffersink.c
+++ b/libavfilter/buffersink.c
@@ -28,6 +28,7 @@
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/internal.h"
+#include "libavutil/mem.h"
#include "libavutil/opt.h"
#include "audio.h"
@@ -45,26 +46,46 @@ typedef struct BufferSinkContext {
unsigned frame_size;
/* only used for video */
+#if FF_API_BUFFERSINK_OPTS
enum AVPixelFormat *pixel_fmts; ///< list of accepted pixel formats
int pixel_fmts_size;
enum AVColorSpace *color_spaces; ///< list of accepted color spaces
int color_spaces_size;
enum AVColorRange *color_ranges; ///< list of accepted color ranges
int color_ranges_size;
+#endif
+
+ enum AVPixelFormat *pixel_formats;
+ unsigned nb_pixel_formats;
+
+ int *colorspaces;
+ unsigned nb_colorspaces;
+
+ int *colorranges;
+ unsigned nb_colorranges;
/* only used for audio */
+#if FF_API_BUFFERSINK_OPTS
enum AVSampleFormat *sample_fmts; ///< list of accepted sample formats
int sample_fmts_size;
char *channel_layouts_str; ///< list of accepted channel layouts
int all_channel_counts;
int *sample_rates; ///< list of accepted sample rates
int sample_rates_size;
+#endif
+
+ enum AVSampleFormat *sample_formats;
+ unsigned nb_sample_formats;
+
+ int *samplerates;
+ unsigned nb_samplerates;
+
+ AVChannelLayout *channel_layouts;
+ unsigned nb_channel_layouts;
AVFrame *peeked_frame;
} BufferSinkContext;
-#define NB_ITEMS(list) (list ## _size / sizeof(*list))
-
int attribute_align_arg av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame)
{
return av_buffersink_get_frame_flags(ctx, frame, 0);
@@ -138,6 +159,39 @@ static av_cold int common_init(AVFilterContext *ctx)
return 0;
}
+#define TERMINATE_ARRAY(arr, val) \
+ if (s->arr) { \
+ void *tmp = av_realloc_array(s->arr, s->nb_ ## arr + 1, sizeof(*s->arr)); \
+ if (!tmp) \
+ return AVERROR(ENOMEM); \
+ s->arr = tmp; \
+ s->arr[s->nb_ ## arr] = val; \
+ }
+
+static int init_video(AVFilterContext *ctx)
+{
+ BufferSinkContext *s = ctx->priv;
+
+ TERMINATE_ARRAY(pixel_formats, AV_PIX_FMT_NONE);
+ TERMINATE_ARRAY(colorranges, -1);
+ TERMINATE_ARRAY(colorspaces, -1);
+
+ return common_init(ctx);
+}
+
+static int init_audio(AVFilterContext *ctx)
+{
+ BufferSinkContext *s = ctx->priv;
+
+ TERMINATE_ARRAY(sample_formats, AV_SAMPLE_FMT_NONE);
+ TERMINATE_ARRAY(samplerates, -1);
+ TERMINATE_ARRAY(channel_layouts, (AVChannelLayout){ .nb_channels = 0 });
+
+ return common_init(ctx);
+}
+
+#undef TERMINATE_ARRAY
+
static void uninit(AVFilterContext *ctx)
{
BufferSinkContext *buf = ctx->priv;
@@ -235,6 +289,9 @@ int av_buffersink_get_ch_layout(const AVFilterContext *ctx, AVChannelLayout *out
return 0;
}
+#if FF_API_BUFFERSINK_OPTS
+#define NB_ITEMS(list) (list ## _size / sizeof(*list))
+
#define CHECK_LIST_SIZE(field) \
if (buf->field ## _size % sizeof(*buf->field)) { \
av_log(ctx, AV_LOG_ERROR, "Invalid size for " #field ": %d, " \
@@ -242,12 +299,40 @@ int av_buffersink_get_ch_layout(const AVFilterContext *ctx, AVChannelLayout *out
buf->field ## _size, (int)sizeof(*buf->field)); \
return AVERROR(EINVAL); \
}
+#endif
+
static int vsink_query_formats(AVFilterContext *ctx)
{
BufferSinkContext *buf = ctx->priv;
- unsigned i;
int ret;
+#if FF_API_BUFFERSINK_OPTS
+ if ((buf->pixel_fmts_size || buf->color_spaces_size || buf->color_ranges_size) &&
+ (buf->nb_pixel_formats || buf->nb_colorspaces || buf->nb_colorranges)) {
+ av_log(ctx, AV_LOG_ERROR, "Cannot combine old and new format lists\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (buf->nb_pixel_formats || buf->nb_colorspaces || buf->nb_colorranges) {
+#endif
+ if (buf->nb_pixel_formats) {
+ ret = ff_set_common_formats_from_list(ctx, buf->pixel_formats);
+ if (ret < 0)
+ return ret;
+ }
+ if (buf->nb_colorspaces) {
+ ret = ff_set_common_color_spaces_from_list(ctx, buf->colorspaces);
+ if (ret < 0)
+ return ret;
+ }
+ if (buf->nb_colorranges) {
+ ret = ff_set_common_color_ranges_from_list(ctx, buf->colorranges);
+ if (ret < 0)
+ return ret;
+ }
+#if FF_API_BUFFERSINK_OPTS
+ } else {
+ unsigned i;
CHECK_LIST_SIZE(pixel_fmts)
CHECK_LIST_SIZE(color_spaces)
CHECK_LIST_SIZE(color_ranges)
@@ -277,6 +362,8 @@ static int vsink_query_formats(AVFilterContext *ctx)
if ((ret = ff_set_common_color_ranges(ctx, formats)) < 0)
return ret;
}
+ }
+#endif
return 0;
}
@@ -284,12 +371,38 @@ static int vsink_query_formats(AVFilterContext *ctx)
static int asink_query_formats(AVFilterContext *ctx)
{
BufferSinkContext *buf = ctx->priv;
+ int ret;
+
+#if FF_API_BUFFERSINK_OPTS
+ if ((buf->sample_fmts_size || buf->channel_layouts_str || buf->sample_rates_size) &&
+ (buf->nb_sample_formats || buf->nb_samplerates || buf->nb_channel_layouts)) {
+ av_log(ctx, AV_LOG_ERROR, "Cannot combine old and new format lists\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (buf->nb_sample_formats || buf->nb_samplerates || buf->nb_channel_layouts) {
+#endif
+ if (buf->nb_sample_formats) {
+ ret = ff_set_common_formats_from_list(ctx, buf->sample_formats);
+ if (ret < 0)
+ return ret;
+ }
+ if (buf->nb_samplerates) {
+ ret = ff_set_common_samplerates_from_list(ctx, buf->samplerates);
+ if (ret < 0)
+ return ret;
+ }
+ if (buf->nb_channel_layouts) {
+ ret = ff_set_common_channel_layouts_from_list(ctx, buf->channel_layouts);
+ if (ret < 0)
+ return ret;
+ }
+#if FF_API_BUFFERSINK_OPTS
+ } else {
AVFilterFormats *formats = NULL;
AVChannelLayout layout = { 0 };
AVFilterChannelLayouts *layouts = NULL;
unsigned i;
- int ret;
-
CHECK_LIST_SIZE(sample_fmts)
CHECK_LIST_SIZE(sample_rates)
@@ -343,6 +456,8 @@ static int asink_query_formats(AVFilterContext *ctx)
if ((ret = ff_set_common_samplerates(ctx, formats)) < 0)
return ret;
}
+ }
+#endif
return 0;
}
@@ -350,19 +465,38 @@ static int asink_query_formats(AVFilterContext *ctx)
#define OFFSET(x) offsetof(BufferSinkContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
static const AVOption buffersink_options[] = {
- { "pix_fmts", "set the supported pixel formats", OFFSET(pixel_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS },
- { "color_spaces", "set the supported color spaces", OFFSET(color_spaces), AV_OPT_TYPE_BINARY, .flags = FLAGS },
- { "color_ranges", "set the supported color ranges", OFFSET(color_ranges), AV_OPT_TYPE_BINARY, .flags = FLAGS },
+#if FF_API_BUFFERSINK_OPTS
+ { "pix_fmts", "set the supported pixel formats", OFFSET(pixel_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS | AV_OPT_FLAG_DEPRECATED },
+ { "color_spaces", "set the supported color spaces", OFFSET(color_spaces), AV_OPT_TYPE_BINARY, .flags = FLAGS | AV_OPT_FLAG_DEPRECATED },
+ { "color_ranges", "set the supported color ranges", OFFSET(color_ranges), AV_OPT_TYPE_BINARY, .flags = FLAGS | AV_OPT_FLAG_DEPRECATED },
+#endif
+
+ { "pixel_formats", "array of supported pixel formats", OFFSET(pixel_formats),
+ AV_OPT_TYPE_PIXEL_FMT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
+ { "colorspaces", "array of supported color spaces", OFFSET(colorspaces),
+ AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
+ { "colorranges", "array of supported color ranges", OFFSET(colorranges),
+ AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
+
{ NULL },
};
#undef FLAGS
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM
static const AVOption abuffersink_options[] = {
- { "sample_fmts", "set the supported sample formats", OFFSET(sample_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS },
- { "sample_rates", "set the supported sample rates", OFFSET(sample_rates), AV_OPT_TYPE_BINARY, .flags = FLAGS },
+#if FF_API_BUFFERSINK_OPTS
+ { "sample_fmts", "set the supported sample formats", OFFSET(sample_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS | AV_OPT_FLAG_DEPRECATED },
+ { "sample_rates", "set the supported sample rates", OFFSET(sample_rates), AV_OPT_TYPE_BINARY, .flags = FLAGS | AV_OPT_FLAG_DEPRECATED },
{ "ch_layouts", "set a '|'-separated list of supported channel layouts",
- OFFSET(channel_layouts_str), AV_OPT_TYPE_STRING, .flags = FLAGS },
- { "all_channel_counts", "accept all channel counts", OFFSET(all_channel_counts), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS },
+ OFFSET(channel_layouts_str), AV_OPT_TYPE_STRING, .flags = FLAGS | AV_OPT_FLAG_DEPRECATED },
+ { "all_channel_counts", "accept all channel counts", OFFSET(all_channel_counts), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS | AV_OPT_FLAG_DEPRECATED },
+#endif
+
+ { "sample_formats", "array of supported sample formats", OFFSET(sample_formats),
+ AV_OPT_TYPE_SAMPLE_FMT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
+ { "samplerates", "array of supported sample formats", OFFSET(samplerates),
+ AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
+ { "channel_layouts", "array of supported channel layouts", OFFSET(channel_layouts),
+ AV_OPT_TYPE_CHLAYOUT | AV_OPT_TYPE_FLAG_ARRAY, .flags = FLAGS },
{ NULL },
};
#undef FLAGS
@@ -375,7 +509,7 @@ const AVFilter ff_vsink_buffer = {
.description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
.priv_size = sizeof(BufferSinkContext),
.priv_class = &buffersink_class,
- .init = common_init,
+ .init = init_video,
.uninit = uninit,
.activate = activate,
FILTER_INPUTS(ff_video_default_filterpad),
@@ -396,7 +530,7 @@ const AVFilter ff_asink_abuffer = {
.description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
.priv_class = &abuffersink_class,
.priv_size = sizeof(BufferSinkContext),
- .init = common_init,
+ .init = init_audio,
.uninit = uninit,
.activate = activate,
FILTER_INPUTS(inputs_audio),
diff --git a/libavfilter/buffersink.h b/libavfilter/buffersink.h
index 361d603679..08cb6b3804 100644
--- a/libavfilter/buffersink.h
+++ b/libavfilter/buffersink.h
@@ -54,20 +54,13 @@
*
* The format can be constrained by setting options, using av_opt_set() and
* related functions with the AV_OPT_SEARCH_CHILDREN flag.
- * - pix_fmts (int list),
- * - color_spaces (int list),
- * - color_ranges (int list),
- * - sample_fmts (int list),
- * - sample_rates (int list),
- * - ch_layouts (string),
- * - channel_counts (int list),
- * - all_channel_counts (bool).
- * Most of these options are of type binary, and should be set using
- * av_opt_set_int_list() or av_opt_set_bin(). If they are not set, all
- * corresponding formats are accepted.
- *
- * As a special case, if ch_layouts is not set, all valid channel layouts are
- * accepted except for UNSPEC layouts, unless all_channel_counts is set.
+ * - pixel_formats (array of pixel formats),
+ * - colorspaces (array of int),
+ * - colorranges (array of int),
+ * - sample_formats (array of sample formats),
+ * - samplerates (array of int),
+ * - channel_layouts (array of channel layouts)
+ * If an option is not set, all corresponding formats are accepted.
*/
/**
diff --git a/libavfilter/version.h b/libavfilter/version.h
index 523a7fe0a6..f191d98883 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -31,7 +31,7 @@
#include "version_major.h"
-#define LIBAVFILTER_VERSION_MINOR 5
+#define LIBAVFILTER_VERSION_MINOR 6
#define LIBAVFILTER_VERSION_MICRO 100
diff --git a/libavfilter/version_major.h b/libavfilter/version_major.h
index c5e660eeda..b2c761370f 100644
--- a/libavfilter/version_major.h
+++ b/libavfilter/version_major.h
@@ -36,5 +36,6 @@
*/
#define FF_API_LINK_PUBLIC (LIBAVFILTER_VERSION_MAJOR < 11)
+#define FF_API_BUFFERSINK_OPTS (LIBAVFILTER_VERSION_MAJOR < 11)
#endif /* AVFILTER_VERSION_MAJOR_H */