mirror of https://git.ffmpeg.org/ffmpeg.git
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).
This commit is contained in:
parent
9d3cdf8fa6
commit
1efcdbc54d
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include "version_major.h"
|
||||
|
||||
#define LIBAVFILTER_VERSION_MINOR 5
|
||||
#define LIBAVFILTER_VERSION_MINOR 6
|
||||
#define LIBAVFILTER_VERSION_MICRO 100
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue