[vlc-devel] [PATCH 2/8] sout_mux/core: handle drain

Thomas Guillem thomas at gllm.fr
Mon Jan 29 18:25:50 CET 2018


Like for decoder_t, a drain is requested when sending/writing a NULL block.

Muxers should drain themselves when they receive the last pf_delstream callback
(call the new sout_MuxIsDrained() helper to know when it happens).
---
 include/vlc_sout.h                |  9 +++++++++
 src/stream_output/stream_output.c | 38 ++++++++++++++++++++++++++++----------
 2 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/include/vlc_sout.h b/include/vlc_sout.h
index e75bf89f86..8ba55b75be 100644
--- a/include/vlc_sout.h
+++ b/include/vlc_sout.h
@@ -166,6 +166,7 @@ struct sout_input_t
     block_fifo_t      *p_fifo;
     void              *p_sys;
     es_format_t        fmt;
+    bool               eof;
 };
 
 
@@ -173,10 +174,18 @@ VLC_API sout_mux_t * sout_MuxNew( sout_instance_t*, const char *, sout_access_ou
 VLC_API sout_input_t *sout_MuxAddStream( sout_mux_t *, const es_format_t * ) VLC_USED;
 VLC_API void sout_MuxDeleteStream( sout_mux_t *, sout_input_t * );
 VLC_API void sout_MuxDelete( sout_mux_t * );
+/* Send a buffer to the muxer, request a drain by sending a NULL buffer */
 VLC_API int sout_MuxSendBuffer( sout_mux_t *, sout_input_t  *, block_t * );
 VLC_API int sout_MuxGetStream(sout_mux_t *, unsigned, mtime_t *);
 VLC_API void sout_MuxFlush( sout_mux_t *, sout_input_t * );
 
+/* Returns true if the mux is drained. Must be called from the pf_delstream
+ * callback. */
+static inline bool sout_MuxIsDrained( sout_mux_t *p_mux )
+{
+    return p_mux->i_nb_inputs == 1;
+}
+
 static inline int sout_MuxControl( sout_mux_t *p_mux, int i_query, ... )
 {
     va_list args;
diff --git a/src/stream_output/stream_output.c b/src/stream_output/stream_output.c
index 2caf902c19..f089d4518d 100644
--- a/src/stream_output/stream_output.c
+++ b/src/stream_output/stream_output.c
@@ -467,6 +467,7 @@ sout_input_t *sout_MuxAddStream( sout_mux_t *p_mux, const es_format_t *p_fmt )
 
     p_input->p_fifo = block_FifoNew();
     p_input->p_sys  = NULL;
+    p_input->eof    = false;
 
     TAB_APPEND( p_mux->i_nb_inputs, p_mux->pp_inputs, p_input );
     if( p_mux->pf_addstream( p_mux, p_input ) < 0 )
@@ -521,17 +522,24 @@ void sout_MuxDeleteStream( sout_mux_t *p_mux, sout_input_t *p_input )
  * sout_MuxSendBuffer:
  *****************************************************************************/
 int sout_MuxSendBuffer( sout_mux_t *p_mux, sout_input_t *p_input,
-                         block_t *p_buffer )
+                        block_t *p_buffer )
 {
-    mtime_t i_dts = p_buffer->i_dts;
-    block_FifoPut( p_input->p_fifo, p_buffer );
+    mtime_t i_dts;
 
-    if( p_mux->p_sout->i_out_pace_nocontrol )
+    if (unlikely(p_buffer == NULL))
+        p_input->eof = true;
+    else
     {
-        mtime_t current_date = mdate();
-        if ( current_date > i_dts )
-            msg_Warn( p_mux, "late buffer for mux input (%"PRId64")",
-                      current_date - i_dts );
+        i_dts = p_buffer->i_dts;
+        block_FifoPut( p_input->p_fifo, p_buffer );
+
+        if( p_mux->p_sout->i_out_pace_nocontrol )
+        {
+            mtime_t current_date = mdate();
+            if ( current_date > i_dts )
+                msg_Warn( p_mux, "late buffer for mux input (%"PRId64")",
+                          current_date - i_dts );
+        }
     }
 
     if( p_mux->b_waiting_stream )
@@ -547,7 +555,17 @@ int sout_MuxSendBuffer( sout_mux_t *p_mux, sout_input_t *p_input,
             return VLC_SUCCESS;
         p_mux->b_waiting_stream = false;
     }
-    return p_mux->pf_mux( p_mux );
+
+    int ret = p_mux->pf_mux( p_mux );
+
+    if( unlikely( p_buffer == NULL ) )
+    {
+        /* Draining: remove the current stream, the muxer will drain itself
+         * when all streams are removed */
+        sout_MuxDeleteStream( p_mux, p_input );
+    }
+
+    return ret;
 }
 
 void sout_MuxFlush( sout_mux_t *p_mux, sout_input_t *p_input )
@@ -571,7 +589,7 @@ int sout_MuxGetStream( sout_mux_t *p_mux, unsigned i_blocks, mtime_t *pi_dts )
         sout_input_t *p_input = p_mux->pp_inputs[i];
         block_t *p_data;
 
-        if( block_FifoCount( p_input->p_fifo ) < i_blocks )
+        if( block_FifoCount( p_input->p_fifo ) < ( p_input->eof ? 1 : i_blocks ) )
         {
             if( (!p_mux->b_add_stream_any_time) &&
                 (p_input->p_fmt->i_cat != SPU_ES ) )
-- 
2.11.0



More information about the vlc-devel mailing list