[vlc-devel] [RFC PATCHv2 04/18] input: pass a specific es_out for each slaves

Thomas Guillem thomas at gllm.fr
Tue Feb 18 17:11:17 CET 2020


Attach a specific es_out_t holding a es_out_ctx_t for each slaves.

The es_out_ctx_t source_id contains the name part of the source, cf. comment.
---
 src/input/input.c          | 68 ++++++++++++++++++++++++++++++++++----
 src/input/input_internal.h |  2 ++
 2 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/src/input/input.c b/src/input/input.c
index c033cdaae91..beb458d93c0 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -87,7 +87,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 *, bool, const char *,
                                        const char *psz_forced_demux,
                                        bool b_in_can_fail );
 static void InputSourceDestroy( input_source_t * );
@@ -1265,7 +1265,7 @@ static int Init( input_thread_t * p_input )
         goto error;
 
     /* */
-    master = InputSourceNew( p_input, priv->p_item->psz_uri, NULL, false );
+    master = InputSourceNew( p_input, true, priv->p_item->psz_uri, NULL, false );
     if( master == NULL )
         goto error;
     priv->master = master;
@@ -2478,13 +2478,54 @@ error:
     return NULL;
 }
 
+static es_out_t *InputCreateSlaveEsOut( input_thread_t *p_input,
+                                        input_source_t *in, const char *url )
+{
+    input_thread_private_t *priv = input_priv(p_input);
+
+    /* Use the last segment of the url as a source identifier. This is prone to
+     * name collision (more than one file with the same name from different
+     * directories) but might be very convenient for the user. Indeed, if an
+     * user is moving their media + slaves, the source ID of the slave will stay
+     * the same (and therefore the track ID will be the same). */
+    const char *source_id = strrchr(url, '/');
+    if( !source_id )
+        source_id = url;
+    else
+        source_id++;
+
+    for( int i = 0; i < input_priv(p_input)->i_slave; i++ )
+    {
+        input_source_t *other_in = input_priv(p_input)->slave[i];
+        if( unlikely( strcmp( other_in->source_id, source_id ) == 0 ) )
+        {
+            /* Name collision, use the full url for the identifier */
+            source_id = url;
+            break;
+        }
+    }
+
+    /* Attach the unique source id to the es_out via an es_out_ctx_t */
+    es_out_ctx_t *ctx = es_out_ctx_New( source_id );
+    if( !ctx )
+        return NULL;
+
+    in->p_slave_es_out = input_EsOutContextNew( priv->p_es_out, ctx );
+    if( in->p_slave_es_out )
+    {
+        in->source_id = es_out_ctx_GetSourceId( ctx );
+        assert( in->source_id );
+    }
+    return in->p_slave_es_out;
+}
+
 static void input_SplitMRL( const char **, const char **, const char **,
                             const char **, char * );
 
 /*****************************************************************************
  * InputSourceNew:
  *****************************************************************************/
-static input_source_t *InputSourceNew( input_thread_t *p_input,
+static input_source_t *InputSourceNew( input_thread_t *p_input, bool master,
                                        const char *psz_mrl,
                                        const char *psz_forced_demux,
                                        bool b_in_can_fail )
@@ -2576,8 +2617,15 @@ static input_source_t *InputSourceNew( input_thread_t *p_input,
     char *url;
     if( likely(asprintf( &url, "%s://%s", psz_access, psz_path ) >= 0) )
     {
-        in->p_demux = InputDemuxNew( p_input, priv->p_es_out, in, url,
-                                     psz_demux, psz_anchor );
+        es_out_t *es_out;
+        if( !master )
+            es_out = InputCreateSlaveEsOut( p_input, in, url );
+        else
+            es_out = priv->p_es_out;
+
+        if( es_out )
+            in->p_demux = InputDemuxNew( p_input, es_out, in, url,
+                                         psz_demux, psz_anchor );
         free( url );
     }
     else
@@ -2592,6 +2640,8 @@ static input_source_t *InputSourceNew( input_thread_t *p_input,
             vlc_dialog_display_error( p_input, _("Your input can't be opened"),
                                       _("VLC is unable to open the MRL '%s'."
                                       " Check the log for details."), psz_mrl );
+        if( in->p_slave_es_out )
+            es_out_Delete( in->p_slave_es_out );
         free( in );
         return NULL;
     }
@@ -2614,6 +2664,8 @@ static input_source_t *InputSourceNew( input_thread_t *p_input,
         if( in->p_demux == NULL )
         {
             msg_Err(p_input, "Failed to create demux filter");
+            if( in->p_slave_es_out )
+                es_out_Delete( in->p_slave_es_out );
             free( in );
             return NULL;
         }
@@ -2724,6 +2776,8 @@ static void InputSourceDestroy( input_source_t *in )
 
     if( in->p_demux )
         demux_Delete( in->p_demux );
+    if( in->p_slave_es_out )
+        es_out_Delete( in->p_slave_es_out );
 
     if( in->i_title > 0 )
     {
@@ -3269,12 +3323,12 @@ static int input_SlaveSourceAdd( input_thread_t *p_input,
 
     priv->i_last_es_cat = UNKNOWN_ES;
 
-    input_source_t *p_source = InputSourceNew( p_input, psz_uri,
+    input_source_t *p_source = InputSourceNew( p_input, false, 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, false, 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 83f3a9e899b..201bf5d36bb 100644
--- a/src/input/input_internal.h
+++ b/src/input/input_internal.h
@@ -367,6 +367,8 @@ input_item_t* input_GetItem( input_thread_t * ) VLC_USED;
 typedef struct
 {
     demux_t  *p_demux; /**< Demux object (most downstream) */
+    es_out_t *p_slave_es_out; /**< Slave es out */
+    const char *source_id;
 
     /* Title infos for that input */
     bool         b_title_demux; /* Titles/Seekpoints provided by demux */
-- 
2.20.1



More information about the vlc-devel mailing list