[vlc-commits] [Git][videolan/vlc][master] input: decoder: fix drain/flush execution order

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sat Dec 3 15:31:36 UTC 2022



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
037edac3 by Thomas Guillem at 2022-12-03T15:17:38+00:00
input: decoder: fix drain/flush execution order

This fixes a possible (but unlikely) assert, from
vlc_aout_stream_Drain():
assert(atomic_load_explicit(&stream->drain_deadline,
                            memory_order_relaxed) == VLC_TICK_INVALID);

It can happen when vlc_aout_stream_Drain() is called more than time in a
row, that is illegal: Drain should be the last command or can be
cancelled by a Flush to continue the playback.

If drain and flush are called in that order
- vlc_input_decoder_Drain()
- vlc_input_decoder_Flush()
- vlc_input_decoder_Drain()

It was possible that vlc_aout_stream_Flush() was called before the first
vlc_input_decoder_Drain().

To fix this issue, cancel the draining state when flushing the decoder
and do check that the decoder is still draining after unlocking/locking
(after draining the decoder module).

Regression from 34a548cc02ce67920efbd7fdaa5af752199236a8

Fixes #27499

- - - - -


1 changed file:

- src/input/decoder.c


Changes:

=====================================
src/input/decoder.c
=====================================
@@ -1791,16 +1791,17 @@ static void *DecoderThread( void *p_data )
         DecoderThread_ProcessInput( p_owner, frame );
 
         vlc_fifo_Lock(p_owner->p_fifo);
-        if( frame == NULL && p_owner->dec.fmt_in->i_cat == AUDIO_ES )
-        {   /* 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_astream != NULL )
+        if( p_owner->b_draining && frame == NULL )
+        {
+            p_owner->b_draining = false;
+
+            if( p_owner->dec.fmt_in->i_cat == AUDIO_ES && p_owner->p_astream != NULL )
+            {   /* Draining: the decoder is drained and all decoded buffers are
+                 * queued to the output at this point. Now drain the output. */
                 vlc_aout_stream_Drain( p_owner->p_astream );
+            }
         }
 
-        /* TODO? Wait for draining instead of polling. */
-        if( p_owner->b_draining && (frame == NULL) )
-            p_owner->b_draining = false;
         vlc_cond_signal( &p_owner->wait_acknowledge );
     }
 
@@ -2386,6 +2387,7 @@ void vlc_input_decoder_Flush( vlc_input_decoder_t *p_owner )
      * dequeued by DecoderThread and there is no need to flush a second time in
      * a row. */
     p_owner->flushing = true;
+    p_owner->b_draining = false;
 
     /* Flush video/spu decoder when paused: increment frames_countdown in order
      * to display one frame/subtitle */



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/037edac375bd08e7bbe7346fd6fd1f060816bc93

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/037edac375bd08e7bbe7346fd6fd1f060816bc93
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list