The audio output locking rule seems very vague. Moreover there could be some cross lock issues.
#ifndef __LIBVLC_AOUT_INTERNAL_H
# define __LIBVLC_AOUT_INTERNAL_H 1
+#include <assert.h>
+
#if defined( __APPLE__ ) || defined( SYS_BSD )
#undef HAVE_ALLOCA
#endif
/* Helpers */
+static inline void aout_lock_mixer( aout_instance_t *p_aout )
+{
+ vlc_mutex_lock( &p_aout->mixer_lock );
+}
+
+static inline void aout_unlock_mixer( aout_instance_t *p_aout )
+{
+ vlc_mutex_unlock( &p_aout->mixer_lock );
+}
+
+static inline void aout_lock_input_fifos( aout_instance_t *p_aout )
+{
+ vlc_mutex_lock( &p_aout->input_fifos_lock );
+}
+
+static inline void aout_unlock_input_fifos( aout_instance_t *p_aout )
+{
+ vlc_mutex_unlock( &p_aout->input_fifos_lock );
+}
+
+static inline void aout_lock_output_fifo( aout_instance_t *p_aout )
+{
+ vlc_mutex_lock( &p_aout->output_fifo_lock );
+}
+
+static inline void aout_unlock_output_fifo( aout_instance_t *p_aout )
+{
+ vlc_mutex_unlock( &p_aout->output_fifo_lock );
+}
+
+static inline void aout_lock_input( aout_instance_t *p_aout, aout_input_t * p_input )
+{
+ (void)p_aout;
+ vlc_mutex_lock( &p_input->lock );
+}
+
+static inline void aout_unlock_input( aout_instance_t *p_aout, aout_input_t * p_input )
+{
+ (void)p_aout;
+ vlc_mutex_unlock( &p_input->lock );
+}
+
+
/**
* This function will safely mark aout input to be restarted as soon as
* possible to take configuration changes into account */
static inline void AoutInputsMarkToRestart( aout_instance_t *p_aout )
{
int i;
- vlc_mutex_lock( &p_aout->mixer_lock );
+ aout_lock_mixer( p_aout );
for( i = 0; i < p_aout->i_nb_inputs; i++ )
p_aout->pp_inputs[i]->b_restart = true;
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_mixer( p_aout );
}
/* This function will add or remove a a module from a string list (comma
/* We can only be called by the decoder, so no need to lock
* p_input->lock. */
- vlc_mutex_lock( &p_aout->mixer_lock );
+ aout_lock_mixer( p_aout );
if ( p_aout->i_nb_inputs >= AOUT_MAX_INPUTS )
{
if( p_replay_gain )
p_input->replay_gain = *p_replay_gain;
- vlc_mutex_lock( &p_aout->input_fifos_lock );
+ aout_lock_input_fifos( p_aout );
p_aout->pp_inputs[p_aout->i_nb_inputs] = p_input;
p_aout->i_nb_inputs++;
{
for ( i = 0; i < p_aout->i_nb_inputs - 1; i++ )
{
- vlc_mutex_lock( &p_aout->pp_inputs[i]->lock );
+ aout_lock_input( p_aout, p_aout->pp_inputs[i] );
aout_InputDelete( p_aout, p_aout->pp_inputs[i] );
- vlc_mutex_unlock( &p_aout->pp_inputs[i]->lock );
+ aout_unlock_input( p_aout, p_aout->pp_inputs[i] );
}
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_input_fifos( p_aout );
+ aout_unlock_mixer( p_aout );
return p_input;
}
/* Create other input streams. */
for ( i = 0; i < p_aout->i_nb_inputs - 1; i++ )
{
- vlc_mutex_lock( &p_aout->pp_inputs[i]->lock );
+ aout_lock_input( p_aout, p_aout->pp_inputs[i] );
aout_InputDelete( p_aout, p_aout->pp_inputs[i] );
aout_InputNew( p_aout, p_aout->pp_inputs[i] );
- vlc_mutex_unlock( &p_aout->pp_inputs[i]->lock );
+ aout_unlock_input( p_aout, p_aout->pp_inputs[i] );
}
}
else
if ( aout_MixerNew( p_aout ) == -1 )
{
aout_OutputDelete( p_aout );
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
+ aout_unlock_input_fifos( p_aout );
goto error;
}
aout_InputNew( p_aout, p_input );
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
+ aout_unlock_input_fifos( p_aout );
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_mixer( p_aout );
p_input->i_desync = var_CreateGetInteger( p_this, "audio-desync" ) * 1000;
p_input_thread = (input_thread_t *)vlc_object_find( p_this,
return p_input;
error:
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_mixer( p_aout );
return NULL;
}
/* This function can only be called by the decoder itself, so no need
* to lock p_input->lock. */
- vlc_mutex_lock( &p_aout->mixer_lock );
+ aout_lock_mixer( p_aout );
for ( i_input = 0; i_input < p_aout->i_nb_inputs; i_input++ )
{
if ( i_input == p_aout->i_nb_inputs )
{
msg_Err( p_aout, "cannot find an input to delete" );
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_mixer( p_aout );
return -1;
}
}
}
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_mixer( p_aout );
return 0;
}
aout_buffer_t * p_buffer;
mtime_t duration;
- vlc_mutex_lock( &p_input->lock );
+ aout_lock_input( NULL, p_input );
if ( p_input->b_error )
{
- vlc_mutex_unlock( &p_input->lock );
+ aout_unlock_input( NULL, p_input );
return NULL;
}
/* Suppose the decoder doesn't have more than one buffered buffer */
p_input->b_changed = 0;
- vlc_mutex_unlock( &p_input->lock );
+ aout_unlock_input( NULL, p_input );
if( p_buffer == NULL )
return NULL;
+ (mtime_t)p_buffer->i_nb_samples * 1000000
/ p_input->input.i_rate;
- vlc_mutex_lock( &p_input->lock );
+ aout_lock_input( p_aout, p_input );
if ( p_input->b_error )
{
- vlc_mutex_unlock( &p_input->lock );
+ aout_unlock_input( p_aout, p_input );
aout_BufferFree( p_buffer );
return -1;
}
/* If the buffer is too early, wait a while. */
mwait( p_buffer->start_date - AOUT_MAX_PREPARE_TIME );
- if ( aout_InputPlay( p_aout, p_input, p_buffer, i_input_rate ) == -1 )
- {
- vlc_mutex_unlock( &p_input->lock );
- return -1;
- }
+ int ret = aout_InputPlay( p_aout, p_input, p_buffer, i_input_rate );
+
+ aout_unlock_input( p_aout, p_input );
- vlc_mutex_unlock( &p_input->lock );
+ if ( ret == -1 ) return -1;
/* Run the mixer if it is able to run. */
- vlc_mutex_lock( &p_aout->mixer_lock );
+ aout_lock_mixer( p_aout );
aout_MixerRun( p_aout );
if( p_input->p_input_thread )
{
1, NULL );
vlc_mutex_unlock( &p_input->p_input_thread->p->counters.counters_lock);
}
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_mixer( p_aout );
return 0;
}
aout_fifo_t fifo, dummy_fifo;
uint8_t *p_first_byte_to_mix;
- vlc_mutex_lock( &p_aout->mixer_lock );
- vlc_mutex_lock( &p_aout->input_fifos_lock );
+ aout_lock_mixer( p_aout );
+ aout_lock_input_fifos( p_aout );
/* A little trick to avoid loosing our input fifo */
aout_FifoInit( p_aout, &dummy_fifo, p_aout->mixer.mixer.i_rate );
p_input->p_first_byte_to_mix = p_first_byte_to_mix;
p_input->fifo = fifo;
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_input_fifos( p_aout );
+ aout_unlock_mixer( p_aout );
}
if( i_input_rate != INPUT_RATE_DEFAULT && p_input->p_playback_rate_filter == NULL )
/* We don't care if someone changes the start date behind our back after
* this. We'll deal with that when pushing the buffer, and compensate
* with the next incoming buffer. */
- vlc_mutex_lock( &p_aout->input_fifos_lock );
+ aout_lock_input_fifos( p_aout );
start_date = aout_FifoNextStart( p_aout, &p_input->fifo );
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
+ aout_unlock_input_fifos( p_aout );
if ( start_date != 0 && start_date < mdate() )
{
* happen :). */
msg_Warn( p_aout, "computed PTS is out of range (%"PRId64"), "
"clearing out", mdate() - start_date );
- vlc_mutex_lock( &p_aout->input_fifos_lock );
+ aout_lock_input_fifos( p_aout );
aout_FifoSet( p_aout, &p_input->fifo, 0 );
p_input->p_first_byte_to_mix = NULL;
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
+ aout_unlock_input_fifos( p_aout );
if ( p_input->i_resampling_type != AOUT_RESAMPLING_NONE )
msg_Warn( p_aout, "timing screwed, stopping resampling" );
inputResamplingStop( p_input );
{
msg_Warn( p_aout, "audio drift is too big (%"PRId64"), clearing out",
start_date - p_buffer->start_date );
- vlc_mutex_lock( &p_aout->input_fifos_lock );
+ aout_lock_input_fifos( p_aout );
aout_FifoSet( p_aout, &p_input->fifo, 0 );
p_input->p_first_byte_to_mix = NULL;
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
+ aout_unlock_input_fifos( p_aout );
if ( p_input->i_resampling_type != AOUT_RESAMPLING_NONE )
msg_Warn( p_aout, "timing screwed, stopping resampling" );
inputResamplingStop( p_input );
(p_buffer->end_date - p_buffer->start_date);
p_buffer->start_date = start_date;
- vlc_mutex_lock( &p_aout->input_fifos_lock );
+ aout_lock_input_fifos( p_aout );
aout_FifoPush( p_aout, &p_input->fifo, p_buffer );
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
+ aout_unlock_input_fifos( p_aout );
return 0;
}
aout_instance_t *p_aout = (aout_instance_t *)p_this;
int i;
- vlc_mutex_lock( &p_aout->mixer_lock );
+ aout_lock_mixer( p_aout );
for( i = 0; i < p_aout->i_nb_inputs; i++ )
ReplayGainSelect( p_aout, p_aout->pp_inputs[i] );
/* Restart the mixer (a trivial mixer may be in use) */
aout_MixerMultiplierSet( p_aout, p_aout->mixer.f_multiplier );
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_mixer( p_aout );
return VLC_SUCCESS;
}
return 0;
}
- vlc_mutex_lock( &p_aout->mixer_lock );
+ aout_lock_mixer( p_aout );
if ( !p_aout->mixer.b_error )
{
i_result = p_aout->output.pf_volume_get( p_aout, pi_volume );
{
*pi_volume = (audio_volume_t)config_GetInt( p_object, "volume" );
}
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_mixer( p_aout );
vlc_object_release( p_aout );
return i_result;
if ( p_aout == NULL ) return 0;
- vlc_mutex_lock( &p_aout->mixer_lock );
+ aout_lock_mixer( p_aout );
if ( !p_aout->mixer.b_error )
{
i_result = p_aout->output.pf_volume_set( p_aout, i_volume );
}
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_mixer( p_aout );
var_Set( p_aout, "intf-change", val );
vlc_object_release( p_aout );
if ( p_aout == NULL ) return 0;
- vlc_mutex_lock( &p_aout->mixer_lock );
+ aout_lock_mixer( p_aout );
if ( p_aout->mixer.b_error )
{
/* The output module is destroyed. */
{
i_result = p_aout->output.pf_volume_infos( p_aout, pi_soft );
}
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_mixer( p_aout );
vlc_object_release( p_aout );
return i_result;
if ( p_aout == NULL ) return 0;
- vlc_mutex_lock( &p_aout->mixer_lock );
+ aout_lock_mixer( p_aout );
if ( !p_aout->mixer.b_error )
{
i_result = p_aout->output.pf_volume_set( p_aout,
(audio_volume_t) i_volume );
}
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_mixer( p_aout );
vlc_object_release( p_aout );
return i_result;
if ( p_aout == NULL ) return 0;
- vlc_mutex_lock( &p_aout->mixer_lock );
+ aout_lock_mixer( p_aout );
if ( !p_aout->mixer.b_error )
{
i_result = p_aout->output.pf_volume_set( p_aout, (audio_volume_t) i_volume );
}
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_mixer( p_aout );
vlc_object_release( p_aout );
return i_result;
int i;
bool b_error = 0;
- vlc_mutex_lock( &p_aout->mixer_lock );
+ aout_lock_mixer( p_aout );
if ( p_aout->i_nb_inputs == 0 )
{
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_mixer( p_aout );
msg_Err( p_aout, "no decoder thread" );
return -1;
}
/* Lock all inputs. */
- vlc_mutex_lock( &p_aout->input_fifos_lock );
+ aout_lock_input_fifos( p_aout );
for ( i = 0; i < p_aout->i_nb_inputs; i++ )
{
- vlc_mutex_lock( &p_aout->pp_inputs[i]->lock );
+ aout_lock_input( p_aout, p_aout->pp_inputs[i] );
aout_InputDelete( p_aout, p_aout->pp_inputs[i] );
}
{
vlc_mutex_unlock( &p_aout->pp_inputs[i]->lock );
}
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_input_fifos( p_aout );
+ aout_unlock_mixer( p_aout );
return -1;
}
{
vlc_mutex_unlock( &p_aout->pp_inputs[i]->lock );
}
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_input_fifos( p_aout );
+ aout_unlock_mixer( p_aout );
return -1;
}
for ( i = 0; i < p_aout->i_nb_inputs; i++ )
{
aout_input_t * p_input = p_aout->pp_inputs[i];
-
b_error |= aout_InputNew( p_aout, p_input );
p_input->b_changed = 1;
- vlc_mutex_unlock( &p_input->lock );
+ aout_unlock_input( p_aout, p_input );
}
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
- vlc_mutex_unlock( &p_aout->mixer_lock );
+ aout_unlock_input_fifos( p_aout );
+ aout_unlock_mixer( p_aout );
return b_error;
}
if ( p_aout->mixer.b_error )
{
/* Free all incoming buffers. */
- vlc_mutex_lock( &p_aout->input_fifos_lock );
+ aout_lock_input_fifos( p_aout );
for ( i = 0; i < p_aout->i_nb_inputs; i++ )
{
aout_input_t * p_input = p_aout->pp_inputs[i];
p_buffer = p_next;
}
}
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
+ aout_unlock_input_fifos( p_aout );
return -1;
}
- vlc_mutex_lock( &p_aout->output_fifo_lock );
- vlc_mutex_lock( &p_aout->input_fifos_lock );
+ aout_lock_output_fifo( p_aout );
+ aout_lock_input_fifos( p_aout );
/* Retrieve the date of the next buffer. */
memcpy( &exact_start_date, &p_aout->output.fifo.end_date,
start_date = 0;
}
- vlc_mutex_unlock( &p_aout->output_fifo_lock );
+ aout_unlock_output_fifo( p_aout );
/* See if we have enough data to prepare a new buffer for the audio
* output. First : start date. */
if ( i < p_aout->i_nb_inputs )
{
/* Interrupted before the end... We can't run. */
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
+ aout_unlock_input_fifos( p_aout );
return -1;
}
}
if( i_nb_bytes < 0 )
{
/* Is it really the best way to do it ? */
- vlc_mutex_lock( &p_aout->output_fifo_lock );
+ aout_lock_output_fifo( p_aout );
aout_FifoSet( p_aout, &p_aout->output.fifo, 0 );
aout_DateSet( &exact_start_date, 0 );
- vlc_mutex_unlock( &p_aout->output_fifo_lock );
+ aout_unlock_output_fifo( p_aout );
break;
}
if ( i < p_aout->i_nb_inputs || i_first_input == p_aout->i_nb_inputs )
{
/* Interrupted before the end... We can't run. */
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
+ aout_unlock_input_fifos( p_aout );
return -1;
}
p_output_buffer );
if ( p_output_buffer == NULL )
{
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
+ aout_unlock_input_fifos( p_aout );
return -1;
}
/* This is again a bit kludgy - for the S/PDIF mixer. */
p_aout->mixer.pf_do_work( p_aout, p_output_buffer );
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
+ aout_unlock_input_fifos( p_aout );
aout_OutputPlay( p_aout, p_output_buffer );
p_aout->output.output.i_rate = i_rate;
aout_FormatPrepare( &p_aout->output.output );
- vlc_mutex_lock( &p_aout->output_fifo_lock );
+ aout_lock_output_fifo( p_aout );
/* Find the best output plug-in. */
p_aout->output.p_module = module_Need( p_aout, "audio output", "$aout", 0);
if ( p_aout->output.p_module == NULL )
{
msg_Err( p_aout, "no suitable audio output module" );
- vlc_mutex_unlock( &p_aout->output_fifo_lock );
+ aout_unlock_output_fifo( p_aout );
return -1;
}
aout_FifoInit( p_aout, &p_aout->output.fifo,
p_aout->output.output.i_rate );
- vlc_mutex_unlock( &p_aout->output_fifo_lock );
+ aout_unlock_output_fifo( p_aout );
aout_FormatPrint( p_aout, "output", &p_aout->output.output );
aout_FiltersDestroyPipeline( p_aout, p_aout->output.pp_filters,
p_aout->output.i_nb_filters );
- vlc_mutex_lock( &p_aout->output_fifo_lock );
+ aout_lock_output_fifo( p_aout );
aout_FifoDestroy( p_aout, &p_aout->output.fifo );
- vlc_mutex_unlock( &p_aout->output_fifo_lock );
+ aout_unlock_output_fifo( p_aout );
p_aout->output.b_error = true;
}
return;
}
- vlc_mutex_lock( &p_aout->output_fifo_lock );
+ aout_lock_output_fifo( p_aout );
aout_FifoPush( p_aout, &p_aout->output.fifo, p_buffer );
p_aout->output.pf_play( p_aout );
- vlc_mutex_unlock( &p_aout->output_fifo_lock );
+ aout_unlock_output_fifo( p_aout );
}
/*****************************************************************************
{
aout_buffer_t * p_buffer;
- vlc_mutex_lock( &p_aout->output_fifo_lock );
+ aout_lock_output_fifo( p_aout );
p_buffer = p_aout->output.fifo.p_first;
p_aout->output.b_starving = 1;
#endif
- vlc_mutex_unlock( &p_aout->output_fifo_lock );
+ aout_unlock_output_fifo( p_aout );
return NULL;
}
*/
{
const mtime_t i_delta = p_buffer->start_date - start_date;
- vlc_mutex_unlock( &p_aout->output_fifo_lock );
+ aout_unlock_output_fifo( p_aout );
if ( !p_aout->output.b_starving )
msg_Dbg( p_aout, "audio output is starving (%"PRId64"), "
msg_Warn( p_aout, "output date isn't PTS date, requesting "
"resampling (%"PRId64")", difference );
- vlc_mutex_lock( &p_aout->input_fifos_lock );
+ aout_lock_input_fifos( p_aout );
for ( i = 0; i < p_aout->i_nb_inputs; i++ )
{
aout_fifo_t * p_fifo = &p_aout->pp_inputs[i]->fifo;
}
aout_FifoMoveDates( p_aout, &p_aout->output.fifo, difference );
- vlc_mutex_unlock( &p_aout->input_fifos_lock );
+ aout_unlock_input_fifos( p_aout );
}
p_aout->output.fifo.p_first = p_buffer->p_next;
p_aout->output.fifo.pp_last = &p_aout->output.fifo.p_first;
}
- vlc_mutex_unlock( &p_aout->output_fifo_lock );
+ aout_unlock_output_fifo( p_aout );
return p_buffer;
}