audio_filter: only one module for all simple channel mixers
authorThomas Guillem <thomas@gllm.fr>
Thu, 27 Aug 2015 12:52:28 +0000 (14:52 +0200)
committerThomas Guillem <thomas@gllm.fr>
Thu, 27 Aug 2015 12:56:37 +0000 (14:56 +0200)
This fixes a bad conversion when doing 6_x to 2_0 using neon.

The neon channel mixer code is now used from the simple channel_mixer module.

modules/arm_neon/Makefile.am
modules/arm_neon/simple_channel_mixer.S
modules/arm_neon/simple_channel_mixer.c [deleted file]
modules/audio_filter/Makefile.am
modules/audio_filter/channel_mixer/simple.c
modules/audio_filter/channel_mixer/simple_neon.h [new file with mode: 0644]
po/POTFILES.in

index 4e73a4f..db81ec0 100644 (file)
@@ -1,11 +1,5 @@
 neondir = $(pluginsdir)/arm_neon
 
-libsimple_channel_mixer_neon_plugin_la_SOURCES = \
-       arm_neon/simple_channel_mixer.S \
-       arm_neon/simple_channel_mixer.c
-libsimple_channel_mixer_neon_plugin_la_CFLAGS = $(AM_CFLAGS)
-libsimple_channel_mixer_neon_plugin_LIBTOOLFLAGS = --tag=CC
-
 libchroma_yuv_neon_plugin_la_SOURCES = \
        arm_neon/deinterleave_chroma.S \
        arm_neon/i420_yuyv.S \
@@ -30,7 +24,6 @@ libyuv_rgb_neon_plugin_LIBTOOLFLAGS = --tag=CC
 
 if HAVE_NEON
 neon_LTLIBRARIES = \
-       libsimple_channel_mixer_neon_plugin.la \
        libchroma_yuv_neon_plugin.la \
        libvolume_neon_plugin.la \
        libyuv_rgb_neon_plugin.la
index dcc51ed..a94ae85 100644 (file)
@@ -34,9 +34,9 @@ coeff_7to2:
        .float 0.5
        .float 0.25
        .float 0.25
-       .global convert_7to2_neon_asm
-       .type   convert_7to2_neon_asm, %function
-convert_7to2_neon_asm:
+       .global convert_7_x_to_2_0_neon_asm
+       .type   convert_7_x_to_2_0_neon_asm, %function
+convert_7_x_to_2_0_neon_asm:
        push {r4,lr}
 
        adr COEFF, coeff_7to2
@@ -70,9 +70,9 @@ coeff_5to2:
        .float 0.5
        .float 0.33
        .float 0.33
-       .global convert_5to2_neon_asm
-       .type   convert_5to2_neon_asm, %function
-convert_5to2_neon_asm:
+       .global convert_5_x_to_2_0_neon_asm
+       .type   convert_5_x_to_2_0_neon_asm, %function
+convert_5_x_to_2_0_neon_asm:
        push {r4,lr}
 
        adr COEFF, coeff_5to2
@@ -100,9 +100,9 @@ convert_5to2_neon_asm:
 coeff_4to2:
        .float 0.5
        .float 0.5
-       .global convert_4to2_neon_asm
-       .type   convert_4to2_neon_asm, %function
-convert_4to2_neon_asm:
+       .global convert_4_0_to_2_0_neon_asm
+       .type   convert_4_0_to_2_0_neon_asm, %function
+convert_4_0_to_2_0_neon_asm:
        push {r4,lr}
 
        adr COEFF, coeff_4to2
@@ -124,9 +124,9 @@ convert_4to2_neon_asm:
 coeff_3to2:
        .float 0.5
        .float 0.5
-       .global convert_3to2_neon_asm
-       .type   convert_3to2_neon_asm, %function
-convert_3to2_neon_asm:
+       .global convert_3_x_to_2_0_neon_asm
+       .type   convert_3_x_to_2_0_neon_asm, %function
+convert_3_x_to_2_0_neon_asm:
        push {r4,lr}
 
        adr COEFF, coeff_3to2
@@ -154,9 +154,9 @@ coeff_7to1:
        .float 0.25
        .float 0.125
        .float 0.125
-       .global convert_7to1_neon_asm
-       .type   convert_7to1_neon_asm, %function
-convert_7to1_neon_asm:
+       .global convert_7_x_to_1_0_neon_asm
+       .type   convert_7_x_to_1_0_neon_asm, %function
+convert_7_x_to_1_0_neon_asm:
        push {r4,lr}
 
        adr COEFF, coeff_7to1
@@ -188,9 +188,9 @@ coeff_5to1:
        .float 0.25
        .float 0.16666667
        .float 0.16666667
-       .global convert_5to1_neon_asm
-       .type   convert_5to1_neon_asm, %function
-convert_5to1_neon_asm:
+       .global convert_5_x_to_1_0_neon_asm
+       .type   convert_5_x_to_1_0_neon_asm, %function
+convert_5_x_to_1_0_neon_asm:
        push {r4,lr}
 
        adr COEFF, coeff_5to1
@@ -219,9 +219,9 @@ coeff_7to4:
        .float 0.5
        .float 0.16666667
        .float 0.16666667
-       .global convert_7to4_neon_asm
-       .type   convert_7to4_neon_asm, %function
-convert_7to4_neon_asm:
+       .global convert_7_x_to_4_0_neon_asm
+       .type   convert_7_x_to_4_0_neon_asm, %function
+convert_7_x_to_4_0_neon_asm:
        push {r4,lr}
 
        adr COEFF, coeff_7to4
@@ -252,9 +252,9 @@ convert_7to4_neon_asm:
 coeff_5to4:
        .float 0.5
        .float 0.5
-       .global convert_5to4_neon_asm
-       .type   convert_5to4_neon_asm, %function
-convert_5to4_neon_asm:
+       .global convert_5_x_to_4_0_neon_asm
+       .type   convert_5_x_to_4_0_neon_asm, %function
+convert_5_x_to_4_0_neon_asm:
        push {r4,lr}
 
        adr COEFF, coeff_5to4
diff --git a/modules/arm_neon/simple_channel_mixer.c b/modules/arm_neon/simple_channel_mixer.c
deleted file mode 100644 (file)
index 8627415..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*****************************************************************************
- * simple_channel_mixer.c : simple channel mixer plug-in using NEON assembly
- *****************************************************************************
- * Copyright (C) 2002, 2004, 2006-2009, 2012 VLC authors and VideoLAN
- * $Id$
- *
- * Authors: Gildas Bazin <gbazin@videolan.org>
- *          David Geldreich <david.geldreich@free.fr>
- *          S├ębastien Toque
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <vlc_common.h>
-#include <vlc_plugin.h>
-#include <vlc_aout.h>
-#include <vlc_filter.h>
-#include <vlc_block.h>
-#include <vlc_cpu.h>
-#include <assert.h>
-
-/*****************************************************************************
- * Module descriptor
- *****************************************************************************/
-static int  OpenFilter( vlc_object_t * );
-
-vlc_module_begin ()
-    set_description( N_("Audio filter for simple channel mixing using NEON assembly") )
-    set_category( CAT_AUDIO )
-    set_subcategory( SUBCAT_AUDIO_MISC )
-    set_capability( "audio converter", 20 )
-    set_callbacks( OpenFilter, NULL )
-vlc_module_end ()
-
-#define FILTER_WRAPPER(in, out)                                                  \
-    void convert_##in##to##out##_neon_asm(float *dst, const float *src, int num, bool lfeChannel); \
-    static block_t *Filter_##in##to##out (filter_t *p_filter, block_t *p_block)  \
-    {                                                                            \
-        block_t *p_out;                                                          \
-        if (!FilterInit( p_filter, p_block, &p_out ))                            \
-            return NULL;                                                         \
-        const float *p_src = (const float *)p_block->p_buffer;                   \
-        float *p_dest = (float *)p_out->p_buffer;                                \
-        convert_##in##to##out##_neon_asm( p_dest, p_src, p_block->i_nb_samples,  \
-                  p_filter->fmt_in.audio.i_physical_channels & AOUT_CHAN_LFE );  \
-        block_Release( p_block );                                                \
-        return p_out;                                                            \
-    }
-
-#define TRY_FILTER(in, out)                                \
-    if ( b_input_##in && b_output_##out )                  \
-    {                                                      \
-        p_filter->pf_audio_filter = Filter_##in##to##out ; \
-        return VLC_SUCCESS;                                \
-    }
-
-/*****************************************************************************
- * Filter:
- *****************************************************************************/
-static bool FilterInit( filter_t *p_filter, block_t *p_block, block_t **pp_out )
-{
-    if( !p_block || !p_block->i_nb_samples )
-    {
-        if( p_block )
-            block_Release( p_block );
-        return false;
-    }
-
-    size_t i_out_size = p_block->i_nb_samples *
-        p_filter->fmt_out.audio.i_bitspersample *
-        p_filter->fmt_out.audio.i_channels / 8;
-
-    block_t *p_out = block_Alloc( i_out_size );
-    if( !p_out )
-    {
-        msg_Warn( p_filter, "can't get output buffer" );
-        block_Release( p_block );
-        return false;
-    }
-
-    p_out->i_nb_samples = p_block->i_nb_samples;
-    p_out->i_dts = p_block->i_dts;
-    p_out->i_pts = p_block->i_pts;
-    p_out->i_length = p_block->i_length;
-
-    int i_input_nb = aout_FormatNbChannels( &p_filter->fmt_in.audio );
-    int i_output_nb = aout_FormatNbChannels( &p_filter->fmt_out.audio );
-    p_out->i_buffer = p_block->i_buffer * i_output_nb / i_input_nb;
-
-    *pp_out = p_out;
-    return true;
-}
-
-FILTER_WRAPPER(7,2)
-FILTER_WRAPPER(5,2)
-FILTER_WRAPPER(4,2)
-FILTER_WRAPPER(3,2)
-FILTER_WRAPPER(7,1)
-FILTER_WRAPPER(5,1)
-FILTER_WRAPPER(7,4)
-FILTER_WRAPPER(5,4)
-
-/*****************************************************************************
- * OpenFilter:
- *****************************************************************************/
-static int OpenFilter( vlc_object_t *p_this )
-{
-    filter_t *p_filter = (filter_t *)p_this;
-
-    if (!vlc_CPU_ARM_NEON())
-        return VLC_EGENERIC;
-
-    audio_format_t fmt_in  = p_filter->fmt_in.audio;
-    audio_format_t fmt_out = p_filter->fmt_out.audio;
-
-    fmt_in.i_format = p_filter->fmt_in.i_codec;
-    fmt_out.i_format = p_filter->fmt_out.i_codec;
-
-    if( fmt_in.i_format != VLC_CODEC_FL32 ||
-        fmt_in.i_format != fmt_out.i_format ||
-        fmt_in.i_rate != fmt_out.i_rate )
-    {
-        return VLC_EGENERIC;
-    }
-
-    if( fmt_in.i_physical_channels == fmt_out.i_physical_channels &&
-        fmt_in.i_original_channels == fmt_out.i_original_channels )
-    {
-        return VLC_EGENERIC;
-    }
-
-    const bool b_input_7 = (fmt_in.i_physical_channels & ~AOUT_CHAN_LFE) == AOUT_CHANS_7_0;
-    const bool b_input_5 = ( (fmt_in.i_physical_channels & AOUT_CHANS_5_0) == AOUT_CHANS_5_0 ||
-                             (fmt_in.i_physical_channels & AOUT_CHANS_5_0_MIDDLE) == AOUT_CHANS_5_0_MIDDLE );
-    const bool b_input_4 =  (fmt_in.i_physical_channels & ~AOUT_CHAN_LFE) == AOUT_CHANS_4_CENTER_REAR;
-    const bool b_input_3 = (fmt_in.i_physical_channels & ~AOUT_CHAN_LFE) == AOUT_CHANS_3_0;
-
-    const bool b_output_1 = fmt_out.i_physical_channels == AOUT_CHAN_CENTER;
-    const bool b_output_2 = fmt_out.i_physical_channels == AOUT_CHANS_2_0;
-    const bool b_output_4 = fmt_out.i_physical_channels == AOUT_CHANS_4_0;
-
-    /* Only conversion to Mono, Stereo and 4.0 right now */
-    /* Only from 7/7.1/5/5.1/3/3.1/2.0
-     * XXX 5.X rear and middle are handled the same way */
-
-    TRY_FILTER(7,2)
-    TRY_FILTER(5,2)
-    TRY_FILTER(4,2)
-    TRY_FILTER(3,2)
-    TRY_FILTER(7,1)
-    TRY_FILTER(5,1)
-    TRY_FILTER(7,4)
-    TRY_FILTER(5,4)
-
-    return VLC_EGENERIC;
-}
index c7b866e..978edf8 100644 (file)
@@ -56,6 +56,9 @@ libtrivial_channel_mixer_plugin_la_SOURCES = \
        audio_filter/channel_mixer/trivial.c
 libsimple_channel_mixer_plugin_la_SOURCES = \
        audio_filter/channel_mixer/simple.c
+if HAVE_NEON
+libsimple_channel_mixer_plugin_la_SOURCES += arm_neon/simple_channel_mixer.S
+endif
 
 audio_filter_LTLIBRARIES += \
        libdolby_surround_decoder_plugin.la \
index f296e28..f825f98 100644 (file)
@@ -258,6 +258,12 @@ static void DoWork_6_1_to_5_x( filter_t * p_filter,  block_t * p_in_buf, block_t
     }
 }
 
+#if defined (__arm__)
+#include "simple_neon.h"
+#define GET_WORK(in, out) GET_WORK_##in##_to_##out##_neon()
+#else
+#define GET_WORK(in, out) DoWork_##in##_to_##out
+#endif
 
 /*****************************************************************************
  * OpenFilter:
@@ -300,43 +306,43 @@ static int OpenFilter( vlc_object_t *p_this )
     if( output == AOUT_CHAN_CENTER )
     {
         if( b_input_7_x )
-            do_work = DoWork_7_x_to_1_0;
+            do_work = GET_WORK(7_x,1_0);
         else if( b_input_5_x )
-            do_work = DoWork_5_x_to_1_0;
+            do_work = GET_WORK(5_x,1_0);
         else if( b_input_4_center_rear )
-            do_work = DoWork_4_0_to_1_0;
+            do_work = GET_WORK(4_0,1_0);
         else if( b_input_3_x )
-            do_work = DoWork_3_x_to_1_0;
+            do_work = GET_WORK(3_x,1_0);
         else
-            do_work = DoWork_2_x_to_1_0;
+            do_work = GET_WORK(2_x,1_0);
     }
     else if( output == AOUT_CHANS_2_0 )
     {
         if( b_input_7_x )
-            do_work = DoWork_7_x_to_2_0;
+            do_work = GET_WORK(7_x,2_0);
         else if( b_input_6_1 )
-            do_work = DoWork_6_1_to_2_0;
+            do_work = GET_WORK(6_1,2_0);
         else if( b_input_5_x )
-            do_work = DoWork_5_x_to_2_0;
+            do_work = GET_WORK(5_x,2_0);
         else if( b_input_4_center_rear )
-            do_work = DoWork_4_0_to_2_0;
+            do_work = GET_WORK(4_0,2_0);
         else if( b_input_3_x )
-            do_work = DoWork_3_x_to_2_0;
+            do_work = GET_WORK(3_x,2_0);
     }
     else if( output == AOUT_CHANS_4_0 )
     {
         if( b_input_7_x )
-            do_work = DoWork_7_x_to_4_0;
+            do_work = GET_WORK(7_x,4_0);
         else if( b_input_5_x )
-            do_work = DoWork_5_x_to_4_0;
+            do_work = GET_WORK(5_x,4_0);
     }
     else if( (output & ~AOUT_CHAN_LFE) == AOUT_CHANS_5_0 ||
              (output & ~AOUT_CHAN_LFE) == AOUT_CHANS_5_0_MIDDLE )
     {
         if( b_input_7_x )
-            do_work = DoWork_7_x_to_5_x;
+            do_work = GET_WORK(7_x,5_x);
         else if( b_input_6_1 )
-            do_work = DoWork_6_1_to_5_x;
+            do_work = GET_WORK(6_1,5_x);
     }
 
     if( do_work == NULL )
diff --git a/modules/audio_filter/channel_mixer/simple_neon.h b/modules/audio_filter/channel_mixer/simple_neon.h
new file mode 100644 (file)
index 0000000..2fe6075
--- /dev/null
@@ -0,0 +1,72 @@
+/*****************************************************************************
+ * simple_neon.h : simple channel mixer plug-in using NEON assembly
+ *****************************************************************************
+ * Copyright (C) 2002, 2004, 2006-2009, 2012, 2015 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Gildas Bazin <gbazin@videolan.org>
+ *          David Geldreich <david.geldreich@free.fr>
+ *          S├ębastien Toque
+ *          Thomas Guillem <thomas@gllm.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <vlc_cpu.h>
+
+/* Only conversion to Mono, Stereo and 4.0 right now */
+/* Only from 7/7.1/5/5.1/3/3.1/2.0
+ * XXX 5.X rear and middle are handled the same way */
+
+#define NEON_WRAPPER(in, out)                                                    \
+    void convert_##in##_to_##out##_neon_asm(float *dst, const float *src, int num, bool lfeChannel); \
+    static inline void DoWork_##in##_to_##out##_neon( filter_t *p_filter, block_t *p_in_buf, block_t *p_out_buf )  \
+    {                                                                            \
+        const float *p_src = (const float *)p_in_buf->p_buffer;                  \
+        float *p_dest = (float *)p_out_buf->p_buffer;                            \
+        convert_##in##_to_##out##_neon_asm( p_dest, p_src, p_in_buf->i_nb_samples, \
+                  p_filter->fmt_in.audio.i_physical_channels & AOUT_CHAN_LFE );  \
+    } \
+    static inline void (*GET_WORK_##in##_to_##out##_neon())(filter_t*, block_t*, block_t*) \
+    { \
+        return vlc_CPU_ARM_NEON() ? DoWork_##in##_to_##out##_neon : DoWork_##in##_to_##out; \
+    }
+
+NEON_WRAPPER(7_x,2_0)
+NEON_WRAPPER(5_x,2_0)
+NEON_WRAPPER(4_0,2_0)
+NEON_WRAPPER(3_x,2_0)
+NEON_WRAPPER(7_x,1_0)
+NEON_WRAPPER(5_x,1_0)
+NEON_WRAPPER(7_x,4_0)
+NEON_WRAPPER(5_x,4_0)
+
+/* TODO: the following conversions are not handled in NEON */
+
+#define C_WRAPPER(in, out) \
+    static inline void (*GET_WORK_##in##_to_##out##_neon())(filter_t*, block_t*, block_t*) \
+    { \
+        return DoWork_##in##_to_##out; \
+    }
+
+C_WRAPPER(4_0,1_0)
+C_WRAPPER(3_x,1_0)
+C_WRAPPER(2_x,1_0)
+C_WRAPPER(6_1,2_0)
+C_WRAPPER(7_x,5_x)
+C_WRAPPER(6_1,5_x)
index 223078d..aa2cd3a 100644 (file)
@@ -279,7 +279,6 @@ modules/access/vnc.c
 modules/access/wasapi.c
 modules/access/zip/zipstream.c
 modules/arm_neon/chroma_yuv.c
-modules/arm_neon/simple_channel_mixer.c
 modules/arm_neon/volume.c
 modules/arm_neon/yuv_rgb.c
 modules/audio_filter/audiobargraph_a.c