[vlc-devel] [PATCH] libvlc_media_list: add parse_start / parse_stop
Thomas Guillem
thomas at gllm.fr
Tue Dec 23 18:36:06 CET 2014
---
include/vlc/libvlc_media_list.h | 27 ++++++++++
lib/libvlc.sym | 2 +
lib/media_list.c | 108 ++++++++++++++++++++++++++++++++++++++++
lib/media_list_internal.h | 2 +
4 files changed, 139 insertions(+)
diff --git a/include/vlc/libvlc_media_list.h b/include/vlc/libvlc_media_list.h
index 015824b..b950d84 100644
--- a/include/vlc/libvlc_media_list.h
+++ b/include/vlc/libvlc_media_list.h
@@ -93,6 +93,33 @@ LIBVLC_API libvlc_media_t *
libvlc_media_list_media( libvlc_media_list_t *p_ml );
/**
+ * Parse the media (a directory, an archive or a playlist) associated with this
+ * media list instance.
+ * Parsing is asynchronous, new items will be added in background.
+ * Listen to libvlc_MediaListItemAdded events to get notified of new items.
+ * The libvlc_media_list_lock should NOT be held upon entering this function.
+ *
+ * \see libvlc_media_list_set_media
+ * \see libvlc_media_list_parse_stop
+ *
+ * \param p_ml a media list instance
+ * \return 0 on success, -1 on error or if the media list is read-only
+ */
+LIBVLC_API int
+libvlc_media_list_parse_start( libvlc_media_list_t *p_ml );
+
+/**
+ * Stop previous media parsing initiated by parse_start.
+ * The libvlc_media_list_lock should NOT be held upon entering this function.
+ *
+ * \see libvlc_media_list_parse_start
+ *
+ * \param p_ml a media list instance
+ */
+LIBVLC_API void
+libvlc_media_list_parse_stop( libvlc_media_list_t *p_ml );
+
+/**
* Add media instance to media list
* The libvlc_media_list_lock should be held upon entering this function.
*
diff --git a/lib/libvlc.sym b/lib/libvlc.sym
index f0512c6..38c17d7 100644
--- a/lib/libvlc.sym
+++ b/lib/libvlc.sym
@@ -107,6 +107,8 @@ libvlc_media_list_item_at_index
libvlc_media_list_lock
libvlc_media_list_media
libvlc_media_list_new
+libvlc_media_list_parse_start
+libvlc_media_list_parse_stop
libvlc_media_list_player_event_manager
libvlc_media_list_player_get_state
libvlc_media_list_player_is_playing
diff --git a/lib/media_list.c b/lib/media_list.c
index 39bc354..70f92c6 100644
--- a/lib/media_list.c
+++ b/lib/media_list.c
@@ -123,6 +123,33 @@ notify_item_deletion( libvlc_media_list_t * p_mlist,
}
/**************************************************************************
+ * input_item_add_subitem (private)
+ *
+ * Callback when new item is found by input thread (via parse_start)
+ **************************************************************************/
+static void input_item_add_subitem ( const vlc_event_t * p_event,
+ void * user_data )
+{
+ libvlc_media_list_t *p_mlist = user_data;
+ input_item_t *p_item = p_event->u.input_item_subitem_added.p_new_child;
+ libvlc_media_t *p_md;
+
+ if (!p_item)
+ return;
+
+ p_md = libvlc_media_new_from_input_item( p_mlist->p_libvlc_instance,
+ p_item );
+ if (!p_md)
+ return;
+
+ vlc_mutex_lock( &p_mlist->object_lock );
+ _libvlc_media_list_add_media( p_mlist, p_md );
+ vlc_mutex_unlock( &p_mlist->object_lock );
+
+ libvlc_media_release( p_md );
+}
+
+/**************************************************************************
* static mlist_is_writable (private)
**************************************************************************/
static inline
@@ -179,11 +206,13 @@ libvlc_media_list_new( libvlc_instance_t * p_inst )
vlc_mutex_init( &p_mlist->object_lock );
vlc_mutex_init( &p_mlist->refcount_lock ); // FIXME: spinlock?
+ vlc_mutex_init( &p_mlist->input_lock );
vlc_array_init( &p_mlist->items );
assert( p_mlist->items.i_count == 0 );
p_mlist->i_refcount = 1;
p_mlist->p_md = NULL;
+ p_mlist->p_input_thread = NULL;
return p_mlist;
}
@@ -209,6 +238,8 @@ void libvlc_media_list_release( libvlc_media_list_t * p_mlist )
/* Refcount null, time to free */
+ libvlc_media_list_parse_stop( p_mlist );
+
libvlc_event_manager_release( p_mlist->p_event_manager );
libvlc_media_release( p_mlist->p_md );
@@ -221,6 +252,7 @@ void libvlc_media_list_release( libvlc_media_list_t * p_mlist )
vlc_mutex_destroy( &p_mlist->object_lock );
vlc_mutex_destroy( &p_mlist->refcount_lock );
+ vlc_mutex_destroy( &p_mlist->input_lock );
vlc_array_clear( &p_mlist->items );
free( p_mlist );
@@ -284,6 +316,8 @@ void libvlc_media_list_set_media( libvlc_media_list_t * p_mlist,
libvlc_media_t * p_md )
{
+ libvlc_media_list_parse_stop( p_mlist );
+
vlc_mutex_lock( &p_mlist->object_lock );
libvlc_media_release( p_mlist->p_md );
libvlc_media_retain( p_md );
@@ -315,6 +349,80 @@ libvlc_media_list_media( libvlc_media_list_t * p_mlist )
}
/**************************************************************************
+ * parse_start (Public)
+ **************************************************************************/
+int libvlc_media_list_parse_start( libvlc_media_list_t * p_mlist )
+{
+ int ret = -1;
+ libvlc_media_t *p_md;
+
+ vlc_mutex_lock( &p_mlist->object_lock );
+ p_md = p_mlist->b_read_only ? NULL : p_mlist->p_md;
+ if( p_md )
+ libvlc_media_retain( p_md );
+ vlc_mutex_unlock( &p_mlist->object_lock );
+ if( !p_md )
+ return ret;
+
+ vlc_mutex_lock( &p_mlist->input_lock );
+ if( !p_mlist->p_input_thread )
+ {
+ vlc_event_manager_t *p_em = &p_md->p_input_item->event_manager;
+
+ vlc_event_attach( p_em, vlc_InputItemSubItemAdded,
+ input_item_add_subitem, p_mlist );
+
+ p_mlist->p_input_thread = input_CreateAndStart(
+ p_mlist->p_libvlc_instance->p_libvlc_int,
+ p_md->p_input_item, NULL );
+
+ if( p_mlist->p_input_thread )
+ ret = 0;
+ else
+ {
+ vlc_event_detach( p_em, vlc_InputItemSubItemAdded,
+ input_item_add_subitem, p_mlist );
+ libvlc_media_release( p_md );
+ }
+ }
+ vlc_mutex_unlock( &p_mlist->input_lock );
+ return ret;
+}
+
+/**************************************************************************
+ * parse_stop (Public)
+ **************************************************************************/
+void libvlc_media_list_parse_stop( libvlc_media_list_t * p_mlist )
+{
+ libvlc_media_t *p_md;
+
+ vlc_mutex_lock( &p_mlist->object_lock );
+ p_md = p_mlist->p_md;
+ vlc_mutex_unlock( &p_mlist->object_lock );
+ if( !p_md )
+ return;
+
+ vlc_mutex_lock( &p_mlist->input_lock );
+ if( p_mlist->p_input_thread )
+ {
+ vlc_event_manager_t *p_em = &p_md->p_input_item->event_manager;
+
+ /* object_lock shouldn't be hold when detaching events since
+ * input_item_add_subitem callback can hold this mutex too */
+ vlc_event_detach( p_em, vlc_InputItemSubItemAdded,
+ input_item_add_subitem, p_mlist );
+
+ input_Stop( p_mlist->p_input_thread, true );
+ input_Close( p_mlist->p_input_thread );
+
+ p_mlist->p_input_thread = NULL;
+
+ libvlc_media_release( p_md );
+ }
+ vlc_mutex_unlock( &p_mlist->input_lock );
+}
+
+/**************************************************************************
* libvlc_media_list_count (Public)
*
* Lock should be held when entering.
diff --git a/lib/media_list_internal.h b/lib/media_list_internal.h
index 8df6579..818908a 100644
--- a/lib/media_list_internal.h
+++ b/lib/media_list_internal.h
@@ -45,6 +45,8 @@ struct libvlc_media_list_t
libvlc_media_t * p_md; /* The media from which the
* mlist comes, if any. */
vlc_array_t items;
+ input_thread_t * p_input_thread;
+ vlc_mutex_t input_lock;
/* This indicates if this media list is read-only
* from a user point of view */
--
2.1.3
More information about the vlc-devel
mailing list