History

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).

Anton Khirnov committed 2 years ago

Commit 1efcdbc1 parent 9d3cdf85 files · +175 −29Browse files

Unified · Split

5 files
  1. doc/APIchanges +18 −0
  2. libavfilter/buffersink.c +148 −14
  3. libavfilter/buffersink.h +7 −14
  4. libavfilter/version.h +1 −1
  5. libavfilter/version_major.h +1 −0
doc/APIchanges+18−0
@@ -2,6 +2,24 @@ The last version increases of all libraries were on 2024-03-07 · 1 unmodified line
22
33 API changes, most recent first:
44
5+2024-09-xx - xxxxxxxxxx - lavfi 10.6.100
6+ Buffersink now has array-type options
7+ - pixel_formats
8+ - colorspaces
9+ - colorranges
10+ replacing the int-list options
11+ - pix_fmts
12+ - color_spaces
13+ - color_ranges
14+ abuffersink now has array-type options
15+ - sample_formats
16+ - samplerates
17+ - channel_layouts
18+ replacing the int-list/string options
19+ - sample_fmts
20+ - sample_rates
21+ - ch_layouts
22+
523 -------- 8< --------- FFmpeg 7.1 was cut here -------- 8< ---------
624
725 2024-09-23 - 6940a6de2f0 - lavu 59.38.100 - frame.h
libavfilter/buffersink.c+148−14
@@ -28,6 +28,7 @@ · 27 unmodified lines
2828 #include "libavutil/channel_layout.h"
2929 #include "libavutil/common.h"
3030 #include "libavutil/internal.h"
31+#include "libavutil/mem.h"
3132 #include "libavutil/opt.h"
3233
3334 #include "audio.h"
@@ -45,26 +46,46 @@ typedef struct BufferSinkContext { · 11 unmodified lines
4546 unsigned frame_size;
4647
4748 /* only used for video */
49+#if FF_API_BUFFERSINK_OPTS
4850 enum AVPixelFormat *pixel_fmts; ///< list of accepted pixel formats
4951 int pixel_fmts_size;
5052 enum AVColorSpace *color_spaces; ///< list of accepted color spaces
5153 int color_spaces_size;
5254 enum AVColorRange *color_ranges; ///< list of accepted color ranges
5355 int color_ranges_size;
56+#endif
57+
58+ enum AVPixelFormat *pixel_formats;
59+ unsigned nb_pixel_formats;
60+
61+ int *colorspaces;
62+ unsigned nb_colorspaces;
63+
64+ int *colorranges;
65+ unsigned nb_colorranges;
5466
5567 /* only used for audio */
68+#if FF_API_BUFFERSINK_OPTS
5669 enum AVSampleFormat *sample_fmts; ///< list of accepted sample formats
5770 int sample_fmts_size;
5871 char *channel_layouts_str; ///< list of accepted channel layouts
5972 int all_channel_counts;
6073 int *sample_rates; ///< list of accepted sample rates
6174 int sample_rates_size;
75+#endif
76+
77+ enum AVSampleFormat *sample_formats;
78+ unsigned nb_sample_formats;
79+
80+ int *samplerates;
81+ unsigned nb_samplerates;
82+
83+ AVChannelLayout *channel_layouts;
84+ unsigned nb_channel_layouts;
6285
6386 AVFrame *peeked_frame;
6487 } BufferSinkContext;
6588
66−#define NB_ITEMS(list) (list ## _size / sizeof(*list))
67−
6889 int attribute_align_arg av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame)
6990 {
7091 return av_buffersink_get_frame_flags(ctx, frame, 0);
@@ -138,6 +159,39 @@ static av_cold int common_init(AVFilterContext *ctx) · 67 unmodified lines
138159 return 0;
139160 }
140161
162+#define TERMINATE_ARRAY(arr, val) \
163+ if (s->arr) { \
164+ void *tmp = av_realloc_array(s->arr, s->nb_ ## arr + 1, sizeof(*s->arr)); \
165+ if (!tmp) \
166+ return AVERROR(ENOMEM); \
167+ s->arr = tmp; \
168+ s->arr[s->nb_ ## arr] = val; \
169+ }
170+
171+static int init_video(AVFilterContext *ctx)
172+{
173+ BufferSinkContext *s = ctx->priv;
174+
175+ TERMINATE_ARRAY(pixel_formats, AV_PIX_FMT_NONE);
176+ TERMINATE_ARRAY(colorranges, -1);
177+ TERMINATE_ARRAY(colorspaces, -1);
178+
179+ return common_init(ctx);
180+}
181+
182+static int init_audio(AVFilterContext *ctx)
183+{
184+ BufferSinkContext *s = ctx->priv;
185+
186+ TERMINATE_ARRAY(sample_formats, AV_SAMPLE_FMT_NONE);
187+ TERMINATE_ARRAY(samplerates, -1);
188+ TERMINATE_ARRAY(channel_layouts, (AVChannelLayout){ .nb_channels = 0 });
189+
190+ return common_init(ctx);
191+}
192+
193+#undef TERMINATE_ARRAY
194+
141195 static void uninit(AVFilterContext *ctx)
142196 {
143197 BufferSinkContext *buf = ctx->priv;
@@ -235,6 +289,9 @@ int av_buffersink_get_ch_layout(const AVFilterContext *ctx, AVChannelLayout *out · 91 unmodified lines
235289 return 0;
236290 }
237291
292+#if FF_API_BUFFERSINK_OPTS
293+#define NB_ITEMS(list) (list ## _size / sizeof(*list))
294+
238295 #define CHECK_LIST_SIZE(field) \
239296 if (buf->field ## _size % sizeof(*buf->field)) { \
240297 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 · 1 unmodified line
242299 buf->field ## _size, (int)sizeof(*buf->field)); \
243300 return AVERROR(EINVAL); \
244301 }
302+#endif
303+
245304 static int vsink_query_formats(AVFilterContext *ctx)
246305 {
247306 BufferSinkContext *buf = ctx->priv;
248− unsigned i;
249307 int ret;
250308
309+#if FF_API_BUFFERSINK_OPTS
310+ if ((buf->pixel_fmts_size || buf->color_spaces_size || buf->color_ranges_size) &&
311+ (buf->nb_pixel_formats || buf->nb_colorspaces || buf->nb_colorranges)) {
312+ av_log(ctx, AV_LOG_ERROR, "Cannot combine old and new format lists\n");
313+ return AVERROR(EINVAL);
314+ }
315+
316+ if (buf->nb_pixel_formats || buf->nb_colorspaces || buf->nb_colorranges) {
317+#endif
318+ if (buf->nb_pixel_formats) {
319+ ret = ff_set_common_formats_from_list(ctx, buf->pixel_formats);
320+ if (ret < 0)
321+ return ret;
322+ }
323+ if (buf->nb_colorspaces) {
324+ ret = ff_set_common_color_spaces_from_list(ctx, buf->colorspaces);
325+ if (ret < 0)
326+ return ret;
327+ }
328+ if (buf->nb_colorranges) {
329+ ret = ff_set_common_color_ranges_from_list(ctx, buf->colorranges);
330+ if (ret < 0)
331+ return ret;
332+ }
333+#if FF_API_BUFFERSINK_OPTS
334+ } else {
335+ unsigned i;
251336 CHECK_LIST_SIZE(pixel_fmts)
252337 CHECK_LIST_SIZE(color_spaces)
253338 CHECK_LIST_SIZE(color_ranges)
@@ -277,6 +362,8 @@ static int vsink_query_formats(AVFilterContext *ctx) · 23 unmodified lines
277362 if ((ret = ff_set_common_color_ranges(ctx, formats)) < 0)
278363 return ret;
279364 }
365+ }
366+#endif
280367
281368 return 0;
282369 }
@@ -284,12 +371,38 @@ static int vsink_query_formats(AVFilterContext *ctx) · 1 unmodified line
284371 static int asink_query_formats(AVFilterContext *ctx)
285372 {
286373 BufferSinkContext *buf = ctx->priv;
374+ int ret;
375+
376+#if FF_API_BUFFERSINK_OPTS
377+ if ((buf->sample_fmts_size || buf->channel_layouts_str || buf->sample_rates_size) &&
378+ (buf->nb_sample_formats || buf->nb_samplerates || buf->nb_channel_layouts)) {
379+ av_log(ctx, AV_LOG_ERROR, "Cannot combine old and new format lists\n");
380+ return AVERROR(EINVAL);
381+ }
382+
383+ if (buf->nb_sample_formats || buf->nb_samplerates || buf->nb_channel_layouts) {
384+#endif
385+ if (buf->nb_sample_formats) {
386+ ret = ff_set_common_formats_from_list(ctx, buf->sample_formats);
387+ if (ret < 0)
388+ return ret;
389+ }
390+ if (buf->nb_samplerates) {
391+ ret = ff_set_common_samplerates_from_list(ctx, buf->samplerates);
392+ if (ret < 0)
393+ return ret;
394+ }
395+ if (buf->nb_channel_layouts) {
396+ ret = ff_set_common_channel_layouts_from_list(ctx, buf->channel_layouts);
397+ if (ret < 0)
398+ return ret;
399+ }
400+#if FF_API_BUFFERSINK_OPTS
401+ } else {
287402 AVFilterFormats *formats = NULL;
288403 AVChannelLayout layout = { 0 };
289404 AVFilterChannelLayouts *layouts = NULL;
290405 unsigned i;
291− int ret;
292−
293406 CHECK_LIST_SIZE(sample_fmts)
294407 CHECK_LIST_SIZE(sample_rates)
295408
@@ -343,6 +456,8 @@ static int asink_query_formats(AVFilterContext *ctx) · 47 unmodified lines
343456 if ((ret = ff_set_common_samplerates(ctx, formats)) < 0)
344457 return ret;
345458 }
459+ }
460+#endif
346461
347462 return 0;
348463 }
@@ -350,19 +465,38 @@ static int asink_query_formats(AVFilterContext *ctx) · 1 unmodified line
350465 #define OFFSET(x) offsetof(BufferSinkContext, x)
351466 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
352467 static const AVOption buffersink_options[] = {
353− { "pix_fmts", "set the supported pixel formats", OFFSET(pixel_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS },
354− { "color_spaces", "set the supported color spaces", OFFSET(color_spaces), AV_OPT_TYPE_BINARY, .flags = FLAGS },
355− { "color_ranges", "set the supported color ranges", OFFSET(color_ranges), AV_OPT_TYPE_BINARY, .flags = FLAGS },
468+#if FF_API_BUFFERSINK_OPTS
469+ { "pix_fmts", "set the supported pixel formats", OFFSET(pixel_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS | AV_OPT_FLAG_DEPRECATED },
470+ { "color_spaces", "set the supported color spaces", OFFSET(color_spaces), AV_OPT_TYPE_BINARY, .flags = FLAGS | AV_OPT_FLAG_DEPRECATED },
471+ { "color_ranges", "set the supported color ranges", OFFSET(color_ranges), AV_OPT_TYPE_BINARY, .flags = FLAGS | AV_OPT_FLAG_DEPRECATED },
472+#endif
473+
474+ { "pixel_formats", "array of supported pixel formats", OFFSET(pixel_formats),
475+ AV_OPT_TYPE_PIXEL_FMT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
476+ { "colorspaces", "array of supported color spaces", OFFSET(colorspaces),
477+ AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
478+ { "colorranges", "array of supported color ranges", OFFSET(colorranges),
479+ AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
480+
356481 { NULL },
357482 };
358483 #undef FLAGS
359484 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM
360485 static const AVOption abuffersink_options[] = {
361− { "sample_fmts", "set the supported sample formats", OFFSET(sample_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS },
362− { "sample_rates", "set the supported sample rates", OFFSET(sample_rates), AV_OPT_TYPE_BINARY, .flags = FLAGS },
486+#if FF_API_BUFFERSINK_OPTS
487+ { "sample_fmts", "set the supported sample formats", OFFSET(sample_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS | AV_OPT_FLAG_DEPRECATED },
488+ { "sample_rates", "set the supported sample rates", OFFSET(sample_rates), AV_OPT_TYPE_BINARY, .flags = FLAGS | AV_OPT_FLAG_DEPRECATED },
363489 { "ch_layouts", "set a '|'-separated list of supported channel layouts",
364− OFFSET(channel_layouts_str), AV_OPT_TYPE_STRING, .flags = FLAGS },
365− { "all_channel_counts", "accept all channel counts", OFFSET(all_channel_counts), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS },
490+ OFFSET(channel_layouts_str), AV_OPT_TYPE_STRING, .flags = FLAGS | AV_OPT_FLAG_DEPRECATED },
491+ { "all_channel_counts", "accept all channel counts", OFFSET(all_channel_counts), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS | AV_OPT_FLAG_DEPRECATED },
492+#endif
493+
494+ { "sample_formats", "array of supported sample formats", OFFSET(sample_formats),
495+ AV_OPT_TYPE_SAMPLE_FMT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
496+ { "samplerates", "array of supported sample formats", OFFSET(samplerates),
497+ AV_OPT_TYPE_INT | AV_OPT_TYPE_FLAG_ARRAY, .max = INT_MAX, .flags = FLAGS },
498+ { "channel_layouts", "array of supported channel layouts", OFFSET(channel_layouts),
499+ AV_OPT_TYPE_CHLAYOUT | AV_OPT_TYPE_FLAG_ARRAY, .flags = FLAGS },
366500 { NULL },
367501 };
368502 #undef FLAGS
@@ -375,7 +509,7 @@ const AVFilter ff_vsink_buffer = { · 6 unmodified lines
375509 .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
376510 .priv_size = sizeof(BufferSinkContext),
377511 .priv_class = &buffersink_class,
378− .init = common_init,
512+ .init = init_video,
379513 .uninit = uninit,
380514 .activate = activate,
381515 FILTER_INPUTS(ff_video_default_filterpad),
@@ -396,7 +530,7 @@ const AVFilter ff_asink_abuffer = { · 14 unmodified lines
396530 .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
397531 .priv_class = &abuffersink_class,
398532 .priv_size = sizeof(BufferSinkContext),
399− .init = common_init,
533+ .init = init_audio,
400534 .uninit = uninit,
401535 .activate = activate,
402536 FILTER_INPUTS(inputs_audio),
libavfilter/buffersink.h+7−14
@@ -54,20 +54,13 @@ · 53 unmodified lines
5454 *
5555 * The format can be constrained by setting options, using av_opt_set() and
5656 * related functions with the AV_OPT_SEARCH_CHILDREN flag.
57− * - pix_fmts (int list),
58− * - color_spaces (int list),
59− * - color_ranges (int list),
60− * - sample_fmts (int list),
61− * - sample_rates (int list),
62− * - ch_layouts (string),
63− * - channel_counts (int list),
64− * - all_channel_counts (bool).
65− * Most of these options are of type binary, and should be set using
66− * av_opt_set_int_list() or av_opt_set_bin(). If they are not set, all
67− * corresponding formats are accepted.
68− *
69− * As a special case, if ch_layouts is not set, all valid channel layouts are
70− * accepted except for UNSPEC layouts, unless all_channel_counts is set.
57+ * - pixel_formats (array of pixel formats),
58+ * - colorspaces (array of int),
59+ * - colorranges (array of int),
60+ * - sample_formats (array of sample formats),
61+ * - samplerates (array of int),
62+ * - channel_layouts (array of channel layouts)
63+ * If an option is not set, all corresponding formats are accepted.
7164 */
7265
7366 /**
libavfilter/version.h+1−1
@@ -31,7 +31,7 @@ · 30 unmodified lines
3131
3232 #include "version_major.h"
3333
34−#define LIBAVFILTER_VERSION_MINOR 5
34+#define LIBAVFILTER_VERSION_MINOR 6
3535 #define LIBAVFILTER_VERSION_MICRO 100
3636
3737
libavfilter/version_major.h+1−0
@@ -36,5 +36,6 @@ · 35 unmodified lines
3636 */
3737
3838 #define FF_API_LINK_PUBLIC (LIBAVFILTER_VERSION_MAJOR < 11)
39+#define FF_API_BUFFERSINK_OPTS (LIBAVFILTER_VERSION_MAJOR < 11)
3940
4041 #endif /* AVFILTER_VERSION_MAJOR_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t