[vlc-devel] [PATCH] jack: don't deactivate/activate client in Flush()

Tristan Matthews le.businessman at gmail.com
Thu May 2 15:36:36 CEST 2013


Instead, protect the resetting of the ringbuffer with an atomic
flag, to avoid resetting while its being read by the Process()
thread. Fixes #8551
---
 modules/audio_output/jack.c | 72 +++++++++++----------------------------------
 1 file changed, 17 insertions(+), 55 deletions(-)

diff --git a/modules/audio_output/jack.c b/modules/audio_output/jack.c
index 4571394..552cc52 100644
--- a/modules/audio_output/jack.c
+++ b/modules/audio_output/jack.c
@@ -37,6 +37,7 @@
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 #include <vlc_aout.h>
+#include <vlc_atomic.h>
 
 #include <jack/jack.h>
 #include <jack/ringbuffer.h>
@@ -61,6 +62,7 @@ struct aout_sys_t
     float soft_gain;
     bool soft_mute;
     mtime_t paused; /**< Time when (last) paused */
+    vlc_atomic_t reset_safe;
 };
 
 /*****************************************************************************
@@ -117,6 +119,7 @@ static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt )
 
     p_sys->latency = 0;
     p_sys->paused = VLC_TS_INVALID;
+    vlc_atomic_set( &p_sys->reset_safe, true );
 
     /* Connect to the JACK server */
     snprintf( psz_name, sizeof(psz_name), "vlc_%d", getpid());
@@ -175,6 +178,12 @@ static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt )
         goto error_out;
     }
 
+    if( jack_ringbuffer_mlock( p_sys->p_jack_ringbuffer ))
+    {
+        msg_Err( p_aout, "failed to lock JACK ringbuffer in memory" );
+        status = VLC_EGENERIC;
+    }
+
     /* Create the output ports */
     for( i = 0; i < p_sys->i_channels; i++ )
     {
@@ -307,8 +316,6 @@ static void Flush(audio_output_t *p_aout, bool wait)
 {
     struct aout_sys_t * p_sys = p_aout->sys;
     jack_ringbuffer_t *rb = p_sys->p_jack_ringbuffer;
-    jack_client_t *client = p_sys->p_jack_client;
-    int i_error;
 
     /* Sleep if wait was requested */
     if( wait )
@@ -318,60 +325,9 @@ static void Flush(audio_output_t *p_aout, bool wait)
             msleep(delay);
     }
 
-    /* FIXME: maybe the ringbuffer_reset should just be protected by signalling
-     * with atomic variables?
-     * Here we save and restore connections, otherwise we'd lose the connections
-     * every seek because of the deactivate/activate */
-
-    /* Save connections */
-    const char **connections_list[p_sys->i_channels];
-
-    for( size_t i = 0; i < p_sys->i_channels; i++ )
-    {
-        const char **port_connections = jack_port_get_all_connections( client,
-                p_sys->p_jack_ports[i] );
-        connections_list[i] = port_connections;
-    }
-
-    /* Suspend audio processing */
-    i_error = jack_deactivate( p_sys->p_jack_client );
-    if( i_error )
-    {
-        msg_Err( p_aout, "failed to deactivate JACK client (error %d)",
-                i_error );
-        return;
-    }
-
     /* reset ringbuffer read and write pointers */
-    jack_ringbuffer_reset(rb);
-
-    /* Resume audio processing */
-    i_error = jack_activate( p_sys->p_jack_client );
-    if( i_error )
-    {
-        msg_Err( p_aout, "failed to activate JACK client (error %d)", i_error );
-        return;
-    }
-
-    /* Restore connections */
-    for( size_t i = 0; i < p_sys->i_channels; i++ )
-    {
-        const char **port_connections = connections_list[i];
-        const char *psz_out = jack_port_name( p_sys->p_jack_ports[i] );
-        for (const char **psz_in = port_connections; psz_in && *psz_in;
-                psz_in++)
-        {
-            i_error = jack_connect( client, psz_out, *psz_in );
-            if( i_error )
-            {
-                msg_Err( p_aout, "failed to connect ports %s and %s (error %d)",
-                        psz_out, *psz_in, i_error );
-            }
-        }
-
-        if( port_connections )
-            jack_free(port_connections);
-    }
+    if( vlc_atomic_get( &p_sys->reset_safe ) )
+        jack_ringbuffer_reset(rb);
 }
 
 static int TimeGet(audio_output_t *p_aout, mtime_t *delay)
@@ -401,7 +357,10 @@ int Process( jack_nframes_t i_frames, void *p_arg )
     /* Get the next audio data buffer unless paused */
 
     if( p_sys->paused == VLC_TS_INVALID )
+    {
         frames_from_rb = i_frames;
+        vlc_atomic_set( &p_sys->reset_safe, false );
+    }
 
     /* Get the JACK buffers to write to */
     for( i = 0; i < p_sys->i_channels; i++ )
@@ -421,6 +380,9 @@ int Process( jack_nframes_t i_frames, void *p_arg )
         }
     }
 
+    if( frames_from_rb )
+        vlc_atomic_set( &p_sys->reset_safe, true );
+
     /* Fill any remaining buffer with silence */
     frames_read = (bytes_read / sizeof(jack_sample_t)) / p_sys->i_channels;
     if( frames_read < i_frames )
-- 
1.8.1.2




More information about the vlc-devel mailing list