diff options
author | Nicolas George <nicolas.george@normalesup.org> | 2012-02-16 12:34:39 +0100 |
---|---|---|
committer | Nicolas George <nicolas.george@normalesup.org> | 2012-02-20 20:46:35 +0100 |
commit | a44b510d5615dcda705ab2b60fef42ac905dfa44 (patch) | |
tree | 089b762417ab1dca3af632eee34c92dc7cbbafdf /libavfilter/af_pan.c | |
parent | 560b224f53fd553262790216d18c64665ebf436d (diff) | |
download | ffmpeg-a44b510d5615dcda705ab2b60fef42ac905dfa44.tar.gz |
af_pan: use libswr for rematrixing.
Diffstat (limited to 'libavfilter/af_pan.c')
-rw-r--r-- | libavfilter/af_pan.c | 71 |
1 files changed, 24 insertions, 47 deletions
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(); |