diff options
author | James Almer <jamrial@gmail.com> | 2021-08-31 17:03:14 +0300 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2022-03-15 15:42:46 +0300 |
commit | 1f96db959c1235bb7079d354e09914a0a2608f62 (patch) | |
tree | 21ac480d5b148c0524761853e6badb3a90a7ca3f /libavfilter/buffersink.c | |
parent | 8a5896ec1f635ccf0d726f7ba7a06649ebeebf25 (diff) |
avfilter: convert to new channel layout API
Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavfilter/buffersink.c')
-rw-r--r-- | libavfilter/buffersink.c | 93 |
1 files changed, 84 insertions, 9 deletions
diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c index c0215669e7..b989473719 100644 --- a/libavfilter/buffersink.c +++ b/libavfilter/buffersink.c @@ -24,6 +24,7 @@ */ #include "libavutil/avassert.h" +#include "libavutil/avstring.h" #include "libavutil/channel_layout.h" #include "libavutil/common.h" #include "libavutil/internal.h" @@ -49,10 +50,13 @@ typedef struct BufferSinkContext { /* only used for audio */ enum AVSampleFormat *sample_fmts; ///< list of accepted sample formats int sample_fmts_size; +#if FF_API_OLD_CHANNEL_LAYOUT int64_t *channel_layouts; ///< list of accepted channel layouts int channel_layouts_size; int *channel_counts; ///< list of accepted channel counts int channel_counts_size; +#endif + 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; @@ -62,6 +66,7 @@ typedef struct BufferSinkContext { #define NB_ITEMS(list) (list ## _size / sizeof(*list)) +#if FF_API_OLD_CHANNEL_LAYOUT static void cleanup_redundant_layouts(AVFilterContext *ctx) { BufferSinkContext *buf = ctx->priv; @@ -74,7 +79,7 @@ static void cleanup_redundant_layouts(AVFilterContext *ctx) if (buf->channel_counts[i] < 64) counts |= (uint64_t)1 << buf->channel_counts[i]; for (i = lc = 0; i < nb_layouts; i++) { - n = av_get_channel_layout_nb_channels(buf->channel_layouts[i]); + n = av_popcount64(buf->channel_layouts[i]); if (n < 64 && (counts & ((uint64_t)1 << n))) av_log(ctx, AV_LOG_WARNING, "Removing channel layout 0x%"PRIx64", redundant with %d channels\n", @@ -84,6 +89,7 @@ static void cleanup_redundant_layouts(AVFilterContext *ctx) } buf->channel_layouts_size = lc * sizeof(*buf->channel_layouts); } +#endif int attribute_align_arg av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame) { @@ -217,12 +223,34 @@ MAKE_AVFILTERLINK_ACCESSOR(int , w ) MAKE_AVFILTERLINK_ACCESSOR(int , h ) MAKE_AVFILTERLINK_ACCESSOR(AVRational , sample_aspect_ratio) -MAKE_AVFILTERLINK_ACCESSOR(int , channels ) +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS MAKE_AVFILTERLINK_ACCESSOR(uint64_t , channel_layout ) +FF_ENABLE_DEPRECATION_WARNINGS +#endif MAKE_AVFILTERLINK_ACCESSOR(int , sample_rate ) MAKE_AVFILTERLINK_ACCESSOR(AVBufferRef * , hw_frames_ctx ) +int av_buffersink_get_channels(const AVFilterContext *ctx) +{ + av_assert0(ctx->filter->activate == activate); + return ctx->inputs[0]->ch_layout.nb_channels; +} + +int av_buffersink_get_ch_layout(const AVFilterContext *ctx, AVChannelLayout *out) +{ + AVChannelLayout ch_layout = { 0 }; + int ret; + + av_assert0(ctx->filter->activate == activate); + ret = av_channel_layout_copy(&ch_layout, &ctx->inputs[0]->ch_layout); + if (ret < 0) + return ret; + *out = ch_layout; + return 0; +} + #define CHECK_LIST_SIZE(field) \ if (buf->field ## _size % sizeof(*buf->field)) { \ av_log(ctx, AV_LOG_ERROR, "Invalid size for " #field ": %d, " \ @@ -256,14 +284,17 @@ static int asink_query_formats(AVFilterContext *ctx) { BufferSinkContext *buf = ctx->priv; AVFilterFormats *formats = NULL; + AVChannelLayout layout = { 0 }; AVFilterChannelLayouts *layouts = NULL; unsigned i; int ret; CHECK_LIST_SIZE(sample_fmts) CHECK_LIST_SIZE(sample_rates) +#if FF_API_OLD_CHANNEL_LAYOUT CHECK_LIST_SIZE(channel_layouts) CHECK_LIST_SIZE(channel_counts) +#endif if (buf->sample_fmts_size) { for (i = 0; i < NB_ITEMS(buf->sample_fmts); i++) @@ -273,15 +304,53 @@ static int asink_query_formats(AVFilterContext *ctx) return ret; } - if (buf->channel_layouts_size || buf->channel_counts_size || - buf->all_channel_counts) { + if ( +#if FF_API_OLD_CHANNEL_LAYOUT + buf->channel_layouts_size || buf->channel_counts_size || +#endif + buf->channel_layouts_str || buf->all_channel_counts) { +#if FF_API_OLD_CHANNEL_LAYOUT cleanup_redundant_layouts(ctx); for (i = 0; i < NB_ITEMS(buf->channel_layouts); i++) - if ((ret = ff_add_channel_layout(&layouts, buf->channel_layouts[i])) < 0) + if ((ret = av_channel_layout_from_mask(&layout, buf->channel_layouts[i])) < 0 || + (ret = ff_add_channel_layout(&layouts, &layout) < 0)) return ret; - for (i = 0; i < NB_ITEMS(buf->channel_counts); i++) - if ((ret = ff_add_channel_layout(&layouts, FF_COUNT2LAYOUT(buf->channel_counts[i]))) < 0) + for (i = 0; i < NB_ITEMS(buf->channel_counts); i++) { + layout = FF_COUNT2LAYOUT(buf->channel_counts[i]); + if ((ret = ff_add_channel_layout(&layouts, &layout)) < 0) return ret; + } +#endif + if (buf->channel_layouts_str) { + const char *cur = buf->channel_layouts_str; + +#if FF_API_OLD_CHANNEL_LAYOUT + if (layouts) + av_log(ctx, AV_LOG_WARNING, + "Conflicting ch_layouts and list of channel_counts/channel_layouts. Ignoring the former\n"); + else +#endif + while (cur && *cur) { + char *chl = av_get_token(&cur, "|,"); + if (!chl) + return AVERROR(ENOMEM); + if (*cur) + cur++; + + ret = av_channel_layout_from_string(&layout, chl); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout: %s.\n", chl); + av_free(chl); + return ret; + } + ret = ff_add_channel_layout(&layouts, &layout); + av_channel_layout_uninit(&layout); + av_free(chl); + if (ret < 0) + return ret; + } + } + if (buf->all_channel_counts) { if (layouts) av_log(ctx, AV_LOG_WARNING, @@ -316,8 +385,14 @@ static const AVOption buffersink_options[] = { 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 }, - { "channel_layouts", "set the supported channel layouts", OFFSET(channel_layouts), AV_OPT_TYPE_BINARY, .flags = FLAGS }, - { "channel_counts", "set the supported channel counts", OFFSET(channel_counts), AV_OPT_TYPE_BINARY, .flags = FLAGS }, +#if FF_API_OLD_CHANNEL_LAYOUT + { "channel_layouts", "set the supported channel layouts (deprecated, use ch_layouts)", + OFFSET(channel_layouts), AV_OPT_TYPE_BINARY, .flags = FLAGS | AV_OPT_FLAG_DEPRECATED }, + { "channel_counts", "set the supported channel counts (deprecated, use ch_layouts)", + OFFSET(channel_counts), AV_OPT_TYPE_BINARY, .flags = FLAGS | AV_OPT_FLAG_DEPRECATED }, +#endif + { "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 }, { NULL }, }; |