[vlc-devel] [RFC PATCH 2/3] decoder: merge locks and conds

Thomas Guillem thomas at gllm.fr
Wed Apr 1 16:13:17 CEST 2015


---
 src/input/decoder.c | 148 ++++++++++++++++++++++++++++------------------------
 1 file changed, 79 insertions(+), 69 deletions(-)

diff --git a/src/input/decoder.c b/src/input/decoder.c
index 76c4038..1fd5b90 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -87,9 +87,7 @@ struct decoder_owner_sys_t
 
     /* Lock for communication with decoder thread */
     vlc_mutex_t lock;
-    vlc_cond_t  wait_request;
-    vlc_cond_t  wait_acknowledge;
-    vlc_cond_t  wait_fifo; /* TODO: merge with wait_acknowledge */
+    vlc_cond_t  wait;
 
     /* -- These variables need locking on write(only) -- */
     audio_output_t *p_aout;
@@ -209,15 +207,17 @@ static int aout_update_format( decoder_t *p_dec )
     if( p_owner->p_aout
      && !AOUT_FMTS_IDENTICAL(&p_dec->fmt_out.audio, &p_owner->fmt.audio) )
     {
-        audio_output_t *p_aout = p_owner->p_aout;
+        audio_output_t *p_aout;
 
         /* Parameters changed, restart the aout */
-        vlc_mutex_lock( &p_owner->lock );
 
-        aout_DecDelete( p_owner->p_aout );
+        vlc_mutex_lock( &p_owner->lock );
+        p_aout = p_owner->p_aout;
         p_owner->p_aout = NULL;
-
         vlc_mutex_unlock( &p_owner->lock );
+
+        aout_DecDelete( p_aout );
+
         input_resource_PutAout( p_owner->p_resource, p_aout );
     }
 
@@ -270,12 +270,13 @@ static int aout_update_format( decoder_t *p_dec )
         DecoderUpdateFormatLocked( p_dec );
         aout_FormatPrepare( &p_owner->fmt.audio );
 
-        if( unlikely(p_owner->b_paused) && p_aout != NULL )
-            /* fake pause if needed */
-            aout_DecChangePause( p_aout, true, mdate() );
-
+        /* fake pause if needed */
+        bool b_pause = unlikely(p_owner->b_paused) && p_aout != NULL;
         vlc_mutex_unlock( &p_owner->lock );
 
+        if( b_pause )
+            aout_DecChangePause( p_aout, true, mdate() );
+
         if( p_owner->p_input != NULL )
             input_SendEventAout( p_owner->p_input );
 
@@ -440,7 +441,7 @@ static picture_t *vout_new_buffer( decoder_t *p_dec )
         if( p_owner->b_waiting )
         {
             p_owner->b_has_data = true;
-            vlc_cond_signal( &p_owner->wait_acknowledge );
+            vlc_cond_signal( &p_owner->wait );
         }
         vlc_mutex_unlock( &p_owner->lock );
 
@@ -633,7 +634,7 @@ static bool DecoderWaitUnblock( decoder_t *p_dec )
             if( !p_owner->b_waiting || !p_owner->b_has_data )
                 break;
         }
-        vlc_cond_wait( &p_owner->wait_request, &p_owner->lock );
+        vlc_cond_wait( &p_owner->wait, &p_owner->lock );
     }
 
     return p_owner->b_flushing;
@@ -718,7 +719,7 @@ static void DecoderWaitDate( decoder_t *p_dec,
             break;
         }
     }
-    while( vlc_cond_timedwait( &p_owner->wait_request, &p_owner->lock,
+    while( vlc_cond_timedwait( &p_owner->wait, &p_owner->lock,
                                i_deadline ) == 0 );
 }
 
@@ -737,7 +738,7 @@ static int DecoderPlaySout( decoder_t *p_dec, block_t *p_sout_block )
     if( p_owner->b_waiting )
     {
         p_owner->b_has_data = true;
-        vlc_cond_signal( &p_owner->wait_acknowledge );
+        vlc_cond_signal( &p_owner->wait );
     }
 
     bool b_reject = DecoderWaitUnblock( p_dec );
@@ -885,7 +886,7 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
     if( p_owner->b_waiting && !p_owner->b_first )
     {
         p_owner->b_has_data = true;
-        vlc_cond_signal( &p_owner->wait_acknowledge );
+        vlc_cond_signal( &p_owner->wait );
     }
     bool b_first_after_wait = p_owner->b_waiting && p_owner->b_has_data;
 
@@ -1064,7 +1065,7 @@ static void DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio,
                               int *pi_played_sum, int *pi_lost_sum )
 {
     decoder_owner_sys_t *p_owner = p_dec->p_owner;
-    audio_output_t *p_aout = p_owner->p_aout;
+    audio_output_t *p_aout;
 
     /* */
     if( p_audio->i_pts <= VLC_TS_INVALID ) // FIXME --VLC_TS_INVALID verify audio_output/*
@@ -1081,7 +1082,7 @@ race:
     if( p_owner->b_waiting )
     {
         p_owner->b_has_data = true;
-        vlc_cond_signal( &p_owner->wait_acknowledge );
+        vlc_cond_signal( &p_owner->wait );
     }
 
     bool b_reject = DecoderWaitUnblock( p_dec );
@@ -1103,8 +1104,10 @@ race:
 
     if( unlikely(p_owner->b_paused != b_paused) )
         goto race; /* race with input thread? retry... */
+    p_aout = p_owner->p_aout;
     if( p_aout == NULL )
         b_reject = true;
+    vlc_mutex_unlock( &p_owner->lock );
 
     if( !b_reject )
     {
@@ -1119,7 +1122,6 @@ race:
         *pi_lost_sum += 1;
         block_Release( p_audio );
     }
-    vlc_mutex_unlock( &p_owner->lock );
 }
 
 static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
@@ -1241,7 +1243,7 @@ static void DecoderPlaySpu( decoder_t *p_dec, subpicture_t *p_subpic )
     if( p_owner->b_waiting )
     {
         p_owner->b_has_data = true;
-        vlc_cond_signal( &p_owner->wait_acknowledge );
+        vlc_cond_signal( &p_owner->wait );
     }
 
     bool b_reject = DecoderWaitUnblock( p_dec );
@@ -1326,7 +1328,7 @@ static void DecoderProcessOnFlush( decoder_t *p_dec )
     if( p_owner->b_flushing )
     {
         p_owner->b_flushing = false;
-        vlc_cond_signal( &p_owner->wait_acknowledge );
+        vlc_cond_signal( &p_owner->wait );
     }
     vlc_mutex_unlock( &p_owner->lock );
 }
@@ -1421,10 +1423,10 @@ static void *DecoderThread( void *p_data )
     {
         block_t *p_block;
 
-        vlc_fifo_Lock( p_owner->p_fifo );
-        vlc_fifo_CleanupPush( p_owner->p_fifo );
+        vlc_mutex_lock( &p_owner->lock );
+        mutex_cleanup_push( &p_owner->lock );
 
-        vlc_cond_signal( &p_owner->wait_fifo );
+        vlc_cond_signal( &p_owner->wait );
 
         while( vlc_fifo_IsEmpty( p_owner->p_fifo ) )
         {
@@ -1448,16 +1450,16 @@ static void *DecoderThread( void *p_data )
         int canc = vlc_savecancel();
         DecoderProcess( p_dec, p_block );
 
-        vlc_mutex_lock( &p_owner->lock );
         if( p_block == NULL )
         {   /* Draining: the decoder is drained and all decoded buffers are
              * queued to the output at this point. Now drain the output. */
             if( p_owner->p_aout != NULL )
                 aout_DecFlush( p_owner->p_aout, true );
         }
+        vlc_mutex_lock( &p_owner->lock );
         p_owner->b_drained = (p_block == NULL);
 
-        vlc_cond_signal( &p_owner->wait_acknowledge );
+        vlc_cond_signal( &p_owner->wait );
         vlc_mutex_unlock( &p_owner->lock );
         vlc_restorecancel( canc );
     }
@@ -1523,8 +1525,11 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
     p_owner->b_packetizer = b_packetizer;
     es_format_Init( &p_owner->fmt, UNKNOWN_ES, 0 );
 
+    vlc_mutex_init( &p_owner->lock );
+    vlc_cond_init( &p_owner->wait );
+
     /* decoder fifo */
-    p_owner->p_fifo = block_FifoNew();
+    p_owner->p_fifo = block_FifoNewExt( &p_owner->lock, &p_owner->wait );
     if( unlikely(p_owner->p_fifo == NULL) )
     {
         free( p_owner );
@@ -1594,11 +1599,6 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
     }
 
     /* */
-    vlc_mutex_init( &p_owner->lock );
-    vlc_cond_init( &p_owner->wait_request );
-    vlc_cond_init( &p_owner->wait_acknowledge );
-    vlc_cond_init( &p_owner->wait_fifo );
-
     p_owner->b_fmt_description = false;
     p_owner->p_description = NULL;
 
@@ -1711,10 +1711,8 @@ static void DeleteDecoder( decoder_t * p_dec )
         vlc_object_release( p_owner->p_packetizer );
     }
 
-    vlc_cond_destroy( &p_owner->wait_fifo );
-    vlc_cond_destroy( &p_owner->wait_acknowledge );
-    vlc_cond_destroy( &p_owner->wait_request );
     vlc_mutex_destroy( &p_owner->lock );
+    vlc_cond_destroy( &p_owner->wait );
 
     vlc_object_release( p_dec );
 
@@ -1833,7 +1831,7 @@ void input_DecoderDelete( decoder_t *p_dec )
     p_owner->b_paused = false;
     p_owner->b_waiting = false;
     p_owner->b_flushing = true;
-    vlc_cond_signal( &p_owner->wait_request );
+    vlc_cond_signal( &p_owner->wait );
     vlc_mutex_unlock( &p_owner->lock );
 
     vlc_join( p_owner->thread, NULL );
@@ -1852,18 +1850,13 @@ void input_DecoderDelete( decoder_t *p_dec )
     DeleteDecoder( p_dec );
 }
 
-/**
- * Put a block_t in the decoder's fifo.
- * Thread-safe w.r.t. the decoder. May be a cancellation point.
- *
- * \param p_dec the decoder object
- * \param p_block the data block
- */
-void input_DecoderDecode( decoder_t *p_dec, block_t *p_block, bool b_do_pace )
+static void DecoderDecode( decoder_t *p_dec, block_t *p_block,
+                           bool b_do_pace )
 {
     decoder_owner_sys_t *p_owner = p_dec->p_owner;
 
-    vlc_fifo_Lock( p_owner->p_fifo );
+    vlc_assert_locked( &p_owner->lock );
+
     if( !b_do_pace )
     {
         /* FIXME: ideally we would check the time amount of data
@@ -1882,11 +1875,26 @@ void input_DecoderDecode( decoder_t *p_dec, block_t *p_block, bool b_do_pace )
          * Locking is not necessary as b_waiting is only read, not written by
          * the decoder thread. */
         while( vlc_fifo_GetCount( p_owner->p_fifo ) >= 10 )
-            vlc_fifo_WaitCond( p_owner->p_fifo, &p_owner->wait_fifo );
+            vlc_fifo_Wait( p_owner->p_fifo );
     }
 
     vlc_fifo_QueueUnlocked( p_owner->p_fifo, p_block );
-    vlc_fifo_Unlock( p_owner->p_fifo );
+}
+
+/**
+ * Put a block_t in the decoder's fifo.
+ * Thread-safe w.r.t. the decoder. May be a cancellation point.
+ *
+ * \param p_dec the decoder object
+ * \param p_block the data block
+ */
+void input_DecoderDecode( decoder_t *p_dec, block_t *p_block, bool b_do_pace )
+{
+    decoder_owner_sys_t *p_owner = p_dec->p_owner;
+
+    vlc_mutex_lock( &p_owner->lock );
+    DecoderDecode( p_dec, p_block, b_do_pace );
+    vlc_mutex_unlock( &p_owner->lock );
 }
 
 bool input_DecoderIsEmpty( decoder_t * p_dec )
@@ -1924,10 +1932,10 @@ void input_DecoderDrain( decoder_t *p_dec )
 {
     decoder_owner_sys_t *p_owner = p_dec->p_owner;
 
-    vlc_fifo_Lock( p_owner->p_fifo );
+    vlc_mutex_lock( &p_owner->lock );
     p_owner->b_draining = true;
-    vlc_fifo_Signal( p_owner->p_fifo );
-    vlc_fifo_Unlock( p_owner->p_fifo );
+    vlc_cond_signal( &p_owner->wait );
+    vlc_mutex_unlock( &p_owner->lock );
 }
 
 static void DecoderFlush( decoder_t *p_dec )
@@ -1936,25 +1944,23 @@ static void DecoderFlush( decoder_t *p_dec )
 
     vlc_assert_locked( &p_owner->lock );
 
-    vlc_fifo_Lock( p_owner->p_fifo );
     /* Empty the fifo */
     block_ChainRelease( vlc_fifo_DequeueAllUnlocked( p_owner->p_fifo ) );
     p_owner->b_draining = false; /* flush supersedes drain */
-    vlc_fifo_Unlock( p_owner->p_fifo );
 
     /* Monitor for flush end */
     p_owner->b_flushing = true;
-    vlc_cond_signal( &p_owner->wait_request );
+    vlc_cond_signal( &p_owner->wait );
 
     /* Send a special block */
     block_t *p_null = DecoderBlockFlushNew();
     if( !p_null )
         return;
-    input_DecoderDecode( p_dec, p_null, false );
+    DecoderDecode( p_dec, p_null, false );
 
     /* */
     while( p_owner->b_flushing )
-        vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
+        vlc_cond_wait( &p_owner->wait, &p_owner->lock );
 }
 
 /**
@@ -2055,6 +2061,8 @@ int input_DecoderGetCcState( decoder_t *p_dec, bool *pb_decode, int i_channel )
 void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date )
 {
     decoder_owner_sys_t *p_owner = p_dec->p_owner;
+    audio_output_t *p_aout;
+    vout_thread_t *p_vout;
 
     /* Normally, p_owner->b_paused != b_paused here. But if a track is added
      * while the input is paused (e.g. add sub file), then b_paused is
@@ -2066,7 +2074,10 @@ void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date )
     p_owner->b_paused = b_paused;
     p_owner->pause.i_date = i_date;
     p_owner->pause.i_ignore = 0;
-    vlc_cond_signal( &p_owner->wait_request );
+    vlc_cond_signal( &p_owner->wait );
+    p_aout = p_owner->p_aout;
+    p_vout = p_owner->p_vout;
+    vlc_mutex_unlock( &p_owner->lock );
 
     /* XXX only audio and video output have to be paused.
      * - for sout it is useless
@@ -2074,15 +2085,14 @@ void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date )
      */
     if( p_owner->fmt.i_cat == AUDIO_ES )
     {
-        if( p_owner->p_aout )
-            aout_DecChangePause( p_owner->p_aout, b_paused, i_date );
+        if( p_aout )
+            aout_DecChangePause( p_aout, b_paused, i_date );
     }
     else if( p_owner->fmt.i_cat == VIDEO_ES )
     {
-        if( p_owner->p_vout )
-            vout_ChangePause( p_owner->p_vout, b_paused, i_date );
+        if( p_vout )
+            vout_ChangePause( p_vout, b_paused, i_date );
     }
-    vlc_mutex_unlock( &p_owner->lock );
 }
 
 void input_DecoderChangeDelay( decoder_t *p_dec, mtime_t i_delay )
@@ -2104,7 +2114,7 @@ void input_DecoderStartWait( decoder_t *p_dec )
     p_owner->b_first = true;
     p_owner->b_has_data = false;
     p_owner->b_waiting = true;
-    vlc_cond_signal( &p_owner->wait_request );
+    vlc_cond_signal( &p_owner->wait );
     vlc_mutex_unlock( &p_owner->lock );
 }
 
@@ -2116,7 +2126,7 @@ void input_DecoderStopWait( decoder_t *p_dec )
 
     vlc_mutex_lock( &p_owner->lock );
     p_owner->b_waiting = false;
-    vlc_cond_signal( &p_owner->wait_request );
+    vlc_cond_signal( &p_owner->wait );
     vlc_mutex_unlock( &p_owner->lock );
 }
 
@@ -2127,7 +2137,6 @@ void input_DecoderWait( decoder_t *p_dec )
     assert( p_owner->b_waiting );
 
     vlc_mutex_lock( &p_owner->lock );
-    vlc_fifo_Lock( p_owner->p_fifo );
     while( !p_owner->b_has_data )
     {
         if( p_owner->b_idle && vlc_fifo_IsEmpty( p_owner->p_fifo ) )
@@ -2136,11 +2145,8 @@ void input_DecoderWait( decoder_t *p_dec )
             break;
         }
         vlc_fifo_Signal( p_owner->p_fifo );
-        vlc_fifo_Unlock( p_owner->p_fifo );
-        vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
-        vlc_fifo_Lock( p_owner->p_fifo );
+        vlc_cond_wait( &p_owner->wait, &p_owner->lock );
     }
-    vlc_fifo_Unlock( p_owner->p_fifo );
     vlc_mutex_unlock( &p_owner->lock );
 }
 
@@ -2155,9 +2161,13 @@ void input_DecoderFrameNext( decoder_t *p_dec, mtime_t *pi_duration )
     {
         if( p_owner->b_paused && p_owner->p_vout )
         {
+            vlc_mutex_unlock( &p_owner->lock );
+
             vout_NextPicture( p_owner->p_vout, pi_duration );
+
+            vlc_mutex_lock( &p_owner->lock );
             p_owner->pause.i_ignore++;
-            vlc_cond_signal( &p_owner->wait_request );
+            vlc_cond_signal( &p_owner->wait );
         }
     }
     else
-- 
2.1.3




More information about the vlc-devel mailing list