[vlc-devel] [PATCH] input: don't send ES_OUT_ *PCR/SET_NEXT_DISPLAY_TIME from slaves
Thomas Guillem
thomas at gllm.fr
Thu Apr 5 17:04:36 CEST 2018
This avoid having slaves messing up the timing of the main input.
Fixes #19689
---
src/input/es_out.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++
src/input/es_out.h | 8 +++++++
src/input/input.c | 36 +++++++++++++++++++-----------
src/input/input_internal.h | 1 +
4 files changed, 87 insertions(+), 13 deletions(-)
diff --git a/src/input/es_out.c b/src/input/es_out.c
index db465feca8..8d4dceae26 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -3376,3 +3376,58 @@ static void EsDeleteInfo( es_out_t *out, es_out_id_t *es )
free( psz_info_category );
}
}
+
+static es_out_id_t *SlaveEsOutAdd( es_out_t *out, const es_format_t *fmt )
+{
+ es_out_t *main_out = (void *) out->p_sys;
+ return es_out_Add( main_out, fmt );
+}
+
+static int SlaveEsOutSend( es_out_t *out, es_out_id_t *id, block_t *block )
+{
+ es_out_t *main_out = (void *) out->p_sys;
+ return es_out_Send( main_out, id, block );
+}
+
+static void SlaveEsOutDel( es_out_t *out, es_out_id_t *id )
+{
+ es_out_t *main_out = (void *) out->p_sys;
+ es_out_Del( main_out, id );
+}
+
+static int SlaveEsOutControl( es_out_t *out, int i_query, va_list args )
+{
+ switch( i_query )
+ {
+ /* Drop controls that could mess-up the main input */
+ case ES_OUT_SET_PCR:
+ case ES_OUT_SET_GROUP_PCR:
+ case ES_OUT_RESET_PCR:
+ case ES_OUT_SET_NEXT_DISPLAY_TIME:
+ return VLC_EGENERIC;
+ }
+
+ es_out_t *main_out = (void *) out->p_sys;
+ return es_out_vaControl( main_out, i_query, args );
+}
+
+static void SlaveEsOutDelete ( es_out_t *out )
+{
+ free( out );
+}
+
+es_out_t *es_out_NewSlave( es_out_t *main_out )
+{
+ es_out_t *out = malloc( sizeof( *out ) );
+ if( !out )
+ return NULL;
+
+ out->pf_add = SlaveEsOutAdd;
+ out->pf_send = SlaveEsOutSend;
+ out->pf_del = SlaveEsOutDel;
+ out->pf_control = SlaveEsOutControl;
+ out->pf_destroy = SlaveEsOutDelete;
+ out->p_sys = (void *) main_out;
+ return out;
+}
+
diff --git a/src/input/es_out.h b/src/input/es_out.h
index 8f202266e8..e9096948a8 100644
--- a/src/input/es_out.h
+++ b/src/input/es_out.h
@@ -176,4 +176,12 @@ static inline void es_out_Eos( es_out_t *p_out )
es_out_t *input_EsOutNew( input_thread_t *, int i_rate );
+/**
+ * Create a es_out that will drop PCR and DISPLAY_TIME controls.
+ *
+ * The returned es_out has a *weak* reference to the main_out. Therefore, this
+ * es_out must be destroyed before the main one.
+ */
+es_out_t *es_out_NewSlave( es_out_t *main_out );
+
#endif
diff --git a/src/input/input.c b/src/input/input.c
index f4d49b809f..61a1c3d9f0 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -81,7 +81,7 @@ static void UpdateTitleListfromDemux( input_thread_t * );
static void MRLSections( const char *, int *, int *, int *, int *);
-static input_source_t *InputSourceNew( input_thread_t *, const char *,
+static input_source_t *InputSourceNew( input_thread_t *, es_out_t *, const char *,
const char *psz_forced_demux,
bool b_in_can_fail );
static void InputSourceDestroy( input_source_t * );
@@ -476,7 +476,7 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
priv->stats = NULL;
priv->p_es_out_display = input_EsOutNew( p_input, priv->i_rate );
- priv->p_es_out = NULL;
+ priv->p_es_out = priv->p_slave_es_out = NULL;
/* Set the destructor when we are sure we are initialized */
vlc_object_set_destructor( p_input, input_Destructor );
@@ -1300,13 +1300,17 @@ static int Init( input_thread_t * p_input )
priv->i_rate );
if( priv->p_es_out == NULL )
goto error;
+ priv->p_slave_es_out = es_out_NewSlave( priv->p_es_out );
+ if( priv->p_slave_es_out == NULL )
+ goto error;
/* */
input_ChangeState( p_input, OPENING_S );
input_SendEventCache( p_input, 0.0 );
/* */
- master = InputSourceNew( p_input, priv->p_item->psz_uri, NULL, false );
+ master = InputSourceNew( p_input, priv->p_es_out, priv->p_item->psz_uri,
+ NULL, false );
if( master == NULL )
goto error;
priv->master = master;
@@ -1375,6 +1379,8 @@ static int Init( input_thread_t * p_input )
error:
input_ChangeState( p_input, ERROR_S );
+ if( input_priv(p_input)->p_slave_es_out )
+ es_out_Delete( input_priv(p_input)->p_slave_es_out );
if( input_priv(p_input)->p_es_out )
es_out_Delete( input_priv(p_input)->p_es_out );
es_out_SetMode( input_priv(p_input)->p_es_out_display, ES_OUT_MODE_END );
@@ -1424,6 +1430,8 @@ static void End( input_thread_t * p_input )
priv->i_seekpoint_offset = 0;
/* Unload all modules */
+ if( priv->p_slave_es_out )
+ es_out_Delete( priv->p_slave_es_out );
if( priv->p_es_out )
es_out_Delete( priv->p_es_out );
es_out_SetMode( priv->p_es_out_display, ES_OUT_MODE_END );
@@ -2403,9 +2411,10 @@ InputStreamHandleAnchor( input_source_t *source, stream_t **stream,
return VLC_SUCCESS;
}
-static demux_t *InputDemuxNew( input_thread_t *p_input, input_source_t *p_source,
- const char *psz_access, const char *psz_demux,
- const char *psz_path, const char *psz_anchor )
+static demux_t *InputDemuxNew( input_thread_t *p_input, es_out_t *p_es_out,
+ input_source_t *p_source, const char *psz_access,
+ const char *psz_demux, const char *psz_path,
+ const char *psz_anchor )
{
input_thread_private_t *priv = input_priv(p_input );
vlc_object_t *obj = VLC_OBJECT(p_source);
@@ -2451,8 +2460,7 @@ static demux_t *InputDemuxNew( input_thread_t *p_input, input_source_t *p_source
/* create a regular demux with the access stream created */
p_demux = demux_NewAdvanced( obj, p_input, psz_access, psz_demux, psz_path,
- p_stream, priv->p_es_out,
- priv->b_preparsing );
+ p_stream, p_es_out, priv->b_preparsing );
if( p_demux )
return p_demux;
@@ -2464,7 +2472,7 @@ error:
/*****************************************************************************
* InputSourceNew:
*****************************************************************************/
-static input_source_t *InputSourceNew( input_thread_t *p_input,
+static input_source_t *InputSourceNew( input_thread_t *p_input, es_out_t *p_es_out,
const char *psz_mrl,
const char *psz_forced_demux,
bool b_in_can_fail )
@@ -2554,7 +2562,7 @@ static input_source_t *InputSourceNew( input_thread_t *p_input,
TAB_CLEAN( count, tab );
}
- in->p_demux = InputDemuxNew( p_input, in, psz_access, psz_demux,
+ in->p_demux = InputDemuxNew( p_input, p_es_out, in, psz_access, psz_demux,
psz_path, psz_anchor );
free( psz_demux_var );
@@ -3216,12 +3224,14 @@ static int input_SlaveSourceAdd( input_thread_t *p_input,
msg_Dbg( p_input, "loading %s slave: %s (forced: %d)", psz_es, psz_uri,
b_forced );
- input_source_t *p_source = InputSourceNew( p_input, psz_uri,
- psz_forced_demux,
+ input_source_t *p_source = InputSourceNew( p_input,
+ input_priv(p_input)->p_slave_es_out,
+ psz_uri, psz_forced_demux,
b_can_fail || psz_forced_demux );
if( psz_forced_demux && p_source == NULL )
- p_source = InputSourceNew( p_input, psz_uri, NULL, b_can_fail );
+ p_source = InputSourceNew( p_input, input_priv(p_input)->p_slave_es_out,
+ psz_uri, NULL, b_can_fail );
if( p_source == NULL )
{
diff --git a/src/input/input_internal.h b/src/input/input_internal.h
index 16fd662fb3..632f1b96ab 100644
--- a/src/input/input_internal.h
+++ b/src/input/input_internal.h
@@ -112,6 +112,7 @@ typedef struct input_thread_private_t
bool b_out_pace_control; /* XXX Move it ot es_sout ? */
sout_instance_t *p_sout; /* Idem ? */
es_out_t *p_es_out;
+ es_out_t *p_slave_es_out;
es_out_t *p_es_out_display;
vlc_viewpoint_t viewpoint;
bool viewpoint_changed;
--
2.11.0
More information about the vlc-devel
mailing list