[FFmpeg-devel] [PATCH 2/2] af_pan: use libswr for rematrixing.

Nicolas George nicolas.george at normalesup.org
Thu Feb 16 13:11:59 CET 2012


Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
---
 libavfilter/af_pan.c |   71 +++++++++++++++++---------------------------------
 1 files changed, 24 insertions(+), 47 deletions(-)


There is quite a bit of cleanup necessary afterwards: not only reindent, but
eliminate the double/int union, the indirect function call, etc. But that
would be a nightmare of rebase conflicts to do it before the patch is in
final shape.


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();
-- 
1.7.9



More information about the ffmpeg-devel mailing list