[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