[FFmpeg-cvslog] af_pan: use libswr for rematrixing.
Nicolas George
git at videolan.org
Mon Feb 20 20:58:22 CET 2012
ffmpeg | branch: master | Nicolas George <nicolas.george at normalesup.org> | Thu Feb 16 12:34:39 2012 +0100| [a44b510d5615dcda705ab2b60fef42ac905dfa44] | committer: Nicolas George
af_pan: use libswr for rematrixing.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a44b510d5615dcda705ab2b60fef42ac905dfa44
---
doc/filters.texi | 3 --
libavfilter/af_pan.c | 71 +++++++++++++++++---------------------------------
2 files changed, 24 insertions(+), 50 deletions(-)
diff --git a/doc/filters.texi b/doc/filters.texi
index b885958..238401a 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -384,9 +384,6 @@ The channel remapping will be effective if, and only if:
@itemize
@item gain coefficients are zeroes or ones,
@item only one input per channel output,
- at item the number of output channels is supported by libswresample (16 at the
- moment)
- at c if SWR_CH_MAX changes, fix the line above.
@end itemize
If all these conditions are satisfied, the filter will notify the user ("Pure
diff --git a/libavfilter/af_pan.c b/libavfilter/af_pan.c
index 119111d..a93bd75 100644
--- a/libavfilter/af_pan.c
+++ b/libavfilter/af_pan.c
@@ -234,18 +234,29 @@ static int config_props(AVFilterLink *link)
}
}
}
- // gains are pure, init the channel mapping
- if (pan->pure_gains) {
+ /* TODO reindent */
// sanity check; can't be done in query_formats since the inlink
// channel layout is unknown at that time
- if (pan->nb_input_channels > SWR_CH_MAX) {
+ if (pan->nb_input_channels > SWR_CH_MAX ||
+ pan->nb_output_channels > SWR_CH_MAX) {
av_log(ctx, AV_LOG_ERROR,
"libswresample support a maximum of %d channels. "
"Feel free to ask for a higher limit.\n", SWR_CH_MAX);
return AVERROR_PATCHWELCOME;
}
+ // init libswresample context
+ pan->swr = swr_alloc_set_opts(pan->swr,
+ pan->out_channel_layout, link->format, link->sample_rate,
+ link->channel_layout, link->format, link->sample_rate,
+ 0, ctx);
+ if (!pan->swr)
+ return AVERROR(ENOMEM);
+
+ // gains are pure, init the channel mapping
+ if (pan->pure_gains) {
+
// get channel map from the pure gains
for (i = 0; i < pan->nb_output_channels; i++) {
int ch_id = -1;
@@ -258,19 +269,9 @@ static int config_props(AVFilterLink *link)
pan->channel_map[i] = ch_id;
}
- // init libswresample context
- pan->swr = swr_alloc_set_opts(pan->swr,
- pan->out_channel_layout, link->format, link->sample_rate,
- link->channel_layout, link->format, link->sample_rate,
- 0, ctx);
- if (!pan->swr)
- return AVERROR(ENOMEM);
av_opt_set_int(pan->swr, "icl", pan->out_channel_layout, 0);
av_opt_set_int(pan->swr, "uch", pan->nb_output_channels, 0);
swr_set_channel_mapping(pan->swr, pan->channel_map);
- r = swr_init(pan->swr);
- if (r < 0)
- return r;
} else {
// renormalize
for (i = 0; i < pan->nb_output_channels; i++) {
@@ -289,7 +290,16 @@ static int config_props(AVFilterLink *link)
for (j = 0; j < pan->nb_input_channels; j++)
pan->gain.d[i][j] /= t;
}
+ av_opt_set_int(pan->swr, "icl", link->channel_layout, 0);
+ av_opt_set_int(pan->swr, "ocl", pan->out_channel_layout, 0);
+ swr_set_matrix(pan->swr, pan->gain.d[0],
+ pan->gain.d[1] - pan->gain.d[0]);
}
+
+ r = swr_init(pan->swr);
+ if (r < 0)
+ return r;
+
// summary
for (i = 0; i < pan->nb_output_channels; i++) {
cur = buf;
@@ -331,30 +341,6 @@ static void filter_samples_channel_mapping(PanContext *pan,
swr_convert(pan->swr, outsamples->data, n, (void *)insamples->data, n);
}
-static void filter_samples_panning(PanContext *pan,
- AVFilterBufferRef *outsamples,
- AVFilterBufferRef *insamples,
- int n)
-{
- int i, o;
-
- /* input */
- const int16_t *in = (int16_t *)insamples->data[0];
- const int16_t *in_end = in + n * pan->nb_input_channels;
-
- /* output */
- int16_t *out = (int16_t *)outsamples->data[0];
-
- for (; in < in_end; in += pan->nb_input_channels) {
- for (o = 0; o < pan->nb_output_channels; o++) {
- int v = 0;
- for (i = 0; i < pan->nb_input_channels; i++)
- v += pan->gain.i[o][i] * in[i];
- *(out++) = v >> 8;
- }
- }
-}
-
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
{
int n = insamples->audio->nb_samples;
@@ -379,21 +365,12 @@ static int query_formats(AVFilterContext *ctx)
AVFilterLink *outlink = ctx->outputs[0];
AVFilterFormats *formats;
- if (pan->nb_output_channels <= SWR_CH_MAX)
+ /* TODO reindent */
pan->pure_gains = are_gains_pure(pan);
- if (pan->pure_gains) {
/* libswr supports any sample and packing formats */
avfilter_set_common_sample_formats(ctx, avfilter_make_all_formats(AVMEDIA_TYPE_AUDIO));
avfilter_set_common_packing_formats(ctx, avfilter_make_all_packing_formats());
pan->filter_samples = filter_samples_channel_mapping;
- } else {
- const enum AVSampleFormat sample_fmts[] = {AV_SAMPLE_FMT_S16, -1};
- const int packing_fmts[] = {AVFILTER_PACKED, -1};
-
- avfilter_set_common_sample_formats (ctx, avfilter_make_format_list(sample_fmts));
- avfilter_set_common_packing_formats(ctx, avfilter_make_format_list(packing_fmts));
- pan->filter_samples = filter_samples_panning;
- }
// inlink supports any channel layout
formats = avfilter_make_all_channel_layouts();
More information about the ffmpeg-cvslog
mailing list