[vlc-commits] aout: aout_FiltersNew() can now remap channels

Thomas Guillem git at videolan.org
Thu Jul 13 17:19:21 CEST 2017


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Thu Jul 13 11:43:16 2017 +0200| [beb248a3f2453a586b78735df014c983857de604] | committer: Thomas Guillem

aout: aout_FiltersNew() can now remap channels

Add the possibility to pass an array of chan orders to the aout_FiltersNew
function.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=beb248a3f2453a586b78735df014c983857de604
---

 include/vlc_aout.h                   | 38 ++++++++++++++++--
 modules/stream_out/transcode/audio.c |  2 +-
 src/audio_output/dec.c               |  4 +-
 src/audio_output/filters.c           | 74 +++++++++++++++++++++++++++++++-----
 4 files changed, 103 insertions(+), 15 deletions(-)

diff --git a/include/vlc_aout.h b/include/vlc_aout.h
index 6045652b43..74ae07c7a7 100644
--- a/include/vlc_aout.h
+++ b/include/vlc_aout.h
@@ -23,6 +23,8 @@
 #ifndef VLC_AOUT_H
 #define VLC_AOUT_H 1
 
+#include <assert.h>
+
 /**
  * \defgroup audio_output Audio output
  * \ingroup output
@@ -175,6 +177,35 @@ struct audio_output
     } event;
 };
 
+typedef enum
+{
+    AOUT_CHANIDX_DISABLE = -1,
+    AOUT_CHANIDX_LEFT,
+    AOUT_CHANIDX_RIGHT,
+    AOUT_CHANIDX_MIDDLELEFT,
+    AOUT_CHANIDX_MIDDLERIGHT,
+    AOUT_CHANIDX_REARLEFT,
+    AOUT_CHANIDX_REARRIGHT,
+    AOUT_CHANIDX_REARCENTER,
+    AOUT_CHANIDX_CENTER,
+    AOUT_CHANIDX_LFE,
+    AOUT_CHANIDX_MAX
+} vlc_chan_order_idx_t;
+
+static_assert(AOUT_CHANIDX_MAX == AOUT_CHAN_MAX, "channel count mismatch");
+
+#define AOUT_CHAN_REMAP_INIT { \
+    AOUT_CHANIDX_LEFT,  \
+    AOUT_CHANIDX_RIGHT, \
+    AOUT_CHANIDX_MIDDLELEFT, \
+    AOUT_CHANIDX_MIDDLERIGHT, \
+    AOUT_CHANIDX_REARLEFT, \
+    AOUT_CHANIDX_REARRIGHT, \
+    AOUT_CHANIDX_REARCENTER, \
+    AOUT_CHANIDX_CENTER, \
+    AOUT_CHANIDX_LFE, \
+}
+
 /**
  * It describes the audio channel order VLC expect.
  */
@@ -323,9 +354,10 @@ typedef struct aout_request_vout aout_request_vout_t;
 VLC_API aout_filters_t *aout_FiltersNew(vlc_object_t *,
                                         const audio_sample_format_t *,
                                         const audio_sample_format_t *,
-                                        const aout_request_vout_t *) VLC_USED;
-#define aout_FiltersNew(o,inf,outf,rv) \
-        aout_FiltersNew(VLC_OBJECT(o),inf,outf,rv)
+                                        const aout_request_vout_t *,
+                                        const int *remap) VLC_USED;
+#define aout_FiltersNew(o,inf,outf,rv,remap) \
+        aout_FiltersNew(VLC_OBJECT(o),inf,outf,rv,remap)
 VLC_API void aout_FiltersDelete(vlc_object_t *, aout_filters_t *);
 #define aout_FiltersDelete(o,f) \
         aout_FiltersDelete(VLC_OBJECT(o),f)
diff --git a/modules/stream_out/transcode/audio.c b/modules/stream_out/transcode/audio.c
index 6279a77fa8..9a2357020a 100644
--- a/modules/stream_out/transcode/audio.c
+++ b/modules/stream_out/transcode/audio.c
@@ -71,7 +71,7 @@ static int transcode_audio_initialize_filters( sout_stream_t *p_stream, sout_str
     if( p_sys->psz_af )
         var_SetString( p_stream, "audio-filter", p_sys->psz_af );
     id->p_af_chain = aout_FiltersNew( p_stream, fmt_last,
-                                      &id->p_encoder->fmt_in.audio, NULL );
+                                      &id->p_encoder->fmt_in.audio, NULL, NULL );
     var_Destroy( p_stream, "audio-filter" );
     var_Destroy( p_stream, "audio-time-stretch" );
     if( id->p_af_chain == NULL )
diff --git a/src/audio_output/dec.c b/src/audio_output/dec.c
index d50a656d35..a22f57c333 100644
--- a/src/audio_output/dec.c
+++ b/src/audio_output/dec.c
@@ -95,7 +95,7 @@ int aout_DecNew( audio_output_t *p_aout,
 
     /* Create the audio filtering "input" pipeline */
     owner->filters = aout_FiltersNew (p_aout, p_format, &owner->mixer_format,
-                                      &owner->request_vout);
+                                      &owner->request_vout, NULL);
     if (owner->filters == NULL)
     {
         aout_OutputDelete (p_aout);
@@ -166,7 +166,7 @@ static int aout_CheckReady (audio_output_t *aout)
         {
             owner->filters = aout_FiltersNew (aout, &owner->input_format,
                                               &owner->mixer_format,
-                                              &owner->request_vout);
+                                              &owner->request_vout, NULL);
             if (owner->filters == NULL)
             {
                 aout_OutputDelete (aout);
diff --git a/src/audio_output/filters.c b/src/audio_output/filters.c
index 5e2547dcbc..3f4ac4e073 100644
--- a/src/audio_output/filters.c
+++ b/src/audio_output/filters.c
@@ -46,13 +46,14 @@ static filter_t *CreateFilter (vlc_object_t *obj, const char *type,
                                const char *name, filter_owner_sys_t *owner,
                                const audio_sample_format_t *infmt,
                                const audio_sample_format_t *outfmt,
-                               bool const_fmt)
+                               config_chain_t *cfg, bool const_fmt)
 {
     filter_t *filter = vlc_custom_create (obj, sizeof (*filter), type);
     if (unlikely(filter == NULL))
         return NULL;
 
     filter->owner.sys = owner;
+    filter->p_cfg = cfg;
     filter->fmt_in.audio = *infmt;
     filter->fmt_in.i_codec = infmt->i_format;
     filter->fmt_out.audio = *outfmt;
@@ -92,7 +93,8 @@ static filter_t *FindConverter (vlc_object_t *obj,
                                 const audio_sample_format_t *infmt,
                                 const audio_sample_format_t *outfmt)
 {
-    return CreateFilter (obj, "audio converter", NULL, NULL, infmt, outfmt, true);
+    return CreateFilter (obj, "audio converter", NULL, NULL, infmt, outfmt,
+                         NULL, true);
 }
 
 static filter_t *FindResampler (vlc_object_t *obj,
@@ -100,7 +102,7 @@ static filter_t *FindResampler (vlc_object_t *obj,
                                 const audio_sample_format_t *outfmt)
 {
     return CreateFilter (obj, "audio resampler", "$audio-resampler", NULL,
-                         infmt, outfmt, true);
+                         infmt, outfmt, NULL, true);
 }
 
 /**
@@ -373,7 +375,8 @@ vout_thread_t *aout_filter_RequestVout (filter_t *filter, vout_thread_t *vout,
 static int AppendFilter(vlc_object_t *obj, const char *type, const char *name,
                         aout_filters_t *restrict filters, const void *owner,
                         audio_sample_format_t *restrict infmt,
-                        const audio_sample_format_t *restrict outfmt)
+                        const audio_sample_format_t *restrict outfmt,
+                        config_chain_t *cfg)
 {
     const unsigned max = sizeof (filters->tab) / sizeof (filters->tab[0]);
     if (filters->count >= max)
@@ -383,7 +386,7 @@ static int AppendFilter(vlc_object_t *obj, const char *type, const char *name,
     }
 
     filter_t *filter = CreateFilter (obj, type, name,
-                                     (void *)owner, infmt, outfmt, false);
+                                     (void *)owner, infmt, outfmt, cfg, false);
     if (filter == NULL)
     {
         msg_Err (obj, "cannot add user %s \"%s\" (skipped)", type, name);
@@ -407,6 +410,52 @@ static int AppendFilter(vlc_object_t *obj, const char *type, const char *name,
     return 0;
 }
 
+static int AppendRemapFilter(vlc_object_t *obj, aout_filters_t *restrict filters,
+                             audio_sample_format_t *restrict infmt,
+                             const audio_sample_format_t *restrict outfmt,
+                             const int *wg4_remap)
+{
+    char *name;
+    config_chain_t *cfg;
+
+    /* The remap audio filter use a different order than wg4 */
+    static const uint8_t wg4_to_remap[] = { 0, 2, 6, 7, 3, 5, 4, 1, 8 };
+    int remap[AOUT_CHAN_MAX];
+    bool needed = false;
+    for (int i = 0; i < AOUT_CHAN_MAX; ++i)
+    {
+        if (wg4_remap[i] != i)
+            needed = true;
+        remap[i] = wg4_remap[i] >= 0 ? wg4_to_remap[wg4_remap[i]] : -1;
+    }
+    if (!needed)
+        return 0;
+
+    char *str;
+    int ret = asprintf(&str, "remap{channel-left=%d,channel-right=%d,"
+                       "channel-middleleft=%d,channel-middleright=%d,"
+                       "channel-rearleft=%d,channel-rearright=%d,"
+                       "channel-rearcenter=%d,channel-center=%d,"
+                       "channel-lfe=%d,normalize=false}",
+                       remap[0], remap[1], remap[2], remap[3], remap[4],
+                       remap[5], remap[6], remap[7], remap[8]);
+    if (ret == -1)
+        return -1;
+
+    free(config_ChainCreate(&name, &cfg, str));
+    if (name != NULL && cfg != NULL)
+        ret = AppendFilter(obj, "audio filter", name, filters,
+                           NULL, infmt, outfmt, cfg);
+    else
+        ret = -1;
+
+    free(str);
+    free(name);
+    if (cfg)
+        config_ChainDestroy(cfg);
+    return ret;
+}
+
 #undef aout_FiltersNew
 /**
  * Sets a chain of audio filters up.
@@ -414,6 +463,9 @@ static int AppendFilter(vlc_object_t *obj, const char *type, const char *name,
  * \param infmt chain input format [IN]
  * \param outfmt chain output format [IN]
  * \param request_vout visualization video output request callback
+ * \param remap a const array of size AOUT_CHAN_MAX or NULL. If not NULL, a
+ * remap audio filter will be inserted to remap channels according to the
+ * array. The array is in the WG4 order.
  * \return a filters chain or NULL on failure
  *
  * \note
@@ -425,7 +477,8 @@ static int AppendFilter(vlc_object_t *obj, const char *type, const char *name,
 aout_filters_t *aout_FiltersNew (vlc_object_t *obj,
                                  const audio_sample_format_t *restrict infmt,
                                  const audio_sample_format_t *restrict outfmt,
-                                 const aout_request_vout_t *request_vout)
+                                 const aout_request_vout_t *request_vout,
+                                 const int *remap)
 {
     aout_filters_t *filters = malloc (sizeof (*filters));
     if (unlikely(filters == NULL))
@@ -492,10 +545,13 @@ aout_filters_t *aout_FiltersNew (vlc_object_t *obj,
     if (var_InheritBool (obj, "audio-time-stretch"))
     {
         if (AppendFilter(obj, "audio filter", "scaletempo",
-                         filters, NULL, &input_format, &output_format) == 0)
+                         filters, NULL, &input_format, &output_format, NULL) == 0)
             filters->rate_filter = filters->tab[filters->count - 1];
     }
 
+    if (remap != NULL)
+        AppendRemapFilter(obj, filters, &input_format, &output_format, remap);
+
     /* Now add user filters */
     char *str = var_InheritString (obj, "audio-filter");
     if (str != NULL)
@@ -504,7 +560,7 @@ aout_filters_t *aout_FiltersNew (vlc_object_t *obj,
         while ((name = strsep (&p, " :")) != NULL)
         {
             AppendFilter(obj, "audio filter", name, filters,
-                         NULL, &input_format, &output_format);
+                         NULL, &input_format, &output_format, NULL);
         }
         free (str);
     }
@@ -514,7 +570,7 @@ aout_filters_t *aout_FiltersNew (vlc_object_t *obj,
         char *visual = var_InheritString (obj, "audio-visual");
         if (visual != NULL && strcasecmp (visual, "none"))
             AppendFilter(obj, "visualization", visual, filters,
-                         request_vout, &input_format, &output_format);
+                         request_vout, &input_format, &output_format, NULL);
         free (visual);
     }
 



More information about the vlc-commits mailing list