[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