From a44b510d5615dcda705ab2b60fef42ac905dfa44 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Thu, 16 Feb 2012 12:34:39 +0100 Subject: af_pan: use libswr for rematrixing. --- libavfilter/af_pan.c | 71 ++++++++++++++++++---------------------------------- 1 file changed, 24 insertions(+), 47 deletions(-) (limited to 'libavfilter/af_pan.c') diff --git a/libavfilter/af_pan.c b/libavfilter/af_pan.c index 119111d68c..a93bd75465 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(); -- cgit v1.2.3