[vlc-devel] [PATCH] sd: mediadirs: Discover using preparse instead of playback

Hugo Beauzée-Luyssen hugo at beauzee.fr
Tue Jun 27 18:23:38 CEST 2017


---
 modules/services_discovery/mediadirs.c | 77 ++++++++++++++++++++++++++++++----
 1 file changed, 70 insertions(+), 7 deletions(-)

diff --git a/modules/services_discovery/mediadirs.c b/modules/services_discovery/mediadirs.c
index 69ded2d63f..aaf0b2fe07 100644
--- a/modules/services_discovery/mediadirs.c
+++ b/modules/services_discovery/mediadirs.c
@@ -98,19 +98,27 @@ vlc_module_end ()
 static void* Run( void* );
 
 static void input_subnode_added( const vlc_event_t*, void* );
+static void input_preparse_ended( const vlc_event_t *p_event, void *user_data );
 static int onNewFileAdded( vlc_object_t*, char const *,
                            vlc_value_t, vlc_value_t, void *);
 
 static enum type_e fileType( services_discovery_t *p_sd, const char* psz_file );
 static void formatSnapshotItem( input_item_t* );
 
+#define NB_FOLDERS 2
+
 struct services_discovery_sys_t
 {
     vlc_thread_t thread;
     enum type_e i_type;
 
-    char* psz_dir[2];
+    char* psz_dir[NB_FOLDERS];
+    input_item_t* p_items[NB_FOLDERS];
     const char* psz_var;
+
+    vlc_mutex_t lock;
+    vlc_cond_t cond;
+    unsigned int nb_folders_parsed;
 };
 
 /*****************************************************************************
@@ -162,8 +170,13 @@ static int Open( vlc_object_t *p_this, enum type_e i_type )
 
     var_AddCallback( p_sd->obj.libvlc, p_sys->psz_var, onNewFileAdded, p_sd );
 
+    vlc_mutex_init( &p_sys->lock );
+    vlc_cond_init( &p_sys->cond );
+    p_sys->nb_folders_parsed = 0;
     if( vlc_clone( &p_sys->thread, Run, p_sd, VLC_THREAD_PRIORITY_LOW ) )
     {
+        vlc_cond_destroy( &p_sys->cond );
+        vlc_mutex_destroy( &p_sys->lock );
         var_DelCallback( p_sd->obj.libvlc, p_sys->psz_var, onNewFileAdded, p_sd );
         free( p_sys->psz_dir[1] );
         free( p_sys->psz_dir[0] );
@@ -181,9 +194,9 @@ static void *Run( void *data )
 {
     services_discovery_t *p_sd = data;
     services_discovery_sys_t *p_sys = p_sd->p_sys;
+    unsigned int i_to_parse = 0;
 
-    int num_dir = sizeof( p_sys->psz_dir ) / sizeof( p_sys->psz_dir[0] );
-    for( int i = 0; i < num_dir; i++ )
+    for( int i = 0; i < NB_FOLDERS; i++ )
     {
         char* psz_dir = p_sys->psz_dir[i];
 
@@ -192,11 +205,14 @@ static void *Run( void *data )
         if( psz_dir == NULL            ||
             vlc_stat( psz_dir, &st )  ||
             !S_ISDIR( st.st_mode ) )
+        {
+            p_sys->p_items[i] = NULL;
             continue;
+        }
 
         char* psz_uri = vlc_path2uri( psz_dir, "file" );
 
-        input_item_t* p_root = input_item_New( psz_uri, NULL );
+        input_item_t* p_root = p_sys->p_items[i] = input_item_New( psz_uri, NULL );
         if( p_sys->i_type == Picture )
             input_item_AddOption( p_root, "ignore-filetypes=ini,db,lnk,txt",
                                   VLC_INPUT_OPTION_TRUSTED );
@@ -208,15 +224,35 @@ static void *Run( void *data )
         vlc_event_manager_t *p_em = &p_root->event_manager;
         vlc_event_attach( p_em, vlc_InputItemSubItemTreeAdded,
                           input_subnode_added, p_sd );
+        vlc_event_attach( p_em, vlc_InputItemPreparseEnded,
+                          input_preparse_ended, p_sd );
+
+        if ( libvlc_MetadataRequest( p_sd->obj.libvlc, p_root,
+                META_REQUEST_OPTION_SCOPE_LOCAL | META_REQUEST_OPTION_DO_INTERACT,
+                -1, p_sys->p_items[i] ) == VLC_SUCCESS )
+        {
+            ++i_to_parse;
+        }
+
+        free( psz_uri );
+    }
 
-        input_Read( p_sd, p_root );
+    vlc_mutex_lock( &p_sys->lock );
+    while ( i_to_parse > 0 && p_sys->nb_folders_parsed < i_to_parse )
+        vlc_cond_wait( &p_sys->cond, &p_sys->lock );
 
+    for( int i = 0; i < NB_FOLDERS; ++i )
+    {
+        if( p_sys->p_items[i] == NULL )
+            continue;
+        vlc_event_manager_t *p_em = &p_sys->p_items[i]->event_manager;
         vlc_event_detach( p_em, vlc_InputItemSubItemTreeAdded,
                           input_subnode_added, p_sd );
 
-        input_item_Release( p_root );
-        free( psz_uri );
+        input_item_Release( p_sys->p_items[i] );
+        p_sys->p_items[i] = NULL;
     }
+    vlc_mutex_unlock( &p_sys->lock );
 
     return NULL;
 }
@@ -229,7 +265,23 @@ static void Close( vlc_object_t *p_this )
     services_discovery_t *p_sd = (services_discovery_t *)p_this;
     services_discovery_sys_t *p_sys = p_sd->p_sys;
 
+    vlc_mutex_lock( &p_sys->lock );
+    for ( int i = 0; i < NB_FOLDERS; ++i )
+    {
+        if( p_sys->p_items[i] != NULL )
+        {
+            /* This will synchronously cancel the preparse request, but will not
+             * invoke the input_preparse_ended callback */
+            libvlc_MetadataCancel( p_sd->obj.libvlc, p_sys->p_items[i] );
+            p_sys->nb_folders_parsed++;
+        }
+    }
+    vlc_mutex_unlock( &p_sys->lock );
+    vlc_cond_signal( &p_sys->cond );
+
     vlc_join( p_sys->thread, NULL );
+    vlc_cond_destroy( &p_sys->cond );
+    vlc_mutex_destroy( &p_sys->lock );
 
     var_DelCallback( p_sd->obj.libvlc, p_sys->psz_var, onNewFileAdded, p_sd );
 
@@ -260,6 +312,17 @@ static void input_subnode_added( const vlc_event_t *p_event, void *user_data )
     }
 }
 
+static void input_preparse_ended( const vlc_event_t *p_event, void *user_data )
+{
+    VLC_UNUSED( p_event );
+    services_discovery_t* p_sd = user_data;
+    services_discovery_sys_t *p_sys = p_sd->p_sys;
+    vlc_mutex_lock( &p_sys->lock );
+    ++p_sys->nb_folders_parsed;
+    vlc_mutex_unlock( &p_sys->lock );
+    vlc_cond_signal( &p_sys->cond );
+}
+
 static int onNewFileAdded( vlc_object_t *p_this, char const *psz_var,
                      vlc_value_t oldval, vlc_value_t newval, void *p_data )
 {
-- 
2.11.0



More information about the vlc-devel mailing list