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
2 2
3API changes, most recent first:3API changes, most recent first:
4 4
52024-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
5-------- 8< --------- FFmpeg 7.1 was cut here -------- 8< ---------23-------- 8< --------- FFmpeg 7.1 was cut here -------- 8< ---------
6 24
72024-09-23 - 6940a6de2f0 - lavu 59.38.100 - frame.h252024-09-23 - 6940a6de2f0 - lavu 59.38.100 - frame.h
libavfilter/buffersink.c+148−14
@@ -28,6 +28,7 @@ · 27 unmodified lines
28#include "libavutil/channel_layout.h"28#include "libavutil/channel_layout.h"
29#include "libavutil/common.h"29#include "libavutil/common.h"
30#include "libavutil/internal.h"30#include "libavutil/internal.h"
31#include "libavutil/mem.h"
31#include "libavutil/opt.h"32#include "libavutil/opt.h"
32 33
33#include "audio.h"34#include "audio.h"
@@ -45,26 +46,46 @@ typedef struct BufferSinkContext { · 11 unmodified lines
45 unsigned frame_size;46 unsigned frame_size;
46 47
47 /* only used for video */48 /* only used for video */
49#if FF_API_BUFFERSINK_OPTS
48 enum AVPixelFormat *pixel_fmts; ///< list of accepted pixel formats50 enum AVPixelFormat *pixel_fmts; ///< list of accepted pixel formats
49 int pixel_fmts_size;51 int pixel_fmts_size;
50 enum AVColorSpace *color_spaces; ///< list of accepted color spaces52 enum AVColorSpace *color_spaces; ///< list of accepted color spaces
51 int color_spaces_size;53 int color_spaces_size;
52 enum AVColorRange *color_ranges; ///< list of accepted color ranges54 enum AVColorRange *color_ranges; ///< list of accepted color ranges
53 int color_ranges_size;55 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;
54 66
55 /* only used for audio */67 /* only used for audio */
68#if FF_API_BUFFERSINK_OPTS
56 enum AVSampleFormat *sample_fmts; ///< list of accepted sample formats69 enum AVSampleFormat *sample_fmts; ///< list of accepted sample formats
57 int sample_fmts_size;70 int sample_fmts_size;
58 char *channel_layouts_str; ///< list of accepted channel layouts71 char *channel_layouts_str; ///< list of accepted channel layouts
59 int all_channel_counts;72 int all_channel_counts;
60 int *sample_rates; ///< list of accepted sample rates73 int *sample_rates; ///< list of accepted sample rates
61 int sample_rates_size;74 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;
62 85
63 AVFrame *peeked_frame;86 AVFrame *peeked_frame;
64} BufferSinkContext;87} BufferSinkContext;
65 88
66#define NB_ITEMS(list) (list ## _size / sizeof(*list))
67
68int attribute_align_arg av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame)89int attribute_align_arg av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame)
69{90{
70 return av_buffersink_get_frame_flags(ctx, frame, 0);91 return av_buffersink_get_frame_flags(ctx, frame, 0);
@@ -138,6 +159,39 @@ static av_cold int common_init(AVFilterContext *ctx) · 67 unmodified lines
138 return 0;159 return 0;
139}160}
140 161
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
171static 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
182static 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
141static void uninit(AVFilterContext *ctx)195static void uninit(AVFilterContext *ctx)
142{196{
143 BufferSinkContext *buf = ctx->priv;197 BufferSinkContext *buf = ctx->priv;
@@ -235,6 +289,9 @@ int av_buffersink_get_ch_layout(const AVFilterContext *ctx, AVChannelLayout *out · 91 unmodified lines
235 return 0;289 return 0;
236}290}
237 291
292#if FF_API_BUFFERSINK_OPTS
293#define NB_ITEMS(list) (list ## _size / sizeof(*list))
294
238#define CHECK_LIST_SIZE(field) \295#define CHECK_LIST_SIZE(field) \
239 if (buf->field ## _size % sizeof(*buf->field)) { \296 if (buf->field ## _size % sizeof(*buf->field)) { \
240 av_log(ctx, AV_LOG_ERROR, "Invalid size for " #field ": %d, " \297 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
242 buf->field ## _size, (int)sizeof(*buf->field)); \299 buf->field ## _size, (int)sizeof(*buf->field)); \
243 return AVERROR(EINVAL); \300 return AVERROR(EINVAL); \
244 }301 }
302#endif
303
245static int vsink_query_formats(AVFilterContext *ctx)304static int vsink_query_formats(AVFilterContext *ctx)
246{305{
247 BufferSinkContext *buf = ctx->priv;306 BufferSinkContext *buf = ctx->priv;
248 unsigned i;
249 int ret;307 int ret;
250 308
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;
251 CHECK_LIST_SIZE(pixel_fmts)336 CHECK_LIST_SIZE(pixel_fmts)
252 CHECK_LIST_SIZE(color_spaces)337 CHECK_LIST_SIZE(color_spaces)
253 CHECK_LIST_SIZE(color_ranges)338 CHECK_LIST_SIZE(color_ranges)
@@ -277,6 +362,8 @@ static int vsink_query_formats(AVFilterContext *ctx) · 23 unmodified lines
277 if ((ret = ff_set_common_color_ranges(ctx, formats)) < 0)362 if ((ret = ff_set_common_color_ranges(ctx, formats)) < 0)
278 return ret;363 return ret;
279 }364 }
365 }
366#endif
280 367
281 return 0;368 return 0;
282}369}
@@ -284,12 +371,38 @@ static int vsink_query_formats(AVFilterContext *ctx) · 1 unmodified line
284static int asink_query_formats(AVFilterContext *ctx)371static int asink_query_formats(AVFilterContext *ctx)
285{372{
286 BufferSinkContext *buf = ctx->priv;373 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 {
287 AVFilterFormats *formats = NULL;402 AVFilterFormats *formats = NULL;
288 AVChannelLayout layout = { 0 };403 AVChannelLayout layout = { 0 };
289 AVFilterChannelLayouts *layouts = NULL;404 AVFilterChannelLayouts *layouts = NULL;
290 unsigned i;405 unsigned i;
291 int ret;
292
293 CHECK_LIST_SIZE(sample_fmts)406 CHECK_LIST_SIZE(sample_fmts)
294 CHECK_LIST_SIZE(sample_rates)407 CHECK_LIST_SIZE(sample_rates)
295 408
@@ -343,6 +456,8 @@ static int asink_query_formats(AVFilterContext *ctx) · 47 unmodified lines
343 if ((ret = ff_set_common_samplerates(ctx, formats)) < 0)456 if ((ret = ff_set_common_samplerates(ctx, formats)) < 0)
344 return ret;457 return ret;
345 }458 }
459 }
460#endif
346 461
347 return 0;462 return 0;
348}463}
@@ -350,19 +465,38 @@ static int asink_query_formats(AVFilterContext *ctx) · 1 unmodified line
350#define OFFSET(x) offsetof(BufferSinkContext, x)465#define OFFSET(x) offsetof(BufferSinkContext, x)
351#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM466#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
352static const AVOption buffersink_options[] = {467static const AVOption buffersink_options[] = {
353 { "pix_fmts", "set the supported pixel formats", OFFSET(pixel_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS },468#if FF_API_BUFFERSINK_OPTS
354 { "color_spaces", "set the supported color spaces", OFFSET(color_spaces), AV_OPT_TYPE_BINARY, .flags = FLAGS },469 { "pix_fmts", "set the supported pixel formats", OFFSET(pixel_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS | AV_OPT_FLAG_DEPRECATED },
355 { "color_ranges", "set the supported color ranges", OFFSET(color_ranges), AV_OPT_TYPE_BINARY, .flags = FLAGS },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
356 { NULL },481 { NULL },
357};482};
358#undef FLAGS483#undef FLAGS
359#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM484#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM
360static const AVOption abuffersink_options[] = {485static const AVOption abuffersink_options[] = {
361 { "sample_fmts", "set the supported sample formats", OFFSET(sample_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS },486#if FF_API_BUFFERSINK_OPTS
362 { "sample_rates", "set the supported sample rates", OFFSET(sample_rates), AV_OPT_TYPE_BINARY, .flags = FLAGS },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 },
363 { "ch_layouts", "set a '|'-separated list of supported channel layouts",489 { "ch_layouts", "set a '|'-separated list of supported channel layouts",
364 OFFSET(channel_layouts_str), AV_OPT_TYPE_STRING, .flags = FLAGS },490 OFFSET(channel_layouts_str), AV_OPT_TYPE_STRING, .flags = FLAGS | AV_OPT_FLAG_DEPRECATED },
365 { "all_channel_counts", "accept all channel counts", OFFSET(all_channel_counts), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS },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 },
366 { NULL },500 { NULL },
367};501};
368#undef FLAGS502#undef FLAGS
@@ -375,7 +509,7 @@ const AVFilter ff_vsink_buffer = { · 6 unmodified lines
375 .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),509 .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
376 .priv_size = sizeof(BufferSinkContext),510 .priv_size = sizeof(BufferSinkContext),
377 .priv_class = &buffersink_class,511 .priv_class = &buffersink_class,
378 .init = common_init,512 .init = init_video,
379 .uninit = uninit,513 .uninit = uninit,
380 .activate = activate,514 .activate = activate,
381 FILTER_INPUTS(ff_video_default_filterpad),515 FILTER_INPUTS(ff_video_default_filterpad),
@@ -396,7 +530,7 @@ const AVFilter ff_asink_abuffer = { · 14 unmodified lines
396 .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),530 .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
397 .priv_class = &abuffersink_class,531 .priv_class = &abuffersink_class,
398 .priv_size = sizeof(BufferSinkContext),532 .priv_size = sizeof(BufferSinkContext),
399 .init = common_init,533 .init = init_audio,
400 .uninit = uninit,534 .uninit = uninit,
401 .activate = activate,535 .activate = activate,
402 FILTER_INPUTS(inputs_audio),536 FILTER_INPUTS(inputs_audio),
libavfilter/buffersink.h+7−14
@@ -54,20 +54,13 @@ · 53 unmodified lines
54 *54 *
55 * The format can be constrained by setting options, using av_opt_set() and55 * The format can be constrained by setting options, using av_opt_set() and
56 * related functions with the AV_OPT_SEARCH_CHILDREN flag.56 * related functions with the AV_OPT_SEARCH_CHILDREN flag.
57 * - pix_fmts (int list),57 * - pixel_formats (array of pixel formats),
58 * - color_spaces (int list),58 * - colorspaces (array of int),
59 * - color_ranges (int list),59 * - colorranges (array of int),
60 * - sample_fmts (int list),60 * - sample_formats (array of sample formats),
61 * - sample_rates (int list),61 * - samplerates (array of int),
62 * - ch_layouts (string),62 * - channel_layouts (array of channel layouts)
63 * - channel_counts (int list),63 * If an option is not set, all corresponding formats are accepted.
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.
71 */64 */
72 65
73/**66/**
libavfilter/version.h+1−1
@@ -31,7 +31,7 @@ · 30 unmodified lines
31 31
32#include "version_major.h"32#include "version_major.h"
33 33
34#define LIBAVFILTER_VERSION_MINOR 534#define LIBAVFILTER_VERSION_MINOR 6
35#define LIBAVFILTER_VERSION_MICRO 10035#define LIBAVFILTER_VERSION_MICRO 100
36 36
37 37
libavfilter/version_major.h+1−0
@@ -36,5 +36,6 @@ · 35 unmodified lines
36 */36 */
37 37
38#define FF_API_LINK_PUBLIC (LIBAVFILTER_VERSION_MAJOR < 11)38#define FF_API_LINK_PUBLIC (LIBAVFILTER_VERSION_MAJOR < 11)
39#define FF_API_BUFFERSINK_OPTS (LIBAVFILTER_VERSION_MAJOR < 11)
39 40
40#endif /* AVFILTER_VERSION_MAJOR_H */41#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