History

lavfi/af_channelsplit: support arbitrary channel layouts

Not just those containing channel values under 64. Also, remove an arbitrary limitation on channel count.

Anton Khirnov committed 2 years ago

Commit 18d492f1 parent 7dc81d31 file · +29 −14Browse files

Showing the changes to libavfilter (1 of 1 file). Show all

Unified · Split

libavfilter/af_channelsplit.c+29−14
@@ -34,15 +34,13 @@ · 33 unmodified lines
34#include "filters.h"34#include "filters.h"
35#include "formats.h"35#include "formats.h"
36 36
37#define MAX_CH 64
38
39typedef struct ChannelSplitContext {37typedef struct ChannelSplitContext {
40 const AVClass *class;38 const AVClass *class;
41 39
42 AVChannelLayout channel_layout;40 AVChannelLayout channel_layout;
43 char *channels_str;41 char *channels_str;
44 42
45 int map[64];43 int *map;
46} ChannelSplitContext;44} ChannelSplitContext;
47 45
48#define OFFSET(x) offsetof(ChannelSplitContext, x)46#define OFFSET(x) offsetof(ChannelSplitContext, x)
@@ -71,10 +69,9 @@ static av_cold int init(AVFilterContext *ctx) · 22 unmodified lines
71 goto fail;69 goto fail;
72 }70 }
73 71
74 if (channel_layout.nb_channels > MAX_CH) {72 s->map = av_calloc(channel_layout.nb_channels, sizeof(*s->map));
75 av_log(ctx, AV_LOG_ERROR, "Too many channels\n");73 if (!s->map)
76 goto fail;74 return AVERROR(ENOMEM);
77 }
78 75
79 for (i = 0; i < channel_layout.nb_channels; i++) {76 for (i = 0; i < channel_layout.nb_channels; i++) {
80 enum AVChannel channel = av_channel_layout_channel_from_index(&channel_layout, i);77 enum AVChannel channel = av_channel_layout_channel_from_index(&channel_layout, i);
@@ -118,6 +115,7 @@ static av_cold void uninit(AVFilterContext *ctx) · 37 unmodified lines
118 ChannelSplitContext *s = ctx->priv;115 ChannelSplitContext *s = ctx->priv;
119 116
120 av_channel_layout_uninit(&s->channel_layout);117 av_channel_layout_uninit(&s->channel_layout);
118 av_freep(&s->map);
121}119}
122 120
123static int query_formats(AVFilterContext *ctx)121static int query_formats(AVFilterContext *ctx)
@@ -139,9 +137,27 @@ static int query_formats(AVFilterContext *ctx) · 15 unmodified lines
139 AVFilterChannelLayouts *out_layouts = NULL;137 AVFilterChannelLayouts *out_layouts = NULL;
140 enum AVChannel channel = av_channel_layout_channel_from_index(&s->channel_layout, s->map[i]);138 enum AVChannel channel = av_channel_layout_channel_from_index(&s->channel_layout, s->map[i]);
141 139
142 if ((ret = av_channel_layout_from_mask(&channel_layout, 1ULL << channel)) < 0 ||140 channel_layout.u.map = av_mallocz(sizeof(*channel_layout.u.map));
143 (ret = ff_add_channel_layout(&out_layouts, &channel_layout)) < 0 ||141 if (!channel_layout.u.map)
144 (ret = ff_channel_layouts_ref(out_layouts, &ctx->outputs[i]->incfg.channel_layouts)) < 0)142 return AVERROR(ENOMEM);
143
144 channel_layout.u.map[0].id = channel;
145 channel_layout.nb_channels = 1;
146 channel_layout.order = AV_CHANNEL_ORDER_CUSTOM;
147
148 ret = av_channel_layout_retype(&channel_layout, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
149 if (ret < 0) {
150 av_channel_layout_uninit(&channel_layout);
151 return ret;
152 }
153
154 ret = ff_add_channel_layout(&out_layouts, &channel_layout);
155 av_channel_layout_uninit(&channel_layout);
156 if (ret < 0)
157 return ret;
158
159 ret = ff_channel_layouts_ref(out_layouts, &ctx->outputs[i]->incfg.channel_layouts);
160 if (ret < 0)
145 return ret;161 return ret;
146 }162 }
147 163
@@ -154,17 +170,16 @@ static int filter_frame(AVFilterLink *outlink, AVFrame *buf) · 6 unmodified lines
154 AVFilterContext *ctx = outlink->src;170 AVFilterContext *ctx = outlink->src;
155 ChannelSplitContext *s = ctx->priv;171 ChannelSplitContext *s = ctx->priv;
156 const int i = FF_OUTLINK_IDX(outlink);172 const int i = FF_OUTLINK_IDX(outlink);
157 enum AVChannel channel = av_channel_layout_channel_from_index(&buf->ch_layout, s->map[i]);
158 int ret;173 int ret;
159 174
160 av_assert1(channel >= 0);
161
162 buf_out = av_frame_clone(buf);175 buf_out = av_frame_clone(buf);
163 if (!buf_out)176 if (!buf_out)
164 return AVERROR(ENOMEM);177 return AVERROR(ENOMEM);
165 178
166 buf_out->data[0] = buf_out->extended_data[0] = buf_out->extended_data[s->map[i]];179 buf_out->data[0] = buf_out->extended_data[0] = buf_out->extended_data[s->map[i]];
167 ret = av_channel_layout_from_mask(&buf_out->ch_layout, 1ULL << channel);180
181 av_channel_layout_uninit(&buf_out->ch_layout);
182 ret = av_channel_layout_copy(&buf_out->ch_layout, &outlink->ch_layout);
168 if (ret < 0) {183 if (ret < 0) {
169 av_frame_free(&buf_out);184 av_frame_free(&buf_out);
170 return ret;185 return ret;

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