[vlc-devel] [PATCH 1/9] input: change input_Read() behavior

Thomas Guillem thomas at gllm.fr
Wed Jun 1 13:24:45 CEST 2016


Users will have more control when they need to read an input synchronously.
They'll be able to interrupt it from an other thread for example. This
function can now be used to preparse an item if the input_thread_t was created
with input_CreatePreparser().
---
 include/vlc_input.h                    |  3 +-
 lib/media_list.c                       |  9 ++++-
 modules/services_discovery/mediadirs.c |  7 +++-
 src/input/input.c                      | 72 ++++++++++++++++++++--------------
 src/playlist/loadsave.c                | 15 ++++++-
 5 files changed, 70 insertions(+), 36 deletions(-)

diff --git a/include/vlc_input.h b/include/vlc_input.h
index 7633e9d..f72f8d2 100644
--- a/include/vlc_input.h
+++ b/include/vlc_input.h
@@ -509,8 +509,7 @@ VLC_API int input_Start( input_thread_t * );
 
 VLC_API void input_Stop( input_thread_t * );
 
-VLC_API int input_Read( vlc_object_t *, input_item_t * );
-#define input_Read(a,b) input_Read(VLC_OBJECT(a),b)
+VLC_API int input_Read( input_thread_t *, bool );
 
 VLC_API int input_vaControl( input_thread_t *, int i_query, va_list  );
 
diff --git a/lib/media_list.c b/lib/media_list.c
index 82fee60..7d8737c 100644
--- a/lib/media_list.c
+++ b/lib/media_list.c
@@ -267,7 +267,14 @@ libvlc_media_list_add_file_content( libvlc_media_list_t * p_mlist,
         return -1;
     }
 
-    input_Read( p_mlist->p_libvlc_instance->p_libvlc_int, p_input_item );
+    input_thread_t *p_input =
+        input_Create( p_mlist->p_libvlc_instance->p_libvlc_int, p_input_item,
+                      NULL, NULL );
+    if( p_input != NULL )
+    {
+        input_Read( p_input, false );
+        input_Close( p_input );
+    }
     return 0;
 }
 
diff --git a/modules/services_discovery/mediadirs.c b/modules/services_discovery/mediadirs.c
index 0d1c262..957daa5 100644
--- a/modules/services_discovery/mediadirs.c
+++ b/modules/services_discovery/mediadirs.c
@@ -205,7 +205,12 @@ static void *Run( void *data )
         vlc_event_attach( p_em, vlc_InputItemSubItemAdded,
                           input_item_subitem_added, p_sd );
 
-        input_Read( p_sd, p_root );
+        input_thread_t *p_input = input_Create( p_sd, p_root, NULL, NULL );
+        if( p_input != NULL )
+        {
+            input_Read( p_input, false );
+            input_Close( p_input );
+        }
 
         vlc_event_detach( p_em, vlc_InputItemSubItemAdded,
                           input_item_subitem_added, p_sd );
diff --git a/src/input/input.c b/src/input/input.c
index 5307203..effca97 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -55,8 +55,8 @@
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-static  void *Run( void * );
-static  void *Preparse( void * );
+static  void Run( input_thread_t * );
+static  void Preparse( input_thread_t * );
 
 static input_thread_t * Create  ( vlc_object_t *, input_item_t *,
                                   const char *, bool, input_resource_t * );
@@ -126,27 +126,29 @@ input_thread_t *input_Create( vlc_object_t *p_parent,
     return Create( p_parent, p_item, psz_log, false, p_resource );
 }
 
-#undef input_Read
 /**
- * Initialize an input thread and run it until it stops by itself.
+ * Read a input_thread_t created by input_Create() or input_CreatePreparser().
  *
- * \param p_parent a vlc_object
- * \param p_item an input item
+ * The read is executed in the current thread and is blockling. This function
+ * can be interrupted with input_Stop()
+ *
+ * \param the input thread to read
+ * \param true if the interrupt context is handled by the input_thead_t
  * \return an error code, VLC_SUCCESS on success
  */
-int input_Read( vlc_object_t *p_parent, input_item_t *p_item )
+int input_Read( input_thread_t *p_input, bool b_interrupt )
 {
-    input_thread_t *p_input = Create( p_parent, p_item, NULL, false, NULL );
-    if( !p_input )
-        return VLC_EGENERIC;
+    if( b_interrupt )
+        vlc_interrupt_set(&p_input->p->interrupt);
 
-    if( !Init( p_input ) )
-    {
-        MainLoop( p_input, false );
-        End( p_input );
-    }
+    if( p_input->b_preparsing )
+        Preparse( p_input );
+    else
+        Run( p_input );
+
+    if( b_interrupt )
+        vlc_interrupt_set( NULL );
 
-    vlc_object_release( p_input );
     return VLC_SUCCESS;
 }
 
@@ -156,6 +158,26 @@ input_thread_t *input_CreatePreparser( vlc_object_t *parent,
     return Create( parent, item, NULL, true, NULL );
 }
 
+static void *ThreadRun( void *obj )
+{
+    input_thread_t *p_input = (input_thread_t *)obj;
+
+    vlc_interrupt_set(&p_input->p->interrupt);
+
+    Run( p_input );
+    return NULL;
+}
+
+static void *ThreadPreparse( void *obj )
+{
+    input_thread_t *p_input = (input_thread_t *)obj;
+
+    vlc_interrupt_set(&p_input->p->interrupt);
+
+    Preparse( p_input );
+    return NULL;
+}
+
 /**
  * Start a input_thread_t created by input_Create.
  *
@@ -165,10 +187,10 @@ input_thread_t *input_CreatePreparser( vlc_object_t *parent,
  */
 int input_Start( input_thread_t *p_input )
 {
-    void *(*func)(void *) = Run;
+    void *(*func)(void *) = ThreadRun;
 
     if( p_input->b_preparsing )
-        func = Preparse;
+        func = ThreadPreparse;
 
     assert( !p_input->p->is_running );
     /* Create thread and wait for its readiness. */
@@ -471,12 +493,8 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
  * This is the "normal" thread that spawns the input processing chain,
  * reads the stream, cleans up and waits
  *****************************************************************************/
-static void *Run( void *obj )
+static void Run( input_thread_t *p_input )
 {
-    input_thread_t *p_input = (input_thread_t *)obj;
-
-    vlc_interrupt_set(&p_input->p->interrupt);
-
     if( !Init( p_input ) )
     {
         if( p_input->p->b_can_pace_control && p_input->p->b_out_pace_control )
@@ -493,15 +511,10 @@ static void *Run( void *obj )
     }
 
     input_SendEventDead( p_input );
-    return NULL;
 }
 
-static void *Preparse( void *obj )
+static void Preparse( input_thread_t *p_input )
 {
-    input_thread_t *p_input = (input_thread_t *)obj;
-
-    vlc_interrupt_set(&p_input->p->interrupt);
-
     if( !Init( p_input ) )
     {   /* if the demux is a playlist, call Mainloop that will call
          * demux_Demux in order to fetch sub items */
@@ -518,7 +531,6 @@ static void *Preparse( void *obj )
     }
 
     input_SendEventDead( p_input );
-    return NULL;
 }
 
 bool input_Stopped( input_thread_t *input )
diff --git a/src/playlist/loadsave.c b/src/playlist/loadsave.c
index adbc92d..e5754a3 100644
--- a/src/playlist/loadsave.c
+++ b/src/playlist/loadsave.c
@@ -88,6 +88,17 @@ out:
    return ret;
 }
 
+static int item_Read( vlc_object_t *p_parent, input_item_t *p_item )
+{
+    input_thread_t *p_input = input_Create( p_parent, p_item, NULL, NULL );
+    if( p_input == NULL )
+        return VLC_EGENERIC;
+
+    input_Read( p_input, false );
+    input_Close( p_input );
+    return VLC_SUCCESS;
+}
+
 int playlist_Import( playlist_t *p_playlist, const char *psz_file )
 {
     input_item_t *p_input;
@@ -105,7 +116,7 @@ int playlist_Import( playlist_t *p_playlist, const char *psz_file )
     vlc_object_t *dummy = vlc_object_create( p_playlist, sizeof (*dummy) );
     var_Create( dummy, "meta-file", VLC_VAR_VOID );
 
-    int ret = input_Read( dummy, p_input );
+    int ret = item_Read( dummy, p_input );
 
     vlc_object_release( dummy );
     return ret;
@@ -175,7 +186,7 @@ int playlist_MLLoad( playlist_t *p_playlist )
 
     vlc_object_t *dummy = vlc_object_create( p_playlist, sizeof (*dummy) );
     var_Create( dummy, "meta-file", VLC_VAR_VOID );
-    input_Read( dummy, p_input );
+    item_Read( dummy, p_input );
     vlc_object_release( dummy );
 
     vlc_event_detach( &p_input->event_manager, vlc_InputItemSubItemTreeAdded,
-- 
2.8.1



More information about the vlc-devel mailing list