[vlc-devel] [V3 PATCH 3/3] dec: update pause/rate when the output is restarted

Thomas Guillem thomas at gllm.fr
Tue Jul 3 11:15:52 CEST 2018


The aout/vout paused/rate state was not set if the output was restarted within
the lifetime of the decoder.
---
 src/input/decoder.c | 66 +++++++++++++++++++++++++++------------------
 1 file changed, 40 insertions(+), 26 deletions(-)

diff --git a/src/input/decoder.c b/src/input/decoder.c
index 27dbfba50d..3e5d14814c 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -112,10 +112,12 @@ struct decoder_owner
     /* Preroll */
     vlc_tick_t i_preroll_end;
     /* Pause & Rate */
-    vlc_tick_t pause_date;
-    float rate;
+    vlc_tick_t request_pause_date;
+    float request_rate;
+    float output_rate;
     unsigned frames_countdown;
-    bool paused;
+    bool request_paused;
+    bool output_paused;
 
     bool error;
 
@@ -284,6 +286,17 @@ static void DecoderUpdateFormatLocked( decoder_t *p_dec )
 /*****************************************************************************
  * Buffers allocation callbacks for the decoders
  *****************************************************************************/
+static void out_reset_state( decoder_t *p_dec )
+{
+    struct decoder_owner *p_owner = dec_get_owner( p_dec );
+
+    vlc_fifo_Lock( p_owner->p_fifo );
+    p_owner->output_rate = 1.f;
+    p_owner->output_paused = false;
+    vlc_fifo_Unlock( p_owner->p_fifo );
+
+}
+
 static vout_thread_t *aout_request_vout( void *p_private,
                                          vout_thread_t *p_vout,
                                          const video_format_t *p_fmt, bool b_recyle )
@@ -406,6 +419,8 @@ static int aout_update_format( decoder_t *p_dec )
             p_owner->fmt.audio.i_bytes_per_frame;
         p_dec->fmt_out.audio.i_frame_length =
             p_owner->fmt.audio.i_frame_length;
+
+        out_reset_state( p_dec );
     }
     return 0;
 }
@@ -538,6 +553,7 @@ static int vout_update_format( decoder_t *p_dec )
             msg_Err( p_dec, "failed to create video output" );
             return -1;
         }
+        out_reset_state( p_dec );
     }
 
     if ( memcmp( &p_dec->fmt_out.video.mastering,
@@ -628,7 +644,7 @@ static vlc_tick_t DecoderGetDisplayDate( decoder_t *p_dec, vlc_tick_t i_ts )
     struct decoder_owner *p_owner = dec_get_owner( p_dec );
 
     vlc_mutex_lock( &p_owner->lock );
-    if( p_owner->b_waiting || p_owner->paused )
+    if( p_owner->b_waiting || p_owner->request_paused )
         i_ts = VLC_TICK_INVALID;
     vlc_mutex_unlock( &p_owner->lock );
 
@@ -1016,7 +1032,7 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
     /* FIXME: The *input* FIFO should not be locked here. This will not work
      * properly if/when pictures are queued asynchronously. */
     vlc_fifo_Lock( p_owner->p_fifo );
-    if( unlikely(p_owner->paused) && likely(p_owner->frames_countdown > 0) )
+    if( unlikely(p_owner->request_paused) && likely(p_owner->frames_countdown > 0) )
         p_owner->frames_countdown--;
     vlc_fifo_Unlock( p_owner->p_fifo );
 
@@ -1561,8 +1577,6 @@ static void *DecoderThread( void *p_data )
 {
     decoder_t *p_dec = (decoder_t *)p_data;
     struct decoder_owner *p_owner = dec_get_owner( p_dec );
-    float rate = 1.f;
-    bool paused = false;
 
     /* The decoder's main loop */
     vlc_fifo_Lock( p_owner->p_fifo );
@@ -1591,11 +1605,11 @@ static void *DecoderThread( void *p_data )
             continue;
         }
 
-        if( paused != p_owner->paused )
+        if( p_owner->output_paused != p_owner->request_paused )
         {   /* Update playing/paused status of the output */
             int canc = vlc_savecancel();
-            bool request_paused = p_owner->paused;
-            vlc_tick_t request_date = p_owner->pause_date;
+            bool request_paused = p_owner->request_paused;
+            vlc_tick_t request_date = p_owner->request_pause_date;
 
             vlc_fifo_Unlock( p_owner->p_fifo );
 
@@ -1605,14 +1619,14 @@ static void *DecoderThread( void *p_data )
             vlc_restorecancel( canc );
             vlc_fifo_Lock( p_owner->p_fifo );
             if (success)
-                paused = request_paused;
+                p_owner->output_paused = request_paused;
             continue;
         }
 
-        if( rate != p_owner->rate )
+        if( p_owner->output_rate != p_owner->request_rate )
         {
             int canc = vlc_savecancel();
-            float request_rate = p_owner->rate;
+            float request_rate = p_owner->request_rate;
 
             vlc_fifo_Unlock( p_owner->p_fifo );
 
@@ -1622,10 +1636,10 @@ static void *DecoderThread( void *p_data )
             vlc_restorecancel( canc );
             vlc_fifo_Lock( p_owner->p_fifo );
             if (success)
-                rate = request_rate;
+                p_owner->output_rate = request_rate;
         }
 
-        if( p_owner->paused && p_owner->frames_countdown == 0 )
+        if( p_owner->request_paused && p_owner->frames_countdown == 0 )
         {   /* Wait for resumption from pause */
             p_owner->b_idle = true;
             vlc_cond_signal( &p_owner->wait_acknowledge );
@@ -1746,9 +1760,9 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
     p_owner->b_fmt_description = false;
     p_owner->p_description = NULL;
 
-    p_owner->rate = 1.f;
-    p_owner->paused = false;
-    p_owner->pause_date = VLC_TICK_INVALID;
+    p_owner->request_rate = p_owner->output_rate = 1.f;
+    p_owner->request_paused = p_owner->output_paused = false;
+    p_owner->request_pause_date = VLC_TICK_INVALID;
     p_owner->frames_countdown = 0;
 
     p_owner->b_waiting = false;
@@ -2209,7 +2223,7 @@ void input_DecoderFlush( decoder_t *p_dec )
 
     /* Flush video/spu decoder when paused: increment frames_countdown in order
      * to display one frame/subtitle */
-    if( p_owner->paused
+    if( p_owner->request_paused
      && ( p_owner->fmt.i_cat == VIDEO_ES || p_owner->fmt.i_cat == SPU_ES )
      && p_owner->frames_countdown == 0 )
         p_owner->frames_countdown++;
@@ -2330,8 +2344,8 @@ void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, vlc_tick_t i_dat
      * while the input is paused (e.g. add sub file), then b_paused is
      * (incorrectly) false. FIXME: This is a bug in the decoder owner. */
     vlc_fifo_Lock( p_owner->p_fifo );
-    p_owner->paused = b_paused;
-    p_owner->pause_date = i_date;
+    p_owner->request_paused = b_paused;
+    p_owner->request_pause_date = i_date;
     p_owner->frames_countdown = 0;
     vlc_fifo_Signal( p_owner->p_fifo );
     vlc_fifo_Unlock( p_owner->p_fifo );
@@ -2342,7 +2356,7 @@ void input_DecoderChangeRate( decoder_t *dec, float rate )
     struct decoder_owner *owner = dec_get_owner( dec );
 
     vlc_fifo_Lock( owner->p_fifo );
-    owner->rate = rate;
+    owner->request_rate = rate;
     vlc_fifo_Signal( owner->p_fifo );
     vlc_fifo_Unlock( owner->p_fifo );
 }
@@ -2391,9 +2405,9 @@ void input_DecoderWait( decoder_t *p_dec )
     vlc_mutex_lock( &p_owner->lock );
     while( !p_owner->b_has_data )
     {
-        /* Don't need to lock p_owner->paused since it's only modified by the
-         * owner */
-        if( p_owner->paused )
+        /* Don't need to lock p_owner->request_paused since it's only modified
+         * by the owner */
+        if( p_owner->request_paused )
             break;
         vlc_fifo_Lock( p_owner->p_fifo );
         if( p_owner->b_idle && vlc_fifo_IsEmpty( p_owner->p_fifo ) )
@@ -2412,7 +2426,7 @@ void input_DecoderFrameNext( decoder_t *p_dec, vlc_tick_t *pi_duration )
 {
     struct decoder_owner *p_owner = dec_get_owner( p_dec );
 
-    assert( p_owner->paused );
+    assert( p_owner->request_paused );
     *pi_duration = 0;
 
     vlc_fifo_Lock( p_owner->p_fifo );
-- 
2.18.0



More information about the vlc-devel mailing list