]> git.sesse.net Git - vlc/commitdiff
Merge all audio output locks except volume control
authorRémi Denis-Courmont <remi@remlab.net>
Fri, 8 Jul 2011 19:59:27 +0000 (22:59 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Fri, 8 Jul 2011 19:59:27 +0000 (22:59 +0300)
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.

include/vlc_aout.h
src/audio_output/aout_internal.h
src/audio_output/common.c
src/audio_output/dec.c
src/audio_output/input.c
src/audio_output/intf.c
src/audio_output/mixer.c
src/audio_output/output.c

index f03aa834f94d4852502e55cb0422ccfd31860529..d2d04170e66fd76cf0c16faf3a6575ef2730f8c9 100644 (file)
@@ -178,22 +178,9 @@ struct aout_instance_t
 {
     VLC_COMMON_MEMBERS
 
-    /* Locks : please note that if you need several of these locks, it is
-     * mandatory (to avoid deadlocks) to take them in the following order :
-     * mixer_lock, p_input->lock, output_fifo_lock, input_fifos_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;
+    /* Lock for volume variables (FIXME: should be in input manager) */
+    vlc_mutex_t             volume_lock;
+    vlc_mutex_t             lock;
 
     /* Input streams & pre-filters */
     aout_input_t *          p_input;
index 0aa81cacd238aad6555d875e3bffa17d221710ff..4a236730c9a4759464f8b534b0e01930595a40c0 100644 (file)
@@ -97,8 +97,8 @@ struct aout_input_t
 /* From input.c : */
 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_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
-                    aout_buffer_t * p_buffer, int i_input_rate );
+void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
+                     aout_buffer_t * p_buffer, int i_input_rate );
 void aout_InputCheckAndRestart( aout_instance_t * p_aout, aout_input_t * p_input );
 
 /* From filters.c : */
@@ -138,7 +138,7 @@ bool aout_ChangeFilterString( vlc_object_t *, aout_instance_t *, const char *psz
 /* From dec.c */
 aout_input_t *aout_DecNew( aout_instance_t *, audio_sample_format_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 );
 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 );
@@ -157,81 +157,40 @@ bool aout_DecIsEmpty( aout_instance_t * p_aout, aout_input_t * p_input );
 #ifdef AOUT_DEBUG
 enum
 {
-    MIXER_LOCK=1,
-    INPUT_LOCK=2,
-    INPUT_FIFO_LOCK=4,
-    OUTPUT_FIFO_LOCK=8,
-    VOLUME_VARS_LOCK=16
+    OUTPUT_LOCK=1,
+    VOLUME_LOCK=2,
 };
 
-void aout_lock (unsigned);
-void aout_unlock (unsigned);
+void aout_lock_check (unsigned);
+void aout_unlock_check (unsigned);
 
 #else
-# define aout_lock( i )   (void)0
-# define aout_unlock( i ) (void)0
+# define aout_lock_check( i )   (void)0
+# define aout_unlock_check( i ) (void)0
 #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 );
-    vlc_mutex_lock( &p_aout->mixer_lock );
+    aout_lock_check( OUTPUT_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 );
-    vlc_mutex_unlock( &p_aout->mixer_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 );
+    aout_unlock_check( OUTPUT_LOCK );
+    vlc_mutex_unlock( &p_aout->lock );
 }
 
 static inline void aout_lock_volume( aout_instance_t *p_aout )
 {
-    aout_lock( VOLUME_VARS_LOCK );
-    vlc_mutex_lock( &p_aout->volume_vars_lock );
+    aout_lock_check( VOLUME_LOCK );
+    vlc_mutex_lock( &p_aout->volume_lock );
 }
 
 static inline void aout_unlock_volume( aout_instance_t *p_aout )
 {
-    aout_unlock( VOLUME_VARS_LOCK );
-    vlc_mutex_unlock( &p_aout->volume_vars_lock );
+    aout_unlock_check( VOLUME_LOCK );
+    vlc_mutex_unlock( &p_aout->volume_lock );
 }
 
 /* Helpers */
@@ -241,10 +200,10 @@ static inline void aout_unlock_volume( aout_instance_t *p_aout )
  * possible to take configuration changes into account */
 static inline void AoutInputsMarkToRestart( aout_instance_t *p_aout )
 {
-    aout_lock_mixer( p_aout );
+    aout_lock( p_aout );
     if( p_aout->p_input != NULL )
         p_aout->p_input->b_restart = true;
-    aout_unlock_mixer( p_aout );
+    aout_unlock( p_aout );
 }
 
 #endif /* !LIBVLC_AOUT_INTERNAL_H */
index 49aff60991daa6680b513b59ba4c60a6135bd161..ecd99f888b5af7f19c047a8382a0d250fe448ebf 100644 (file)
@@ -59,10 +59,8 @@ aout_instance_t * __aout_New( vlc_object_t * p_parent )
     }
 
     /* Initialize members. */
-    vlc_mutex_init( &p_aout->input_fifos_lock );
-    vlc_mutex_init( &p_aout->mixer_lock );
-    vlc_mutex_init( &p_aout->volume_vars_lock );
-    vlc_mutex_init( &p_aout->output_fifo_lock );
+    vlc_mutex_init( &p_aout->volume_lock );
+    vlc_mutex_init( &p_aout->lock );
     p_aout->p_input = NULL;
     p_aout->mixer_multiplier = 1.0;
     p_aout->p_mixer = NULL;
@@ -82,45 +80,24 @@ aout_instance_t * __aout_New( vlc_object_t * p_parent )
 static void aout_Destructor( vlc_object_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->mixer_lock );
-    vlc_mutex_destroy( &p_aout->volume_vars_lock );
-    vlc_mutex_destroy( &p_aout->output_fifo_lock );
+    vlc_mutex_destroy( &p_aout->volume_lock );
+    vlc_mutex_destroy( &p_aout->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
 /* Lock debugging */
 static __thread unsigned aout_locks = 0;
 
-void aout_lock (unsigned i)
+void aout_lock_check (unsigned i)
 {
     unsigned allowed;
     switch (i)
     {
-        case VOLUME_VARS_LOCK:
+        case VOLUME_LOCK:
             allowed = 0;
             break;
-        case MIXER_LOCK:
-            allowed = VOLUME_VARS_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;
+        case OUTPUT_LOCK:
+            allowed = VOLUME_LOCK;
             break;
         default:
             abort ();
@@ -136,7 +113,7 @@ void aout_lock (unsigned i)
     aout_locks |= i;
 }
 
-void aout_unlock (unsigned i)
+void aout_unlock_check (unsigned i)
 {
     assert (aout_locks & i);
     aout_locks &= ~i;
index 3f6565ced95f57442b6bc0a9ccd24c16641b2fd4..16d0aa8e38b4e876ddc060acfcc78b9a6957c4cf 100644 (file)
@@ -81,7 +81,6 @@ aout_input_t *aout_DecNew( aout_instance_t *p_aout,
     if( !p_input )
         return NULL;
 
-    vlc_mutex_init( &p_input->lock );
     p_input->b_error = true;
     p_input->b_paused = false;
     p_input->i_pause_date = 0;
@@ -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
      * p_input->lock. */
-    aout_lock_mixer( p_aout );
-    aout_lock_input_fifos( p_aout );
+    aout_lock( p_aout );
     assert( p_aout->p_input == NULL );
     p_aout->p_input = p_input;
 
@@ -119,28 +117,18 @@ aout_input_t *aout_DecNew( aout_instance_t *p_aout,
 
     aout_InputNew( p_aout, p_input, p_request_vout );
 out:
-    aout_unlock_input_fifos( p_aout );
-    aout_unlock_mixer( p_aout );
+    aout_unlock( p_aout );
     return p_input;
 }
 
 /*****************************************************************************
  * 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
-     * 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;
-    }
-
+    aout_lock( p_aout );
     /* Remove the input. */
+    assert( p_input == p_aout->p_input ); /* buggy decoder? */
     p_aout->p_input = NULL;
     aout_InputDelete( p_aout, 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-channels" );
 
-    aout_unlock_mixer( p_aout );
-
-    vlc_mutex_destroy( &p_input->lock );
+    aout_unlock( p_aout );
     free( p_input );
-    return 0;
 }
 
 
@@ -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,
                                    size_t i_nb_samples )
 {
-    block_t *block;
-    size_t 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 );
-
+    size_t length = i_nb_samples * p_input->input.i_bytes_per_frame
+                                 / p_input->input.i_frame_length;
+    block_t *block = block_Alloc( length );
     if( likely(block != NULL) )
     {
         block->i_nb_samples = i_nb_samples;
@@ -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_input->input.i_rate;
 
-    aout_lock_mixer( p_aout );
-    aout_lock_input( p_aout, p_input );
-
+    aout_lock( p_aout );
     if( p_input->b_error )
     {
-        aout_unlock_input( p_aout, p_input );
-        aout_unlock_mixer( p_aout );
-
+        aout_unlock( p_aout );
         aout_BufferFree( p_buffer );
         return -1;
     }
 
     aout_InputCheckAndRestart( p_aout, p_input );
-    aout_unlock_mixer( p_aout );
-
-    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;
-
+    aout_InputPlay( p_aout, p_input, p_buffer, i_input_rate );
     /* Run the mixer if it is able to run. */
-    aout_lock_mixer( p_aout );
     aout_MixerRun( p_aout, p_aout->mixer_multiplier );
-    aout_unlock_mixer( p_aout );
-
+    aout_unlock( p_aout );
     return 0;
 }
 
 int aout_DecGetResetLost( aout_instance_t *p_aout, aout_input_t *p_input )
 {
-    aout_lock_input( p_aout, p_input );
-    int i_value = p_input->i_buffer_lost;
+    int val;
+
+    aout_lock( p_aout );
+    val = p_input->i_buffer_lost;
     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 )
 {
     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 );
     if( p_input->b_paused )
     {
@@ -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->i_pause_date = i_date;
-    aout_unlock_input( p_aout, p_input );
 
     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 )
         {
             p->i_pts += i_duration;
         }
-        aout_unlock_mixer( p_aout );
     }
     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 )
 {
-    aout_lock_input_fifos( p_aout );
+    aout_lock( p_aout );
     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 )
 {
     mtime_t end_date;
 
-    aout_lock_input_fifos( p_aout );
+    aout_lock( p_aout );
     end_date = aout_FifoNextStart( &p_input->mixer.fifo );
-    aout_unlock_input_fifos( p_aout );
+    aout_unlock( p_aout );
     return end_date <= mdate();
 }
index b47b1c7184d9b80541ec93d6f6cf3f02a396f69c..add3263a14221c8d5fe2aabdadc04235ddadf595 100644 (file)
@@ -48,8 +48,7 @@
 
 #include "aout_internal.h"
 
-#define AOUT_ASSERT_MIXER_LOCKED vlc_assert_locked( &p_aout->mixer_lock )
-#define AOUT_ASSERT_INPUT_LOCKED vlc_assert_locked( &p_input->lock )
+#define AOUT_ASSERT_LOCKED vlc_assert_locked( &p_aout->lock )
 
 static void inputFailure( aout_instance_t *, aout_input_t *, const char * );
 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_
  *****************************************************************************/
 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 )
         return 0;
 
@@ -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 )
 {
-    AOUT_ASSERT_MIXER_LOCKED;
-    AOUT_ASSERT_INPUT_LOCKED;
+    AOUT_ASSERT_LOCKED;
 
     if( !p_input->b_restart )
         return;
 
-    aout_lock_input_fifos( p_aout );
-
     /* A little trick to avoid loosing our input fifo and properties */
 
     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
     p_input->i_pause_date = i_pause_date;
 
     p_input->b_restart = false;
-
-    aout_unlock_input_fifos( p_aout );
 }
 /*****************************************************************************
  * aout_InputPlay : play a buffer
@@ -494,16 +488,16 @@ void aout_InputCheckAndRestart( aout_instance_t * p_aout, aout_input_t * p_input
  *****************************************************************************/
 /* XXX Do not activate it !! */
 //#define AOUT_PROCESS_BEFORE_CHEKS
-int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
-                    aout_buffer_t * p_buffer, int i_input_rate )
+void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
+                     aout_buffer_t * p_buffer, int i_input_rate )
 {
     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 )
     {
         inputDrop( p_input, p_buffer );
-        return 0;
+        return;
     }
 
 #ifdef AOUT_PROCESS_BEFORE_CHEKS
@@ -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,
                       &p_buffer );
     if( !p_buffer )
-        return 0;
+        return;
 
     /* Actually run the resampler now. */
     if ( p_input->i_nb_resamplers > 0 )
@@ -523,11 +517,11 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
     }
 
     if( !p_buffer )
-        return 0;
+        return;
     if( p_buffer->i_nb_samples <= 0 )
     {
         block_Release( p_buffer );
-        return 0;
+        return;
     }
 #endif
 
@@ -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
      * this. We'll deal with that when pushing the buffer, and compensate
      * with the next incoming buffer. */
-    aout_lock_input_fifos( p_aout );
     start_date = aout_FifoNextStart( &p_input->mixer.fifo );
 
     if ( start_date != 0 && start_date < now )
@@ -573,7 +566,7 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
                   now - p_buffer->i_pts );
         inputDrop( p_input, p_buffer );
         inputResamplingStop( p_input );
-        goto out;
+        return;
     }
 
     /* 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,
         msg_Warn( p_aout, "buffer way too late (%"PRId64"), dropping buffer",
                   drift );
         inputDrop( p_input, p_buffer );
-        goto out;
+        return;
     }
 
 #ifndef AOUT_PROCESS_BEFORE_CHEKS
     /* Run pre-filters. */
     aout_FiltersPlay( p_input->pp_filters, p_input->i_nb_filters, &p_buffer );
     if( !p_buffer )
-        goto out;
+        return;
 #endif
 
     /* Run the resampler if needed.
@@ -691,20 +684,17 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
     }
 
     if( !p_buffer )
-        goto out;
+        return;
     if( p_buffer->i_nb_samples <= 0 )
     {
         block_Release( p_buffer );
-        goto out;
+        return;
     }
 #endif
 
     /* Adding the start date will be managed by aout_FifoPush(). */
     p_buffer->i_pts = start_date;
     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,
     VLC_UNUSED(newval); VLC_UNUSED(p_data);
     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 )
         ReplayGainSelect( p_aout, p_aout->p_input );
-    aout_unlock_mixer( p_aout );
+    aout_unlock( p_aout );
 
     return VLC_SUCCESS;
 }
index 9b6afa52a6f554c38162bdde85d3d9324fe37380..0d1c77404301046eded99b48951751bc9d8857b7 100644 (file)
@@ -85,12 +85,11 @@ static int commitVolume (vlc_object_t *obj, aout_instance_t *aout,
 
     if (aout != NULL)
     {
-        aout_lock_mixer (aout);
-        aout_lock_input_fifos (aout);
+        aout_lock (aout);
+#warning FIXME: wrong test. Need to check that aout_output is ready.
         if (aout->p_mixer != NULL)
             ret = aout->output.pf_volume_set (aout, volume, mute);
-        aout_unlock_input_fifos (aout);
-        aout_unlock_mixer (aout);
+        aout_unlock (aout);
 
         if (ret == 0)
             var_TriggerCallback (aout, "intf-change");
@@ -291,58 +290,46 @@ void aout_VolumeNoneInit( 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 );
-
-    if( p_aout->p_input == NULL )
+    aout_lock( p_aout );
+    p_input = p_aout->p_input;
+    if( p_input == NULL )
     {
-        aout_unlock_mixer( p_aout );
+        aout_unlock( p_aout );
         msg_Err( p_aout, "no decoder thread" );
         return -1;
     }
 
-    aout_lock_input( p_aout, p_aout->p_input );
-    aout_lock_input_fifos( p_aout );
-    aout_InputDelete( p_aout, p_aout->p_input );
-    aout_unlock_input_fifos( p_aout );
-
-    /* Lock all inputs. */
-    aout_lock_input_fifos( p_aout );
+    /* Reinitializes the output */
+    aout_InputDelete( p_aout, p_input );
     aout_MixerDelete( p_aout );
-
-    /* Re-open the output plug-in. */
     aout_OutputDelete( p_aout );
 
     /* FIXME: This function is notoriously dangerous/unsafe.
      * 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. */
-        vlc_mutex_unlock( &p_aout->p_input->lock );
-        aout_unlock_input_fifos( p_aout );
-        aout_unlock_mixer( p_aout );
+        aout_unlock( p_aout );
         return -1;
     }
 
     if ( aout_MixerNew( p_aout ) == -1 )
     {
         aout_OutputDelete( p_aout );
-        vlc_mutex_unlock( &p_aout->p_input->lock );
-        aout_unlock_input_fifos( p_aout );
-        aout_unlock_mixer( p_aout );
+        aout_unlock( p_aout );
         return -1;
     }
 
-    /* Re-open the input. */
-    aout_input_t * p_input = p_aout->p_input;
-    b_error |= aout_InputNew( p_aout, p_input, &p_input->request_vout );
-    aout_unlock_input( p_aout, p_input );
-
-    aout_unlock_input_fifos( p_aout );
-    aout_unlock_mixer( p_aout );
-
-    return b_error;
+    if( aout_InputNew( p_aout, p_input, &p_input->request_vout ) )
+    {
+#warning FIXME: deal with errors
+        aout_unlock( p_aout );
+        return -1;
+    }
+    aout_unlock( p_aout );
+    return 0;
 }
 
 /*****************************************************************************
index 0e1b8179edf3700dff0498e9950a532268e6117b..27eba46985af9f2dc767d0d016287d898b19c4e6 100644 (file)
@@ -44,7 +44,7 @@
 int aout_MixerNew( aout_instance_t * p_aout )
 {
     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) );
     if( !p_mixer )
@@ -75,14 +75,13 @@ int aout_MixerNew( aout_instance_t * p_aout )
  *****************************************************************************/
 void aout_MixerDelete( aout_instance_t * p_aout )
 {
+    vlc_assert_locked( &p_aout->lock );
+
     if( !p_aout->p_mixer )
         return;
 
     module_unneed( p_aout->p_mixer, p_aout->p_mixer->module );
-
     vlc_object_release( p_aout->p_mixer );
-
-    /* */
     p_aout->p_mixer = NULL;
 }
 
@@ -102,8 +101,7 @@ static int MixBuffer( aout_instance_t * p_aout, float volume )
      * "smart" audio outputs. */
     assert( samples > 0 );
 
-    aout_lock_input_fifos( p_aout );
-    aout_lock_output_fifo( p_aout );
+    vlc_assert_locked( &p_aout->lock );
 
     /* Retrieve the date of the next buffer. */
     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 )
         start_date = 0;
     }
 
-    aout_unlock_output_fifo( p_aout );
-
     /* See if we have enough data to prepare a new buffer for the audio output. */
     aout_buffer_t *p_buffer = p_fifo->p_first;
     if( p_buffer == NULL )
-        goto giveup;
+        return -1;
 
     /* Find the earliest start date available. */
     if ( !start_date )
@@ -153,7 +149,7 @@ static int MixBuffer( aout_instance_t * p_aout, float volume )
 
         p_buffer = p_fifo->p_first;
         if( p_buffer == NULL )
-            goto giveup;
+            return -1;
     }
 
     /* Check that we have enough samples. */
@@ -161,7 +157,7 @@ static int MixBuffer( aout_instance_t * p_aout, float volume )
     {
         p_buffer = p_buffer->p_next;
         if( p_buffer == NULL )
-            goto giveup;
+            return -1;
 
         /* Check that all buffers are contiguous. */
         if( prev_date != p_buffer->i_pts )
@@ -191,11 +187,9 @@ static int MixBuffer( aout_instance_t * p_aout, float volume )
         if( delta < 0 )
         {
             /* Is it really the best way to do it ? */
-            aout_lock_output_fifo( p_aout );
             aout_FifoSet( &p_aout->output.fifo, 0 );
             date_Set( &exact_start_date, 0 );
-            aout_unlock_output_fifo( p_aout );
-            goto giveup;
+            return -1;
         }
         if( delta > 0 )
         {
@@ -212,7 +206,7 @@ static int MixBuffer( aout_instance_t * p_aout, float volume )
         p_buffer = block_Alloc( needed );
         if( unlikely(p_buffer == NULL) )
             /* XXX: should free input buffers */
-            goto giveup;
+            return -1;
         p_buffer->i_nb_samples = samples;
 
         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 )
 
     /* Run the mixer. */
     p_mixer->mix( p_mixer, p_buffer, volume );
-    aout_unlock_input_fifos( p_aout );
     aout_OutputPlay( p_aout, p_buffer );
     return 0;
-
-giveup:
-    /* Interrupted before the end... We can't run. */
-    aout_unlock_input_fifos( p_aout );
-    return -1;
 }
 
 /*****************************************************************************
index fe4461a604dee4d042ef45aba5f70cb19dc647f8..9835d3f343d139d5b93981e317f441d098c0aee7 100644 (file)
@@ -33,6 +33,7 @@
 #include <vlc_cpu.h>
 #include <vlc_modules.h>
 
+#include "libvlc.h"
 #include "aout_internal.h"
 
 /*****************************************************************************
@@ -43,6 +44,7 @@
 int aout_OutputNew( aout_instance_t * p_aout,
                     const audio_sample_format_t * p_format )
 {
+    vlc_assert_locked( &p_aout->lock );
     p_aout->output.output = *p_format;
 
     /* Retrieve user defaults. */
@@ -155,13 +157,8 @@ int aout_OutputNew( aout_instance_t * p_aout,
 
     aout_FormatPrepare( &p_aout->output.output );
 
-    aout_lock_output_fifo( p_aout );
-
     /* Prepare FIFO. */
     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 );
 
     /* Calculate the resulting mixer output format. */
@@ -202,17 +199,16 @@ int aout_OutputNew( 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 )
         return;
+
     module_unneed( p_aout, p_aout->output.p_module );
     p_aout->output.p_module = NULL;
-
     aout_FiltersDestroyPipeline( p_aout->output.pp_filters,
                                  p_aout->output.i_nb_filters );
-
-    aout_lock_output_fifo( p_aout );
     aout_FifoDestroy( &p_aout->output.fifo );
-    aout_unlock_output_fifo( 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 )
 {
+    vlc_assert_locked( &p_aout->lock );
+
     aout_FiltersPlay( p_aout->output.pp_filters, p_aout->output.i_nb_filters,
                       &p_buffer );
-
     if( !p_buffer )
         return;
     if( p_buffer->i_buffer == 0 )
@@ -233,10 +230,8 @@ void aout_OutputPlay( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
         return;
     }
 
-    aout_lock_output_fifo( p_aout );
     aout_FifoPush( &p_aout->output.fifo, p_buffer );
     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 )
  */
 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 )
         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,
     aout_buffer_t * p_buffer;
     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.
      * 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,
                  "audio output is starving (no input), playing silence" );
         p_aout->output.b_starving = true;
 #endif
-        aout_unlock_output_fifo( p_aout );
-        return NULL;
+        goto out;
     }
 
     mtime_t delta = start_date - p_buffer->i_pts;
@@ -315,8 +309,8 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
             msg_Dbg( p_aout, "audio output is starving (%"PRId64"), "
                      "playing silence", -delta );
         p_aout->output.b_starving = true;
-        aout_unlock_output_fifo( p_aout );
-        return NULL;
+        p_buffer = NULL;
+        goto out;
     }
 
     p_aout->output.b_starving = false;
@@ -326,18 +320,15 @@ aout_buffer_t * aout_OutputNextBuffer( aout_instance_t * p_aout,
     {
         if( delta > AOUT_PTS_TOLERANCE || delta < -AOUT_PTS_TOLERANCE )
         {
-            aout_unlock_output_fifo( p_aout );
             /* Try to compensate the drift by doing some resampling. */
             msg_Warn( p_aout, "output date isn't PTS date, requesting "
                       "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_fifo, delta );
-            aout_unlock_input_fifos( p_aout );
         }
     }
-    aout_unlock_output_fifo( p_aout );
+out:
+    aout_unlock( p_aout );
     return p_buffer;
 }