[vlc-devel] [RFC PATCH] decoder: do not depend on allocated block for flush

Thomas Guillem thomas at gllm.fr
Wed Nov 18 18:24:42 CET 2015


With this patch, a flush won't fail because of a block_Alloc failure.
---
 src/input/decoder.c | 46 ++++++++++++++--------------------------------
 1 file changed, 14 insertions(+), 32 deletions(-)

diff --git a/src/input/decoder.c b/src/input/decoder.c
index c9f401b..24e70e9 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -109,6 +109,7 @@ struct decoder_owner_sys_t
     bool b_has_data;
 
     /* Flushing */
+    block_t flush_block;
     bool flushing;
     bool b_draining;
     atomic_bool drained;
@@ -209,18 +210,8 @@ static void DecoderUpdateFormatLocked( decoder_t *p_dec )
     p_owner->b_fmt_description = true;
 }
 
-static block_t *DecoderBlockFlushNew()
+static void BlockNoRelease( block_t *b )
 {
-    block_t *p_null = block_Alloc( 128 );
-    if( !p_null )
-        return NULL;
-
-    p_null->i_flags |= BLOCK_FLAG_DISCONTINUITY |
-                       BLOCK_FLAG_CORRUPTED |
-                       BLOCK_FLAG_CORE_FLUSH;
-    memset( p_null->p_buffer, 0, p_null->i_buffer );
-
-    return p_null;
 }
 
 /*****************************************************************************
@@ -984,11 +975,7 @@ static void DecoderProcessVideo( decoder_t *p_dec, block_t *p_block, bool b_flus
         /* The packetizer does not output a block that tell the decoder to flush
          * do it ourself */
         if( b_flush )
-        {
-            block_t *p_null = DecoderBlockFlushNew();
-            if( p_null )
-                DecoderDecodeVideo( p_dec, p_null );
-        }
+            DecoderDecodeVideo( p_dec, &p_owner->flush_block );
     }
     else
     {
@@ -1136,11 +1123,7 @@ static void DecoderProcessAudio( decoder_t *p_dec, block_t *p_block, bool b_flus
         /* The packetizer does not output a block that tell the decoder to flush
          * do it ourself */
         if( b_flush )
-        {
-            block_t *p_null = DecoderBlockFlushNew();
-            if( p_null )
-                DecoderDecodeAudio( p_dec, p_null );
-        }
+            DecoderDecodeAudio( p_dec, &p_owner->flush_block );
     }
     else
     {
@@ -1261,9 +1244,8 @@ static void DecoderProcess( decoder_t *p_dec, block_t *p_block )
         return;
     }
 
-    if( p_block && p_block->i_buffer <= 0 )
+    if( p_block && p_block->i_buffer <= 0 && !b_flush_request )
     {
-        assert( !b_flush_request );
         block_Release( p_block );
         return;
     }
@@ -1271,7 +1253,7 @@ static void DecoderProcess( decoder_t *p_dec, block_t *p_block )
 #ifdef ENABLE_SOUT
     if( p_owner->b_packetizer )
     {
-        if( p_block )
+        if( p_block && p_block != &p_owner->flush_block )
             p_block->i_flags &= ~BLOCK_FLAG_CORE_PRIVATE_MASK;
 
         DecoderProcessSout( p_dec, p_block );
@@ -1288,7 +1270,8 @@ static void DecoderProcess( decoder_t *p_dec, block_t *p_block )
 
             b_flush = !b_flushing && b_flush_request;
 
-            p_block->i_flags &= ~BLOCK_FLAG_CORE_PRIVATE_MASK;
+            if( p_block != &p_owner->flush_block )
+                p_block->i_flags &= ~BLOCK_FLAG_CORE_PRIVATE_MASK;
         }
 
         if( p_dec->fmt_out.i_cat == AUDIO_ES )
@@ -1334,16 +1317,10 @@ static void *DecoderThread( void *p_data )
              * for the sake of flushing (glitches could otherwise happen). */
             int canc = vlc_savecancel();
 
-            /* TODO: add a flush callback to decoder, do not depend on an
-             * allocated block */
-            block_t *dummy = DecoderBlockFlushNew();
-            if( unlikely(dummy == NULL) )
-                msg_Err( p_dec, "cannot flush" );
-
             vlc_fifo_Unlock( p_owner->p_fifo );
 
             /* Flush the decoder (and the output) */
-            DecoderProcess( p_dec, dummy );
+            DecoderProcess( p_dec, &p_owner->flush_block );
 
             vlc_fifo_Lock( p_owner->p_fifo );
             vlc_restorecancel( canc );
@@ -1481,6 +1458,11 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
     p_owner->b_first = true;
     p_owner->b_has_data = false;
 
+    block_Init( &p_owner->flush_block, NULL, 0 );
+    p_owner->flush_block.pf_release = BlockNoRelease;
+    p_owner->flush_block.i_flags = BLOCK_FLAG_DISCONTINUITY |
+                                   BLOCK_FLAG_CORRUPTED |
+                                   BLOCK_FLAG_CORE_FLUSH;
     p_owner->flushing = false;
     p_owner->b_draining = false;
     atomic_init( &p_owner->drained, false );
-- 
2.1.4



More information about the vlc-devel mailing list