Commit 41d30c6a authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Merge all audio output locks except volume control

With only one input per output, the lock is only useful:
 - to restart the audio instance (needed 3 out of 4 locks anyway),
 - to propagate volume change to the mixer or output plugin,
 - to access the FIFO from the output plugin thread (if applicable).

So 4 fine-grained was over-engineering. Most importantly, the locking
scheme was overly complicated and generally misunderstood/misused. Also
to avoid lock inversion, some unlocking/relocking sequences were
introduced; they broke atomicity.

We could certainly reduce the scope of the remaining lock. Since we
have one only input per output, most of the code is only ever run from
the decoder thread. Thus reentrancy is not anymore needed in some
places. But first aout_Restart() needs to be fixed and simplified.
parent 1d7fcd8c
...@@ -178,22 +178,9 @@ struct aout_instance_t ...@@ -178,22 +178,9 @@ struct aout_instance_t
{ {
VLC_COMMON_MEMBERS VLC_COMMON_MEMBERS
/* Locks : please note that if you need several of these locks, it is /* Lock for volume variables (FIXME: should be in input manager) */
* mandatory (to avoid deadlocks) to take them in the following order : vlc_mutex_t volume_lock;
* mixer_lock, p_input->lock, output_fifo_lock, input_fifos_lock. vlc_mutex_t lock;
* --Meuuh */
/* When input_fifos_lock is taken, none of the p_input->fifo structures
* can be read or modified by a third-party thread. */
vlc_mutex_t input_fifos_lock;
/* When mixer_lock is taken, all decoder threads willing to mix a
* buffer must wait until it is released. The output pipeline cannot
* be modified. No input stream can be added or removed. */
vlc_mutex_t mixer_lock;
/* When output_fifo_lock is taken, the p_aout->output.fifo structure
* cannot be read or written by a third-party thread. */
vlc_mutex_t output_fifo_lock;
/* volume_vars_lock is taken */
vlc_mutex_t volume_vars_lock;
/* Input streams & pre-filters */ /* Input streams & pre-filters */
aout_input_t * p_input; aout_input_t * p_input;
......
...@@ -97,8 +97,8 @@ struct aout_input_t ...@@ -97,8 +97,8 @@ struct aout_input_t
/* From input.c : */ /* From input.c : */
int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input, const aout_request_vout_t * ); int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input, const aout_request_vout_t * );
int aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input ); int aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input );
int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
aout_buffer_t * p_buffer, int i_input_rate ); aout_buffer_t * p_buffer, int i_input_rate );
void aout_InputCheckAndRestart( aout_instance_t * p_aout, aout_input_t * p_input ); void aout_InputCheckAndRestart( aout_instance_t * p_aout, aout_input_t * p_input );
/* From filters.c : */ /* From filters.c : */
...@@ -138,7 +138,7 @@ bool aout_ChangeFilterString( vlc_object_t *, aout_instance_t *, const char *psz ...@@ -138,7 +138,7 @@ bool aout_ChangeFilterString( vlc_object_t *, aout_instance_t *, const char *psz
/* From dec.c */ /* From dec.c */
aout_input_t *aout_DecNew( aout_instance_t *, audio_sample_format_t *, aout_input_t *aout_DecNew( aout_instance_t *, audio_sample_format_t *,
const audio_replay_gain_t *, const aout_request_vout_t * ); const audio_replay_gain_t *, const aout_request_vout_t * );
int aout_DecDelete ( aout_instance_t *, aout_input_t * ); void aout_DecDelete ( aout_instance_t *, aout_input_t * );
aout_buffer_t * aout_DecNewBuffer( aout_input_t *, size_t ); aout_buffer_t * aout_DecNewBuffer( aout_input_t *, size_t );
void aout_DecDeleteBuffer( aout_instance_t *, aout_input_t *, aout_buffer_t * ); void aout_DecDeleteBuffer( aout_instance_t *, aout_input_t *, aout_buffer_t * );
int aout_DecPlay( aout_instance_t *, aout_input_t *, aout_buffer_t *, int i_input_rate ); int aout_DecPlay( aout_instance_t *, aout_input_t *, aout_buffer_t *, int i_input_rate );
...@@ -157,81 +157,40 @@ bool aout_DecIsEmpty( aout_instance_t * p_aout, aout_input_t * p_input ); ...@@ -157,81 +157,40 @@ bool aout_DecIsEmpty( aout_instance_t * p_aout, aout_input_t * p_input );
#ifdef AOUT_DEBUG #ifdef AOUT_DEBUG
enum enum
{ {
MIXER_LOCK=1, OUTPUT_LOCK=1,
INPUT_LOCK=2, VOLUME_LOCK=2,
INPUT_FIFO_LOCK=4,
OUTPUT_FIFO_LOCK=8,
VOLUME_VARS_LOCK=16
}; };
void aout_lock (unsigned); void aout_lock_check (unsigned);
void aout_unlock (unsigned); void aout_unlock_check (unsigned);
#else #else
# define aout_lock( i ) (void)0 # define aout_lock_check( i ) (void)0
# define aout_unlock( i ) (void)0 # define aout_unlock_check( i ) (void)0
#endif #endif
static inline void aout_lock_mixer( aout_instance_t *p_aout ) static inline void aout_lock( aout_instance_t *p_aout )
{ {
aout_lock( MIXER_LOCK ); aout_lock_check( OUTPUT_LOCK );
vlc_mutex_lock( &p_aout->mixer_lock ); vlc_mutex_lock( &p_aout->lock );
} }
static inline void aout_unlock_mixer( aout_instance_t *p_aout ) static inline void aout_unlock( aout_instance_t *p_aout )
{ {
aout_unlock( MIXER_LOCK ); aout_unlock_check( OUTPUT_LOCK );
vlc_mutex_unlock( &p_aout->mixer_lock ); vlc_mutex_unlock( &p_aout->lock );
}
static inline void aout_lock_input_fifos( aout_instance_t *p_aout )
{
aout_lock( INPUT_FIFO_LOCK );
vlc_mutex_lock( &p_aout->input_fifos_lock );
}
static inline void aout_unlock_input_fifos( aout_instance_t *p_aout )
{
aout_unlock( INPUT_FIFO_LOCK );
vlc_mutex_unlock( &p_aout->input_fifos_lock );
}
static inline void aout_lock_output_fifo( aout_instance_t *p_aout )
{
aout_lock( OUTPUT_FIFO_LOCK );
vlc_mutex_lock( &p_aout->output_fifo_lock );
}
static inline void aout_unlock_output_fifo( aout_instance_t *p_aout )
{
aout_unlock( OUTPUT_FIFO_LOCK );
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;
aout_lock( INPUT_LOCK );
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;
aout_unlock( INPUT_LOCK );
vlc_mutex_unlock( &p_input->lock );
} }
static inline void aout_lock_volume( aout_instance_t *p_aout ) static inline void aout_lock_volume( aout_instance_t *p_aout )
{ {
aout_lock( VOLUME_VARS_LOCK ); aout_lock_check( VOLUME_LOCK );
vlc_mutex_lock( &p_aout->volume_vars_lock ); vlc_mutex_lock( &p_aout->volume_lock );
} }
static inline void aout_unlock_volume( aout_instance_t *p_aout ) static inline void aout_unlock_volume( aout_instance_t *p_aout )
{ {
aout_unlock( VOLUME_VARS_LOCK ); aout_unlock_check( VOLUME_LOCK );
vlc_mutex_unlock( &p_aout->volume_vars_lock ); vlc_mutex_unlock( &p_aout->volume_lock );
} }
/* Helpers */ /* Helpers */
...@@ -241,10 +200,10 @@ static inline void aout_unlock_volume( aout_instance_t *p_aout ) ...@@ -241,10 +200,10 @@ static inline void aout_unlock_volume( aout_instance_t *p_aout )
* possible to take configuration changes into account */ * possible to take configuration changes into account */
static inline void AoutInputsMarkToRestart( aout_instance_t *p_aout ) static inline void AoutInputsMarkToRestart( aout_instance_t *p_aout )
{ {
aout_lock_mixer( p_aout ); aout_lock( p_aout );
if( p_aout->p_input != NULL ) if( p_aout->p_input != NULL )
p_aout->p_input->b_restart = true; p_aout->p_input->b_restart = true;
aout_unlock_mixer( p_aout ); aout_unlock( p_aout );
} }
#endif /* !LIBVLC_AOUT_INTERNAL_H */ #endif /* !LIBVLC_AOUT_INTERNAL_H */
...@@ -59,10 +59,8 @@ aout_instance_t * __aout_New( vlc_object_t * p_parent ) ...@@ -59,10 +59,8 @@ aout_instance_t * __aout_New( vlc_object_t * p_parent )
} }
/* Initialize members. */ /* Initialize members. */
vlc_mutex_init( &p_aout->input_fifos_lock ); vlc_mutex_init( &p_aout->volume_lock );
vlc_mutex_init( &p_aout->mixer_lock ); vlc_mutex_init( &p_aout->lock );
vlc_mutex_init( &p_aout->volume_vars_lock );
vlc_mutex_init( &p_aout->output_fifo_lock );
p_aout->p_input = NULL; p_aout->p_input = NULL;
p_aout->mixer_multiplier = 1.0; p_aout->mixer_multiplier = 1.0;
p_aout->p_mixer = NULL; p_aout->p_mixer = NULL;
...@@ -82,45 +80,24 @@ aout_instance_t * __aout_New( vlc_object_t * p_parent ) ...@@ -82,45 +80,24 @@ aout_instance_t * __aout_New( vlc_object_t * p_parent )
static void aout_Destructor( vlc_object_t * p_this ) static void aout_Destructor( vlc_object_t * p_this )
{ {
aout_instance_t * p_aout = (aout_instance_t *)p_this; aout_instance_t * p_aout = (aout_instance_t *)p_this;
vlc_mutex_destroy( &p_aout->input_fifos_lock ); vlc_mutex_destroy( &p_aout->volume_lock );
vlc_mutex_destroy( &p_aout->mixer_lock ); vlc_mutex_destroy( &p_aout->lock );
vlc_mutex_destroy( &p_aout->volume_vars_lock );
vlc_mutex_destroy( &p_aout->output_fifo_lock );
} }
/* Lock ordering rules:
*
* Vars Mixer Input IFIFO OFIFO (< Inner lock)
* Vars No! Yes Yes Yes Yes
* Mixer No! No! Yes Yes Yes
* Input No! No! No! Yes Yes
* In FIFOs No! No! No! No! Yes
* Out FIFOs No! No! No! No! No!
* (^ Outer lock)
*/
#ifdef AOUT_DEBUG #ifdef AOUT_DEBUG
/* Lock debugging */ /* Lock debugging */
static __thread unsigned aout_locks = 0; static __thread unsigned aout_locks = 0;
void aout_lock (unsigned i) void aout_lock_check (unsigned i)
{ {
unsigned allowed; unsigned allowed;
switch (i) switch (i)
{ {
case VOLUME_VARS_LOCK: case VOLUME_LOCK:
allowed = 0; allowed = 0;
break; break;
case MIXER_LOCK: case OUTPUT_LOCK:
allowed = VOLUME_VARS_LOCK; allowed = VOLUME_LOCK;
break;
case INPUT_LOCK:
allowed = VOLUME_VARS_LOCK|MIXER_LOCK;
break;
case INPUT_FIFO_LOCK:
allowed = VOLUME_VARS_LOCK|MIXER_LOCK|INPUT_LOCK;
break;
case OUTPUT_FIFO_LOCK:
allowed = VOLUME_VARS_LOCK|MIXER_LOCK|INPUT_LOCK|INPUT_FIFO_LOCK;
break; break;
default: default:
abort (); abort ();
...@@ -136,7 +113,7 @@ void aout_lock (unsigned i) ...@@ -136,7 +113,7 @@ void aout_lock (unsigned i)
aout_locks |= i; aout_locks |= i;
} }
void aout_unlock (unsigned i) void aout_unlock_check (unsigned i)
{ {
assert (aout_locks & i); assert (aout_locks & i);
aout_locks &= ~i; aout_locks &= ~i;
......
...@@ -81,7 +81,6 @@ aout_input_t *aout_DecNew( aout_instance_t *p_aout, ...@@ -81,7 +81,6 @@ aout_input_t *aout_DecNew( aout_instance_t *p_aout,
if( !p_input ) if( !p_input )
return NULL; return NULL;
vlc_mutex_init( &p_input->lock );
p_input->b_error = true; p_input->b_error = true;
p_input->b_paused = false; p_input->b_paused = false;
p_input->i_pause_date = 0; p_input->i_pause_date = 0;
...@@ -95,8 +94,7 @@ aout_input_t *aout_DecNew( aout_instance_t *p_aout, ...@@ -95,8 +94,7 @@ aout_input_t *aout_DecNew( aout_instance_t *p_aout,
/* We can only be called by the decoder, so no need to lock /* We can only be called by the decoder, so no need to lock
* p_input->lock. */ * p_input->lock. */
aout_lock_mixer( p_aout ); aout_lock( p_aout );
aout_lock_input_fifos( p_aout );
assert( p_aout->p_input == NULL ); assert( p_aout->p_input == NULL );
p_aout->p_input = p_input; p_aout->p_input = p_input;
...@@ -119,28 +117,18 @@ aout_input_t *aout_DecNew( aout_instance_t *p_aout, ...@@ -119,28 +117,18 @@ aout_input_t *aout_DecNew( aout_instance_t *p_aout,
aout_InputNew( p_aout, p_input, p_request_vout ); aout_InputNew( p_aout, p_input, p_request_vout );
out: out:
aout_unlock_input_fifos( p_aout ); aout_unlock( p_aout );
aout_unlock_mixer( p_aout );
return p_input; return p_input;
} }
/***************************************************************************** /*****************************************************************************
* aout_DecDelete : delete a decoder * aout_DecDelete : delete a decoder
*****************************************************************************/ *****************************************************************************/
int aout_DecDelete( aout_instance_t * p_aout, aout_input_t * p_input ) void aout_DecDelete( aout_instance_t * p_aout, aout_input_t * p_input )
{ {
/* This function can only be called by the decoder itself, so no need aout_lock( p_aout );
* to lock p_input->lock. */
aout_lock_mixer( p_aout );
if( p_input != p_aout->p_input )
{
msg_Err( p_aout, "cannot find an input to delete" );
aout_unlock_mixer( p_aout );
return -1;
}
/* Remove the input. */ /* Remove the input. */
assert( p_input == p_aout->p_input ); /* buggy decoder? */
p_aout->p_input = NULL; p_aout->p_input = NULL;
aout_InputDelete( p_aout, p_input ); aout_InputDelete( p_aout, p_input );
...@@ -149,11 +137,8 @@ int aout_DecDelete( aout_instance_t * p_aout, aout_input_t * p_input ) ...@@ -149,11 +137,8 @@ int aout_DecDelete( aout_instance_t * p_aout, aout_input_t * p_input )
var_Destroy( p_aout, "audio-device" ); var_Destroy( p_aout, "audio-device" );
var_Destroy( p_aout, "audio-channels" ); var_Destroy( p_aout, "audio-channels" );
aout_unlock_mixer( p_aout ); aout_unlock( p_aout );
vlc_mutex_destroy( &p_input->lock );
free( p_input ); free( p_input );
return 0;
} }
...@@ -167,23 +152,9 @@ int aout_DecDelete( aout_instance_t * p_aout, aout_input_t * p_input ) ...@@ -167,23 +152,9 @@ int aout_DecDelete( aout_instance_t * p_aout, aout_input_t * p_input )
aout_buffer_t * aout_DecNewBuffer( aout_input_t * p_input, aout_buffer_t * aout_DecNewBuffer( aout_input_t * p_input,
size_t i_nb_samples ) size_t i_nb_samples )
{ {
block_t *block; size_t length = i_nb_samples * p_input->input.i_bytes_per_frame
size_t length; / p_input->input.i_frame_length;
block_t *block = block_Alloc( length );
aout_lock_input( NULL, p_input );
if ( p_input->b_error )
{
aout_unlock_input( NULL, p_input );
return NULL;
}
length = i_nb_samples * p_input->input.i_bytes_per_frame
/ p_input->input.i_frame_length;
block = block_Alloc( length );
aout_unlock_input( NULL, p_input );
if( likely(block != NULL) ) if( likely(block != NULL) )
{ {
block->i_nb_samples = i_nb_samples; block->i_nb_samples = i_nb_samples;
...@@ -216,50 +187,40 @@ int aout_DecPlay( aout_instance_t * p_aout, aout_input_t * p_input, ...@@ -216,50 +187,40 @@ int aout_DecPlay( aout_instance_t * p_aout, aout_input_t * p_input,
p_buffer->i_length = (mtime_t)p_buffer->i_nb_samples * 1000000 p_buffer->i_length = (mtime_t)p_buffer->i_nb_samples * 1000000
/ p_input->input.i_rate; / p_input->input.i_rate;
aout_lock_mixer( p_aout ); aout_lock( p_aout );
aout_lock_input( p_aout, p_input );
if( p_input->b_error ) if( p_input->b_error )
{ {
aout_unlock_input( p_aout, p_input ); aout_unlock( p_aout );
aout_unlock_mixer( p_aout );
aout_BufferFree( p_buffer ); aout_BufferFree( p_buffer );
return -1; return -1;
} }
aout_InputCheckAndRestart( p_aout, p_input ); aout_InputCheckAndRestart( p_aout, p_input );
aout_unlock_mixer( p_aout ); aout_InputPlay( p_aout, p_input, p_buffer, i_input_rate );
int i_ret = aout_InputPlay( p_aout, p_input, p_buffer, i_input_rate );
aout_unlock_input( p_aout, p_input );
if( i_ret == -1 )
return -1;
/* Run the mixer if it is able to run. */ /* Run the mixer if it is able to run. */
aout_lock_mixer( p_aout );
aout_MixerRun( p_aout, p_aout->mixer_multiplier ); aout_MixerRun( p_aout, p_aout->mixer_multiplier );
aout_unlock_mixer( p_aout ); aout_unlock( p_aout );
return 0; return 0;
} }
int aout_DecGetResetLost( aout_instance_t *p_aout, aout_input_t *p_input ) int aout_DecGetResetLost( aout_instance_t *p_aout, aout_input_t *p_input )
{ {
aout_lock_input( p_aout, p_input ); int val;
int i_value = p_input->i_buffer_lost;
aout_lock( p_aout );
val = p_input->i_buffer_lost;
p_input->i_buffer_lost = 0; p_input->i_buffer_lost = 0;
aout_unlock_input( p_aout, p_input ); aout_unlock( p_aout );
return i_value; return val;
} }
void aout_DecChangePause( aout_instance_t *p_aout, aout_input_t *p_input, bool b_paused, mtime_t i_date ) void aout_DecChangePause( aout_instance_t *p_aout, aout_input_t *p_input, bool b_paused, mtime_t i_date )
{ {
mtime_t i_duration = 0; mtime_t i_duration = 0;
aout_lock_input( p_aout, p_input );
aout_lock( p_aout );
assert( p_aout->p_input == p_input );
assert( !p_input->b_paused || !b_paused ); assert( !p_input->b_paused || !b_paused );
if( p_input->b_paused ) if( p_input->b_paused )
{ {
...@@ -267,33 +228,31 @@ void aout_DecChangePause( aout_instance_t *p_aout, aout_input_t *p_input, bool b ...@@ -267,33 +228,31 @@ void aout_DecChangePause( aout_instance_t *p_aout, aout_input_t *p_input, bool b
} }
p_input->b_paused = b_paused; p_input->b_paused = b_paused;
p_input->i_pause_date = i_date; p_input->i_pause_date = i_date;
aout_unlock_input( p_aout, p_input );
if( i_duration != 0 ) if( i_duration != 0 )
{ {
aout_lock_mixer( p_aout );
for( aout_buffer_t *p = p_input->mixer.fifo.p_first; p != NULL; p = p->p_next ) for( aout_buffer_t *p = p_input->mixer.fifo.p_first; p != NULL; p = p->p_next )
{ {
p->i_pts += i_duration; p->i_pts += i_duration;
} }
aout_unlock_mixer( p_aout );
} }
aout_OutputPause( p_aout, b_paused, i_date ); aout_OutputPause( p_aout, b_paused, i_date );
aout_unlock( p_aout );
} }
void aout_DecFlush( aout_instance_t *p_aout, aout_input_t *p_input ) void aout_DecFlush( aout_instance_t *p_aout, aout_input_t *p_input )
{ {
aout_lock_input_fifos( p_aout ); aout_lock( p_aout );
aout_FifoSet( &p_input->mixer.fifo, 0 ); aout_FifoSet( &p_input->mixer.fifo, 0 );
aout_unlock_input_fifos( p_aout ); aout_unlock( p_aout );
} }
bool aout_DecIsEmpty( aout_instance_t * p_aout, aout_input_t * p_input ) bool aout_DecIsEmpty( aout_instance_t * p_aout, aout_input_t * p_input )
{ {
mtime_t end_date; mtime_t end_date;
aout_lock_input_fifos( p_aout ); aout_lock( p_aout );
end_date = aout_FifoNextStart( &p_input->mixer.fifo ); end_date = aout_FifoNextStart( &p_input->mixer.fifo );
aout_unlock_input_fifos( p_aout ); aout_unlock( p_aout );
return end_date <= mdate(); return end_date <= mdate();
} }
...@@ -48,8 +48,7 @@ ...@@ -48,8 +48,7 @@
#include "aout_internal.h" #include "aout_internal.h"
#define AOUT_ASSERT_MIXER_LOCKED vlc_assert_locked( &p_aout->mixer_lock ) #define AOUT_ASSERT_LOCKED vlc_assert_locked( &p_aout->lock )
#define AOUT_ASSERT_INPUT_LOCKED vlc_assert_locked( &p_input->lock )
static void inputFailure( aout_instance_t *, aout_input_t *, const char * ); static void inputFailure( aout_instance_t *, aout_input_t *, const char * );
static void inputDrop( aout_input_t *, aout_buffer_t * ); static void inputDrop( aout_input_t *, aout_buffer_t * );
...@@ -431,7 +430,7 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input, const aout_ ...@@ -431,7 +430,7 @@ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input, const aout_
*****************************************************************************/ *****************************************************************************/
int aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input ) int aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input )
{ {
AOUT_ASSERT_MIXER_LOCKED; AOUT_ASSERT_LOCKED;
if ( p_input->b_error ) if ( p_input->b_error )
return 0; return 0;
...@@ -460,14 +459,11 @@ int aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input ) ...@@ -460,14 +459,11 @@ int aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input )
*****************************************************************************/ *****************************************************************************/
void aout_InputCheckAndRestart( aout_instance_t * p_aout, aout_input_t * p_input ) void aout_InputCheckAndRestart( aout_instance_t * p_aout, aout_input_t * p_input )
{ {
AOUT_ASSERT_MIXER_LOCKED; AOUT_ASSERT_LOCKED;
AOUT_ASSERT_INPUT_LOCKED;
if( !p_input->b_restart ) if( !p_input->b_restart )
return; return;
aout_lock_input_fifos( p_aout );
/* A little trick to avoid loosing our input fifo and properties */ /* A little trick to avoid loosing our input fifo and properties */
aout_fifo_t fifo = p_input->mixer.fifo; aout_fifo_t fifo = p_input->mixer.fifo;
...@@ -484,8 +480,6 @@ void aout_InputCheckAndRestart( aout_instance_t * p_aout, aout_input_t * p_input ...@@ -484,8 +480,6 @@ void aout_InputCheckAndRestart( aout_instance_t * p_aout, aout_input_t * p_input
p_input->i_pause_date = i_pause_date; p_input->i_pause_date = i_pause_date;
p_input->b_restart = false; p_input->b_restart = false;
aout_unlock_input_fifos( p_aout );
} }
/***************************************************************************** /*****************************************************************************
* aout_InputPlay : play a buffer * aout_InputPlay : play a buffer
...@@ -494,16 +488,16 @@ void aout_InputCheckAndRestart( aout_instance_t * p_aout, aout_input_t * p_input ...@@ -494,16 +488,16 @@ void aout_InputCheckAndRestart( aout_instance_t * p_aout, aout_input_t * p_input
*****************************************************************************/ *****************************************************************************/
/* XXX Do not activate it !! */ /* XXX Do not activate it !! */
//#define AOUT_PROCESS_BEFORE_CHEKS //#define AOUT_PROCESS_BEFORE_CHEKS
int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
aout_buffer_t * p_buffer, int i_input_rate ) aout_buffer_t * p_buffer, int i_input_rate )
{ {
mtime_t start_date; mtime_t start_date;
AOUT_ASSERT_INPUT_LOCKED; AOUT_ASSERT_LOCKED;
if( i_input_rate != INPUT_RATE_DEFAULT && p_input->p_playback_rate_filter == NULL ) if( i_input_rate != INPUT_RATE_DEFAULT && p_input->p_playback_rate_filter == NULL )
{ {
inputDrop( p_input, p_buffer ); inputDrop( p_input, p_buffer );
return 0; return;
} }
#ifdef AOUT_PROCESS_BEFORE_CHEKS #ifdef AOUT_PROCESS_BEFORE_CHEKS
...@@ -511,7 +505,7 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, ...@@ -511,7 +505,7 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
aout_FiltersPlay( p_aout, p_input->pp_filters, p_input->i_nb_filters, aout_FiltersPlay( p_aout, p_input->pp_filters, p_input->i_nb_filters,
&p_buffer ); &p_buffer );
if( !p_buffer ) if( !p_buffer )
return 0; return;
/* Actually run the resampler now. */ /* Actually run the resampler now. */
if ( p_input->i_nb_resamplers > 0 ) if ( p_input->i_nb_resamplers > 0 )
...@@ -523,11 +517,11 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, ...@@ -523,11 +517,11 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
} }
if( !p_buffer ) if( !p_buffer )
return 0; return;
if( p_buffer->i_nb_samples <= 0 ) if( p_buffer->i_nb_samples <= 0 )
{ {
block_Release( p_buffer ); block_Release( p_buffer );
return 0; return;
} }
#endif #endif
...@@ -547,7 +541,6 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, ...@@ -547,7 +541,6 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
/* We don't care if someone changes the start date behind our back after /* 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 * this. We'll deal with that when pushing the buffer, and compensate
* with the next incoming buffer. */ * with the next incoming buffer. */
aout_lock_input_fifos( p_aout );
start_date = aout_FifoNextStart( &p_input->mixer.fifo ); start_date = aout_FifoNextStart( &p_input->mixer.fifo );
if ( start_date != 0 && start_date < now ) if ( start_date != 0 && start_date < now )
...@@ -573,7 +566,7 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, ...@@ -573,7 +566,7 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
now - p_buffer->i_pts ); now - p_buffer->i_pts );
inputDrop( p_input, p_buffer ); inputDrop( p_input, p_buffer );
inputResamplingStop( p_input ); inputResamplingStop( p_input );
goto out; return;
} }
/* If the audio drift is too big then it's not worth trying to resample /* If the audio drift is too big then it's not worth trying to resample
...@@ -602,14 +595,14 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, ...@@ -602,14 +595,14 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
msg_Warn( p_aout, "buffer way too late (%"PRId64"), dropping buffer", msg_Warn( p_aout, "buffer way too late (%"PRId64"), dropping buffer",
drift ); drift );
inputDrop( p_input, p_buffer ); inputDrop( p_input, p_buffer );
goto out; return;
} }
#ifndef AOUT_PROCESS_BEFORE_CHEKS #ifndef AOUT_PROCESS_BEFORE_CHEKS
/* Run pre-filters. */ /* Run pre-filters. */
aout_FiltersPlay( p_input->pp_filters, p_input->i_nb_filters, &p_buffer ); aout_FiltersPlay( p_input->pp_filters, p_input->i_nb_filters, &p_buffer );
if( !p_buffer ) if( !p_buffer )
goto out; return;
#endif #endif
/* Run the resampler if needed. /* Run the resampler if needed.
...@@ -691,20 +684,17 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, ...@@ -691,20 +684,17 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
} }
if( !p_buffer ) if( !p_buffer )
goto out; return;
if( p_buffer->i_nb_samples <= 0 ) if( p_buffer->i_nb_samples <= 0 )
{ {
block_Release( p_buffer ); block_Release( p_buffer );
goto out; return;
} }
#endif #endif
/* Adding the start date will be managed by aout_FifoPush(). */ /* Adding the start date will be managed by aout_FifoPush(). */
p_buffer->i_pts = start_date; p_buffer->i_pts = start_date;
aout_FifoPush( &p_input->mixer.fifo, p_buffer ); aout_FifoPush( &p_input->mixer.fifo, p_buffer );
out:
aout_unlock_input_fifos( p_aout );
return 0;
} }
/***************************************************************************** /*****************************************************************************
...@@ -870,10 +860,10 @@ static int ReplayGainCallback( vlc_object_t *p_this, char const *psz_cmd, ...@@ -870,10 +860,10 @@ static int ReplayGainCallback( vlc_object_t *p_this, char const *psz_cmd,
VLC_UNUSED(newval); VLC_UNUSED(p_data); VLC_UNUSED(newval); VLC_UNUSED(p_data);
aout_instance_t *p_aout = (aout_instance_t *)p_this; aout_instance_t *p_aout = (aout_instance_t *)p_this;
aout_lock_mixer( p_aout ); aout_lock( p_aout );
if( p_aout->p_input != NULL ) if( p_aout->p_input != NULL )
ReplayGainSelect( p_aout, p_aout->p_input ); ReplayGainSelect( p_aout, p_aout->p_input );
aout_unlock_mixer( p_aout ); aout_unlock( p_aout );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
......
...@@ -85,12 +85,11 @@ static int commitVolume (vlc_object_t *obj, aout_instance_t *aout, ...@@ -85,12 +85,11 @@ static int commitVolume (vlc_object_t *obj, aout_instance_t *aout,
if (aout != NULL) if (aout != NULL)
{ {
aout_lock_mixer (aout); aout_lock (aout);
aout_lock_input_fifos (aout); #warning FIXME: wrong test. Need to check that aout_output is ready.
if (aout->p_mixer != NULL) if (aout->p_mixer != NULL)
ret = aout->output.pf_volume_set (aout, volume, mute); ret = aout->output.pf_volume_set (aout, volume, mute);
aout_unlock_input_fifos (aout); aout_unlock (aout);
aout_unlock_mixer (aout);
if (ret == 0) if (ret == 0)
var_TriggerCallback (aout, "intf-change"); var_TriggerCallback (aout, "intf-change");
...@@ -291,58 +290,46 @@ void aout_VolumeNoneInit( aout_instance_t * p_aout ) ...@@ -291,58 +290,46 @@ void aout_VolumeNoneInit( aout_instance_t * p_aout )
*****************************************************************************/ *****************************************************************************/
static int aout_Restart( aout_instance_t * p_aout ) static int aout_Restart( aout_instance_t * p_aout )
{ {
bool b_error = 0; aout_input_t *p_input;
aout_lock_mixer( p_aout ); aout_lock( p_aout );
p_input = p_aout->p_input;
if( p_aout->p_input == NULL ) if( p_input == NULL )
{ {
aout_unlock_mixer( p_aout ); aout_unlock( p_aout );
msg_Err( p_aout, "no decoder thread" ); msg_Err( p_aout, "no decoder thread" );
return -1; return -1;
} }
aout_lock_input( p_aout, p_aout->p_input ); /* Reinitializes the output */
aout_lock_input_fifos( p_aout ); aout_InputDelete( p_aout, p_input );
aout_InputDelete( p_aout, p_aout->p_input );
aout_unlock_input_fifos( p_aout );
/* Lock all inputs. */
aout_lock_input_fifos( p_aout );
aout_MixerDelete( p_aout ); aout_MixerDelete( p_aout );
/* Re-open the output plug-in. */
aout_OutputDelete( p_aout ); aout_OutputDelete( p_aout );
/* FIXME: This function is notoriously dangerous/unsafe. /* FIXME: This function is notoriously dangerous/unsafe.
* By the way, if OutputNew or MixerNew fails, we are totally screwed. */ * By the way, if OutputNew or MixerNew fails, we are totally screwed. */
if ( aout_OutputNew( p_aout, &p_aout->p_input->input ) == -1 ) if ( aout_OutputNew( p_aout, &p_input->input ) == -1 )
{ {
/* Release all locks and report the error. */ /* Release all locks and report the error. */
vlc_mutex_unlock( &p_aout->p_input->lock ); aout_unlock( p_aout );
aout_unlock_input_fifos( p_aout );
aout_unlock_mixer( p_aout );
return -1; return -1;
} }
if ( aout_MixerNew( p_aout ) == -1 ) if ( aout_MixerNew( p_aout ) == -1 )
{ {
aout_OutputDelete( p_aout ); aout_OutputDelete( p_aout );
vlc_mutex_unlock( &p_aout->p_input->lock ); aout_unlock( p_aout );
aout_unlock_input_fifos( p_aout );
aout_unlock_mixer( p_aout );
return -1; return -1;
} }
/* Re-open the input. */ if( aout_InputNew( p_aout, p_input, &p_input->request_vout ) )
aout_input_t * p_input = p_aout->p_input; {
b_error |= aout_InputNew( p_aout, p_input, &p_input->request_vout ); #warning FIXME: deal with errors
aout_unlock_input( p_aout, p_input ); aout_unlock( p_aout );
return -1;
aout_unlock_input_fifos( p_aout ); }
aout_unlock_mixer( p_aout ); aout_unlock( p_aout );
return 0;
return b_error;
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
int aout_MixerNew( aout_instance_t * p_aout ) int aout_MixerNew( aout_instance_t * p_aout )
{ {
assert( !p_aout->p_mixer ); assert( !p_aout->p_mixer );
vlc_assert_locked( &p_aout->input_fifos_lock ); vlc_assert_locked( &p_aout->lock );
aout_mixer_t *p_mixer = vlc_object_create( p_aout, sizeof(*p_mixer) ); aout_mixer_t *p_mixer = vlc_object_create( p_aout, sizeof(*p_mixer) );
if( !p_mixer ) if( !p_mixer )
...@@ -75,14 +75,13 @@ int aout_MixerNew( aout_instance_t * p_aout ) ...@@ -75,14 +75,13 @@ int aout_MixerNew( aout_instance_t * p_aout )
*****************************************************************************/ *****************************************************************************/
void aout_MixerDelete( aout_instance_t * p_aout ) void aout_MixerDelete( aout_instance_t * p_aout )
{ {
vlc_assert_locked( &p_aout->lock );
if( !p_aout->p_mixer ) if( !p_aout->p_mixer )
return; return;
module_unneed( p_aout->p_mixer, p_aout->p_mixer->module ); module_unneed( p_aout->p_mixer, p_aout->p_mixer->module );
vlc_object_release( p_aout->p_mixer ); vlc_object_release( p_aout->p_mixer );
/* */
p_aout->p_mixer = NULL; p_aout->p_mixer = NULL;
} }
...@@ -102,8 +101,7 @@ static int MixBuffer( aout_instance_t * p_aout, float volume ) ...@@ -102,8 +101,7 @@ static int MixBuffer( aout_instance_t * p_aout, float volume )
* "smart" audio outputs. */ * "smart" audio outputs. */
assert( samples > 0 ); assert( samples > 0 );
aout_lock_input_fifos( p_aout ); vlc_assert_locked( &p_aout->lock );
aout_lock_output_fifo( p_aout );
/* Retrieve the date of the next buffer. */ /* Retrieve the date of the next buffer. */
date_t exact_start_date = p_aout->output.fifo.end_date; date_t exact_start_date = p_aout->output.fifo.end_date;
...@@ -121,12 +119,10 @@ static int MixBuffer( aout_instance_t * p_aout, float volume ) ...@@ -121,12 +119,10 @@ static int MixBuffer( aout_instance_t * p_aout, float volume )
start_date = 0; start_date = 0;
} }
aout_unlock_output_fifo( p_aout );
/* See if we have enough data to prepare a new buffer for the audio output. */ /* See if we have enough data to prepare a new buffer for the audio output. */
aout_buffer_t *p_buffer = p_fifo->p_first; aout_buffer_t *p_buffer = p_fifo->p_first;
if( p_buffer == NULL ) if( p_buffer == NULL )
goto giveup; return -1;
/* Find the earliest start date available. */ /* Find the earliest start date available. */
if ( !start_date ) if ( !start_date )
...@@ -153,7 +149,7 @@ static int MixBuffer( aout_instance_t * p_aout, float volume ) ...@@ -153,7 +149,7 @@ static int MixBuffer( aout_instance_t * p_aout, float volume )
p_buffer = p_fifo->p_first; p_buffer = p_fifo->p_first;
if( p_buffer == NULL ) if( p_buffer == NULL )
goto giveup; return -1;
} }
/* Check that we have enough samples. */ /* Check that we have enough samples. */
...@@ -161,7 +157,7 @@ static int MixBuffer( aout_instance_t * p_aout, float volume ) ...@@ -161,7 +157,7 @@ static int MixBuffer( aout_instance_t * p_aout, float volume )
{ {
p_buffer = p_buffer->p_next; p_buffer = p_buffer->p_next;
if( p_buffer == NULL ) if( p_buffer == NULL )
goto giveup; return -1;
/* Check that all buffers are contiguous. */ /* Check that all buffers are contiguous. */
if( prev_date != p_buffer->i_pts ) if( prev_date != p_buffer->i_pts )
...@@ -191,11 +187,9 @@ static int MixBuffer( aout_instance_t * p_aout, float volume ) ...@@ -191,11 +187,9 @@ static int MixBuffer( aout_instance_t * p_aout, float volume )
if( delta < 0 ) if( delta < 0 )
{ {
/* Is it really the best way to do it ? */ /* Is it really the best way to do it ? */
aout_lock_output_fifo( p_aout );
aout_FifoSet( &p_aout->output.fifo, 0 ); aout_FifoSet( &p_aout->output.fifo, 0 );
date_Set( &exact_start_date, 0 ); date_Set( &exact_start_date, 0 );
aout_unlock_output_fifo( p_aout ); return -1;
goto giveup;
} }
if( delta > 0 ) if( delta > 0 )
{ {
...@@ -212,7 +206,7 @@ static int MixBuffer( aout_instance_t * p_aout, float volume ) ...@@ -212,7 +206,7 @@ static int MixBuffer( aout_instance_t * p_aout, float volume )
p_buffer = block_Alloc( needed ); p_buffer = block_Alloc( needed );
if( unlikely(p_buffer == NULL) ) if( unlikely(p_buffer == NULL) )
/* XXX: should free input buffers */ /* XXX: should free input buffers */
goto giveup; return -1;
p_buffer->i_nb_samples = samples; p_buffer->i_nb_samples = samples;
for( uint8_t *p_out = p_buffer->p_buffer; needed > 0; ) for( uint8_t *p_out = p_buffer->p_buffer; needed > 0; )
...@@ -254,14 +248,8 @@ static int MixBuffer( aout_instance_t * p_aout, float volume ) ...@@ -254,14 +248,8 @@ static int MixBuffer( aout_instance_t * p_aout, float volume )
/* Run the mixer. */ /* Run the mixer. */
p_mixer->mix( p_mixer, p_buffer, volume ); p_mixer->mix( p_mixer, p_buffer, volume );
aout_unlock_input_fifos( p_aout );
aout_OutputPlay( p_aout, p_buffer ); aout_OutputPlay( p_aout, p_buffer );
return 0; return 0;
giveup:
/* Interrupted before the end... We can't run. */
aout_unlock_input_fifos( p_aout );
return -1;
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <vlc_cpu.h> #include <vlc_cpu.h>
#include <vlc_modules.h> #include <vlc_modules.h>
#include "libvlc.h"
#include "aout_internal.h" #include "aout_internal.h"
/***************************************************************************** /*****************************************************************************
...@@ -43,6 +44,7 @@ ...@@ -43,6 +44,7 @@
int aout_OutputNew( aout_instance_t * p_aout, int aout_OutputNew( aout_instance_t * p_aout,
const audio_sample_format_t * p_format ) const audio_sample_format_t * p_format )
{ {
vlc_assert_locked( &p_aout->lock );
p_aout->output.output = *p_format; p_aout->output.output = *p_format;
/* Retrieve user defaults. */ /* Retrieve user defaults. */
...@@ -155,13 +157,8 @@ int aout_OutputNew( aout_instance_t * p_aout, ...@@ -155,13 +157,8 @@ int aout_OutputNew( aout_instance_t * p_aout,
aout_FormatPrepare( &p_aout->output.output ); aout_FormatPrepare( &p_aout->output.output );
aout_lock_output_fifo( p_aout );
/* Prepare FIFO. */ /* Prepare FIFO. */
aout_FifoInit( p_aout, &p_aout->output.fifo, p_aout->output.output.i_rate ); aout_FifoInit( p_aout, &p_aout->output.fifo, p_aout->output.output.i_rate );
aout_unlock_output_fifo( p_aout );
aout_FormatPrint( p_aout, "output", &p_aout->output.output ); aout_FormatPrint( p_aout, "output", &p_aout->output.output );
/* Calculate the resulting mixer output format. */ /* Calculate the resulting mixer output format. */
...@@ -202,17 +199,16 @@ int aout_OutputNew( aout_instance_t * p_aout, ...@@ -202,17 +199,16 @@ int aout_OutputNew( aout_instance_t * p_aout,
*****************************************************************************/ *****************************************************************************/
void aout_OutputDelete( aout_instance_t * p_aout ) void aout_OutputDelete( aout_instance_t * p_aout )
{ {
vlc_assert_locked( &p_aout->lock );
if( p_aout->output.p_module == NULL ) if( p_aout->output.p_module == NULL )
return; return;
module_unneed( p_aout, p_aout->output.p_module ); module_unneed( p_aout, p_aout->output.p_module );
p_aout->output.p_module = NULL; p_aout->output.p_module = NULL;
aout_FiltersDestroyPipeline( p_aout->output.pp_filters, aout_FiltersDestroyPipeline( p_aout->output.pp_filters,
p_aout->output.i_nb_filters ); p_aout->output.i_nb_filters );
aout_lock_output_fifo( p_aout );
aout_FifoDestroy( &p_aout->output.fifo ); aout_FifoDestroy( &p_aout->output.fifo );
aout_unlock_output_fifo( p_aout );
} }
/***************************************************************************** /*****************************************************************************
...@@ -222,9 +218,10 @@ void aout_OutputDelete( aout_instance_t * p_aout ) ...@@ -222,9 +218,10 @@ void aout_OutputDelete( aout_instance_t * p_aout )
*****************************************************************************/ *****************************************************************************/
void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer ) void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
{ {
vlc_assert_locked( &p_aout->lock );
aout_FiltersPlay( p_aout->output.pp_filters, p_aout->output.i_nb_filters, aout_FiltersPlay( p_aout->output.pp_filters, p_aout->output.i_nb_filters,
&p_buffer ); &p_buffer );
if( !p_buffer ) if( !p_buffer )
return; return;
if( p_buffer->i_buffer == 0 ) if( p_buffer->i_buffer == 0 )
...@@ -233,10 +230,8 @@ void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer ) ...@@ -233,10 +230,8 @@ void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
return; return;
} }
aout_lock_output_fifo( p_aout );
aout_FifoPush( &p_aout->output.fifo, p_buffer ); aout_FifoPush( &p_aout->output.fifo, p_buffer );
p_aout->output.pf_play( p_aout ); p_aout->output.pf_play( p_aout );
aout_unlock_output_fifo( p_aout );
} }
/** /**
...@@ -246,10 +241,10 @@ void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer ) ...@@ -246,10 +241,10 @@ void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
*/ */
void aout_OutputPause( aout_instance_t *aout, bool pause, mtime_t date ) void aout_OutputPause( aout_instance_t *aout, bool pause, mtime_t date )
{ {
aout_lock_output_fifo( aout ); vlc_assert_locked( &aout->lock );
if( aout->output.pf_pause != NULL ) if( aout->output.pf_pause != NULL )
aout->output.pf_pause( aout, pause, date ); aout->output.pf_pause( aout, pause, date );
aout_unlock_output_fifo( aout );
} }
/***************************************************************************** /*****************************************************************************
...@@ -268,7 +263,7 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout, ...@@ -268,7 +263,7 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
aout_buffer_t * p_buffer; aout_buffer_t * p_buffer;
mtime_t now = mdate(); mtime_t now = mdate();
aout_lock_output_fifo( p_aout ); aout_lock( p_aout );
/* Drop the audio sample if the audio output is really late. /* Drop the audio sample if the audio output is really late.
* In the case of b_can_sleek, we don't use a resampler so we need to be * In the case of b_can_sleek, we don't use a resampler so we need to be
...@@ -295,8 +290,7 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout, ...@@ -295,8 +290,7 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
"audio output is starving (no input), playing silence" ); "audio output is starving (no input), playing silence" );
p_aout->output.b_starving = true; p_aout->output.b_starving = true;
#endif #endif
aout_unlock_output_fifo( p_aout ); goto out;
return NULL;
} }
mtime_t delta = start_date - p_buffer->i_pts; mtime_t delta = start_date - p_buffer->i_pts;
...@@ -315,8 +309,8 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout, ...@@ -315,8 +309,8 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
msg_Dbg( p_aout, "audio output is starving (%"PRId64"), " msg_Dbg( p_aout, "audio output is starving (%"PRId64"), "
"playing silence", -delta ); "playing silence", -delta );
p_aout->output.b_starving = true; p_aout->output.b_starving = true;
aout_unlock_output_fifo( p_aout ); p_buffer = NULL;
return NULL; goto out;
} }
p_aout->output.b_starving = false; p_aout->output.b_starving = false;
...@@ -326,18 +320,15 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout, ...@@ -326,18 +320,15 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
{ {
if( delta > AOUT_PTS_TOLERANCE || delta < -AOUT_PTS_TOLERANCE ) if( delta > AOUT_PTS_TOLERANCE || delta < -AOUT_PTS_TOLERANCE )
{ {
aout_unlock_output_fifo( p_aout );
/* Try to compensate the drift by doing some resampling. */ /* Try to compensate the drift by doing some resampling. */
msg_Warn( p_aout, "output date isn't PTS date, requesting " msg_Warn( p_aout, "output date isn't PTS date, requesting "
"resampling (%"PRId64")", delta ); "resampling (%"PRId64")", delta );
aout_lock_input_fifos( p_aout );
aout_lock_output_fifo( p_aout );
aout_FifoMoveDates( &p_aout->p_input->mixer.fifo, delta ); aout_FifoMoveDates( &p_aout->p_input->mixer.fifo, delta );
aout_FifoMoveDates( p_fifo, delta ); aout_FifoMoveDates( p_fifo, delta );
aout_unlock_input_fifos( p_aout );
} }
} }
aout_unlock_output_fifo( p_aout ); out:
aout_unlock( p_aout );
return p_buffer; return p_buffer;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment