[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