Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2021-08-31 17:03:14 +0300
committerJames Almer <jamrial@gmail.com>2022-03-15 15:42:46 +0300
commit1f96db959c1235bb7079d354e09914a0a2608f62 (patch)
tree21ac480d5b148c0524761853e6badb3a90a7ca3f /libavfilter/buffersink.c
parent8a5896ec1f635ccf0d726f7ba7a06649ebeebf25 (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.c93
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 },
};