[vlc-commits] trivial_mixer: select conversion in Create(), not DoWork()

Rémi Denis-Courmont git at videolan.org
Sun Nov 2 11:10:45 CET 2014


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Nov  2 10:52:19 2014 +0200| [1047340ebc8f59895d7ad8747f7ec48528a31f64] | committer: Rémi Denis-Courmont

trivial_mixer: select conversion in Create(), not DoWork()

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

 modules/audio_filter/channel_mixer/trivial.c |  152 ++++++++++++++++++--------
 1 file changed, 105 insertions(+), 47 deletions(-)

diff --git a/modules/audio_filter/channel_mixer/trivial.c b/modules/audio_filter/channel_mixer/trivial.c
index 14823cb..417de8f 100644
--- a/modules/audio_filter/channel_mixer/trivial.c
+++ b/modules/audio_filter/channel_mixer/trivial.c
@@ -29,6 +29,8 @@
 # include "config.h"
 #endif
 
+#include <assert.h>
+
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 #include <vlc_aout.h>
@@ -44,6 +46,8 @@ vlc_module_begin ()
     set_callbacks( Create, NULL )
 vlc_module_end ()
 
+typedef void (*mix_func_t)(float *, const float *, size_t, unsigned, unsigned);
+
 /**
  * Trivially down-mixes or up-mixes a buffer
  */
@@ -60,6 +64,80 @@ static void SparseCopy( float *p_dest, const float *p_src, size_t i_len,
     }
 }
 
+static void CopyLeft( float *p_dest, const float *p_src, size_t i_len,
+                      unsigned i_output_stride, unsigned i_input_stride )
+{
+    assert( i_output_stride == 2 );
+    assert( i_input_stride == 2 );
+
+    for( unsigned i = 0; i < i_len; i++ )
+    {
+        *(p_dest++) = *p_src;
+        *(p_dest++) = *p_src;
+        p_src += 2;
+    }
+}
+
+static void CopyRight( float *p_dest, const float *p_src, size_t i_len,
+                        unsigned i_output_stride, unsigned i_input_stride )
+{
+    assert( i_output_stride == 2 );
+    assert( i_input_stride == 2 );
+
+    for( unsigned i = 0; i < i_len; i++ )
+    {
+        p_src++;
+        *(p_dest++) = *p_src;
+        *(p_dest++) = *p_src;
+        p_src++;
+    }
+}
+
+static void ExtractLeft( float *p_dest, const float *p_src, size_t i_len,
+                         unsigned i_output_stride, unsigned i_input_stride )
+{
+    assert( i_output_stride == 1 );
+    assert( i_input_stride == 2 );
+
+    for( unsigned i = 0; i < i_len; i++ )
+    {
+        *(p_dest++) = *p_src;
+        p_src += 2;
+    }
+}
+
+static void ExtractRight( float *p_dest, const float *p_src, size_t i_len,
+                          unsigned i_output_stride, unsigned i_input_stride )
+{
+    assert( i_output_stride == 1 );
+    assert( i_input_stride == 2 );
+
+    for( unsigned i = 0; i < i_len; i++ )
+    {
+        p_src++;
+        *(p_dest++) = *(p_src++);
+    }
+}
+
+static void ReverseStereo( float *p_dest, const float *p_src, size_t i_len,
+                           unsigned i_output_stride, unsigned i_input_stride )
+{
+    assert( i_output_stride == 2 );
+    assert( i_input_stride == 2 );
+
+    /* Reverse-stereo mode */
+    for( unsigned i = 0; i < i_len; i++ )
+    {
+        float i_tmp = p_src[0];
+
+        p_dest[0] = p_src[1];
+        p_dest[1] = i_tmp;
+
+        p_dest += 2;
+        p_src += 2;
+    }
+}
+
 /**
  * Mixes a buffer
  */
@@ -96,53 +174,11 @@ static block_t *DoWork( filter_t *p_filter, block_t *p_in_buf )
     b_dualmono2stereo &= (p_filter->fmt_out.audio.i_physical_channels & ( AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT ));
     b_dualmono2stereo &= ((p_filter->fmt_out.audio.i_physical_channels & AOUT_CHAN_PHYSMASK) != (p_filter->fmt_in.audio.i_physical_channels & AOUT_CHAN_PHYSMASK));
 
-    if( likely( !b_reverse_stereo && ! b_dualmono2stereo ) )
-    {
-        SparseCopy( p_dest, p_src, p_in_buf->i_nb_samples, i_output_nb,
-                    i_input_nb );
-    }
-    /* Special case from dual mono to stereo */
-    else if( b_dualmono2stereo )
-    {
-        /* This is a bit special. */
-        if( !(p_filter->fmt_out.audio.i_original_channels & AOUT_CHAN_LEFT) )
-        {
-            p_src++;
-        }
-        if( p_filter->fmt_out.audio.i_physical_channels == AOUT_CHAN_CENTER )
-        {   /* Mono mode */
-            for( unsigned i = 0; i < p_in_buf->i_nb_samples; i++ )
-            {
-                *p_dest = *p_src;
-                p_dest++;
-                p_src += 2;
-            }
-        }
-        else
-        {   /* Fake-stereo mode */
-            for( unsigned i = 0; i < p_in_buf->i_nb_samples; i++ )
-            {
-                *p_dest = *p_src;
-                p_dest++;
-                *p_dest = *p_src;
-                p_dest++;
-                p_src += 2;
-            }
-        }
-    }
-    else if( b_reverse_stereo )
-    {
-        /* Reverse-stereo mode */
-        for ( unsigned i = 0; i < p_in_buf->i_nb_samples; i++ )
-        {
-            float i_tmp = p_src[0];
-            p_dest[0] = p_src[1];
-            p_dest[1] = i_tmp;
-
-            p_dest += 2;
-            p_src += 2;
-        }
-    }
+    mix_func_t func = p_filter->p_sys;
+
+    if( func != NULL )
+        func( p_dest, p_src, p_in_buf->i_nb_samples, i_output_nb, i_input_nb );
+
 out:
     if( p_in_buf != p_out_buf )
         block_Release( p_in_buf );
@@ -155,6 +191,7 @@ out:
 static int Create( vlc_object_t *p_this )
 {
     filter_t *p_filter = (filter_t *)p_this;
+    mix_func_t func = NULL;
 
     if( p_filter->fmt_in.audio.i_format != p_filter->fmt_out.audio.i_format
      || p_filter->fmt_in.audio.i_rate != p_filter->fmt_out.audio.i_rate
@@ -165,8 +202,29 @@ static int Create( vlc_object_t *p_this )
      && p_filter->fmt_in.audio.i_original_channels
            == p_filter->fmt_out.audio.i_original_channels )
         return VLC_EGENERIC;
+
+    const bool b_reverse_stereo = p_filter->fmt_out.audio.i_original_channels & AOUT_CHAN_REVERSESTEREO;
+    bool b_dualmono2stereo = (p_filter->fmt_in.audio.i_original_channels & AOUT_CHAN_DUALMONO );
+    b_dualmono2stereo &= (p_filter->fmt_out.audio.i_physical_channels & ( AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT ));
+    b_dualmono2stereo &= ((p_filter->fmt_out.audio.i_physical_channels & AOUT_CHAN_PHYSMASK) != (p_filter->fmt_in.audio.i_physical_channels & AOUT_CHAN_PHYSMASK));
+
+    if( likely( !b_reverse_stereo && ! b_dualmono2stereo ) )
+        func = SparseCopy;
+    /* Special case from dual mono to stereo */
+    else if( b_dualmono2stereo )
+    {
+        bool right = !(p_filter->fmt_out.audio.i_original_channels & AOUT_CHAN_LEFT);
+        if( p_filter->fmt_out.audio.i_physical_channels == AOUT_CHAN_CENTER )
+            /* Mono mode */
+            func = right ? ExtractRight : ExtractLeft;
+        else
+            /* Fake-stereo mode */
+            func = right ? CopyRight : CopyLeft;
     }
+    else /* b_reverse_stereo */
+        func = ReverseStereo;
 
     p_filter->pf_audio_filter = DoWork;
+    p_filter->p_sys = (void *)func;
     return VLC_SUCCESS;
 }



More information about the vlc-commits mailing list