[vlc-devel] [PATCH] decoder: unblock broken decoders when seeking on pause

Thomas Guillem tom at gllm.fr
Tue Oct 28 09:43:41 CET 2014


MediaCodec or iomx with direct rendering can be stuck waiting for an output
buffer when video is paused since output buffers are released by vout.

A previous hack was made in order to fix a deadlock when theses broken decoders
were stuck and when exit was requested. These decoders returned an invalid
picture after a small delay, then DecoderIsExitRequested in DecoderDecodeVideo
was checked and these decoders could be exited without blocking.

This previous hack didn't fix a deadlock when video was flushed, due to a seek,
on pause. Indeed, when stuck, these broken decoders are feed with the same
block. Therefore they won't receive a new block containing the FLUSH flags and
they will be stuck returning an invalid picture.

One way to fix this deadlock is to check for DecoderIsFlushing, at the end of
the DecoderDecodeVideo loop, in order to break the loop if the decoder is
flushing. This check is done at the end of the loop because the output buffer
may be valid and should be processed. If this loop is broken, the
DecoderProcess function will terminate, and a new block containing a FLUSH
flags will be given to the decoder. Then the decoder will flush and won't be be
blocked anymore.

(fixes #12397)
---
 src/input/decoder.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/src/input/decoder.c b/src/input/decoder.c
index 972522a..2bca404 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -1229,6 +1229,13 @@ static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
         }
 
         DecoderPlayAudio( p_dec, p_aout_buf, &i_played, &i_lost );
+
+        if( p_block && DecoderIsFlushing( p_dec ) )
+        {
+            /* It prevent freezing VLC in case of broken decoder */
+            block_Release( p_block );
+            break;
+        }
     }
 
     /* Update ugly stat */
@@ -1402,6 +1409,13 @@ static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
             DecoderGetCc( p_dec, p_dec );
 
         DecoderPlayVideo( p_dec, p_pic, &i_displayed, &i_lost );
+
+        if( p_block && DecoderIsFlushing( p_dec ) )
+        {
+            /* It prevent freezing VLC in case of broken decoder */
+            block_Release( p_block );
+            break;
+        }
     }
 
     /* Update ugly stat */
-- 
2.1.0




More information about the vlc-devel mailing list