[vlc-commits] input: replace input_Preparse() with input_CreatePreparse()

Rémi Denis-Courmont git at videolan.org
Sun Jun 28 17:33:29 CEST 2015


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Jun 28 18:08:08 2015 +0300| [db17d8a433dbf5d4444b52bb80d7348f2a539fe5] | committer: Rémi Denis-Courmont

input: replace input_Preparse() with input_CreatePreparse()

For simplicity, the preparser should run in a dedicated input thread, so
that it can be stopped (refs #14571).

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=db17d8a433dbf5d4444b52bb80d7348f2a539fe5
---

 src/input/input.c           |  104 ++++++++++++++++++++++++++-----------------
 src/input/input_interface.h |    2 +-
 src/playlist/preparser.c    |    4 +-
 3 files changed, 66 insertions(+), 44 deletions(-)

diff --git a/src/input/input.c b/src/input/input.c
index 1260f2c..665a491 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -59,6 +59,7 @@
  * Local prototypes
  *****************************************************************************/
 static  void *Run            ( void * );
+static  void *Preparse       ( void * );
 
 static input_thread_t * Create  ( vlc_object_t *, input_item_t *,
                                   const char *, bool, input_resource_t * );
@@ -154,43 +155,6 @@ int input_Read( vlc_object_t *p_parent, input_item_t *p_item )
 }
 
 /**
- * Initialize an input and initialize it to preparse the item
- * This function is blocking. It will only accept parsing regular files.
- *
- * \param p_parent a vlc_object_t
- * \param p_item an input item
- * \return VLC_SUCCESS or an error
- */
-int input_Preparse( vlc_object_t *p_parent, input_item_t *p_item )
-{
-    input_thread_t *p_input;
-
-    /* Allocate descriptor */
-    p_input = Create( p_parent, p_item, NULL, true, NULL );
-    if( !p_input )
-        return VLC_EGENERIC;
-
-    if( !Init( p_input ) ) {
-        /* if the demux is a playlist, call Mainloop that will call
-         * demux_Demux in order to fetch sub items */
-        bool b_is_playlist = false;
-
-        if ( input_item_ShouldPreparseSubItems( p_item )
-          && demux_Control( p_input->p->input.p_demux,
-                            DEMUX_IS_PLAYLIST,
-                            &b_is_playlist ) )
-            b_is_playlist = false;
-        if( b_is_playlist )
-            MainLoop( p_input, false );
-        End( p_input );
-    }
-
-    vlc_object_release( p_input );
-
-    return VLC_SUCCESS;
-}
-
-/**
  * Start a input_thread_t created by input_Create.
  *
  * You must not start an already running input_thread_t.
@@ -213,6 +177,36 @@ int input_Start( input_thread_t *p_input )
 }
 
 /**
+ * Initialize an input and initialize it to preparse the item.
+ *
+ * Preparsing is performed asynchronously; use input_Stop() to abort it, or
+ * wait until the input goes dead on its own. Use input_Close() to wait for
+ * completion and clean up.
+ *
+ * \param p_parent a vlc_object_t
+ * \param p_item an input item
+ * \return an input thread or NULL on error
+ */
+input_thread_t *input_CreatePreparse( vlc_object_t *p_parent,
+                                      input_item_t *p_item )
+{
+    input_thread_t *p_input = Create( p_parent, p_item, NULL, true, NULL );
+    if( unlikely(p_input == NULL) )
+        return NULL;
+
+    p_input->p->is_running = !vlc_clone( &p_input->p->thread, Preparse,
+                                         p_input, VLC_THREAD_PRIORITY_INPUT );
+    if( !p_input->p->is_running )
+    {
+        input_ChangeState( p_input, ERROR_S );
+        msg_Err( p_input, "cannot create input thread" );
+        input_Close( p_input );
+        p_input = NULL;
+    }
+    return p_input;
+}
+
+/**
  * Request a running input thread to stop and die
  *
  * \param p_input the input thread to stop
@@ -503,11 +497,13 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
     return p_input;
 }
 
-/*****************************************************************************
- * Run: main thread loop
- * This is the "normal" thread that spawns the input processing chain,
- * reads the stream, cleans up and waits
- *****************************************************************************/
+/**
+ * Normal input thread entry point.
+ *
+ * This is the "normal" thread. It spawns the input stream and elementary
+ * stream output, proceeds until the end of the stream is reached, then
+ * cleans up.
+ */
 static void *Run( void *obj )
 {
     input_thread_t *p_input = (input_thread_t *)obj;
@@ -522,7 +518,31 @@ static void *Run( void *obj )
     }
 
     input_SendEventDead( p_input );
+    vlc_restorecancel( canc );
+    return NULL;
+}
 
+static void *Preparse( void *obj )
+{
+    input_thread_t *p_input = (input_thread_t *)obj;
+    const int canc = vlc_savecancel();
+
+    if( !Init( p_input ) )
+    {   /* If the demux is a playlist, call Mainloop(). It will call
+         * demux_Demux() in order to fetch the sub-items. */
+        bool b_is_playlist = false;
+
+        if ( input_item_ShouldPreparseSubItems( p_input->p->p_item )
+          && demux_Control( p_input->p->input.p_demux,
+                            DEMUX_IS_PLAYLIST,
+                            &b_is_playlist ) )
+            b_is_playlist = false;
+        if( b_is_playlist )
+            MainLoop( p_input, false );
+        End( p_input );
+    }
+
+    input_SendEventDead( p_input );
     vlc_restorecancel( canc );
     return NULL;
 }
diff --git a/src/input/input_interface.h b/src/input/input_interface.h
index e7b634a..43b2974 100644
--- a/src/input/input_interface.h
+++ b/src/input/input_interface.h
@@ -37,7 +37,7 @@ void input_item_SetArtFetched( input_item_t *p_i, bool b_art_fetched );
 void input_item_SetEpg( input_item_t *p_item, const vlc_epg_t *p_epg );
 void input_item_SetEpgOffline( input_item_t * );
 
-int input_Preparse( vlc_object_t *, input_item_t * );
+input_thread_t *input_CreatePreparse( vlc_object_t *, input_item_t * );
 
 /* misc/stats.c
  * FIXME it should NOT be defined here or not coded in misc/stats.c */
diff --git a/src/playlist/preparser.c b/src/playlist/preparser.c
index f1c1d1f..cf48f7e 100644
--- a/src/playlist/preparser.c
+++ b/src/playlist/preparser.c
@@ -170,7 +170,9 @@ static void Preparse( vlc_object_t *obj, input_item_t *p_item,
     /* Do not preparse if it is already done (like by playing it) */
     if( !input_item_IsPreparsed( p_item ) )
     {
-        input_Preparse( obj, p_item );
+        input_thread_t *input = input_CreatePreparse( obj, p_item );
+        if( input != NULL )
+            input_Close( input );
         input_item_SetPreparsed( p_item, true );
 
         var_SetAddress( obj, "item-change", p_item );



More information about the vlc-commits mailing list