[vlc-commits] libvlc_media_parse: thread-safety
Rémi Denis-Courmont
git at videolan.org
Sun Jul 10 18:33:10 CEST 2011
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Jul 10 19:31:09 2011 +0300| [c7d87dd271f6a60fbf3d93d27a1b47047c34af31] | committer: Rémi Denis-Courmont
libvlc_media_parse: thread-safety
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=c7d87dd271f6a60fbf3d93d27a1b47047c34af31
---
src/control/media.c | 87 ++++++++++++++++++++----------------------
src/control/media_internal.h | 1 -
2 files changed, 41 insertions(+), 47 deletions(-)
diff --git a/src/control/media.c b/src/control/media.c
index 68ac4ed..0aa64a6 100644
--- a/src/control/media.c
+++ b/src/control/media.c
@@ -227,21 +227,6 @@ static void uninstall_input_item_observer( libvlc_media_t *p_md )
}
/**************************************************************************
- * Preparse if not already done (Private)
- **************************************************************************/
-static void preparse_if_needed( libvlc_media_t *p_md )
-{
- /* XXX: need some locking here */
- if (!p_md->has_asked_preparse)
- {
- playlist_PreparseEnqueue(
- libvlc_priv (p_md->p_libvlc_instance->p_libvlc_int)->p_playlist,
- p_md->p_input_item );
- p_md->has_asked_preparse = true;
- }
-}
-
-/**************************************************************************
* Create a new media descriptor object from an input_item
* (libvlc internal)
* That's the generic constructor
@@ -467,24 +452,8 @@ libvlc_media_get_mrl( libvlc_media_t * p_md )
char *libvlc_media_get_meta( libvlc_media_t *p_md, libvlc_meta_t e_meta )
{
- char * psz_meta;
-
- assert( p_md );
- /* XXX: locking */
-
- preparse_if_needed( p_md );
-
- psz_meta = input_item_GetMeta( p_md->p_input_item,
- libvlc_to_vlc_meta[e_meta] );
-
- if( e_meta == libvlc_meta_ArtworkURL && !psz_meta && !p_md->has_asked_art )
- {
- p_md->has_asked_art = true;
- playlist_AskForArtEnqueue(
- libvlc_priv(p_md->p_libvlc_instance->p_libvlc_int)->p_playlist,
- p_md->p_input_item );
- }
-
+ char *psz_meta = input_item_GetMeta( p_md->p_input_item,
+ libvlc_to_vlc_meta[e_meta] );
/* Should be integrated in core */
if( psz_meta == NULL && e_meta == libvlc_meta_Title
&& p_md->p_input_item->psz_name != NULL )
@@ -614,49 +583,75 @@ libvlc_media_get_duration( libvlc_media_t * p_md )
return -1;
}
- preparse_if_needed( p_md );
-
if (!input_item_IsPreparsed( p_md->p_input_item ))
return -1;
return from_mtime(input_item_GetDuration( p_md->p_input_item ));
}
+static int media_parse(libvlc_media_t *media)
+{
+ /* TODO: fetcher and parser independent of playlist */
+ playlist_t *playlist =
+ libvlc_priv (media->p_libvlc_instance->p_libvlc_int)->p_playlist;
+
+ /* TODO: Fetch art on need basis. But how not to break compatibility? */
+ playlist_AskForArtEnqueue(playlist, media->p_input_item );
+ return playlist_PreparseEnqueue(playlist, media->p_input_item);
+}
+
/**************************************************************************
- * Parse the media.
+ * Parse the media and wait.
**************************************************************************/
void
libvlc_media_parse(libvlc_media_t *media)
{
- preparse_if_needed(media);
-
vlc_mutex_lock(&media->parsed_lock);
+ if (!media->has_asked_preparse)
+ {
+ media->has_asked_preparse = true;
+ vlc_mutex_unlock(&media->parsed_lock);
+
+ if (media_parse(media))
+ /* Parse failed: do not wait! */
+ return;
+ vlc_mutex_lock(&media->parsed_lock);
+ }
+
while (!media->is_parsed)
vlc_cond_wait(&media->parsed_cond, &media->parsed_lock);
vlc_mutex_unlock(&media->parsed_lock);
}
/**************************************************************************
- * Parse the media.
+ * Parse the media but do not wait.
**************************************************************************/
void
libvlc_media_parse_async(libvlc_media_t *media)
{
- preparse_if_needed(media);
+ bool needed;
+
+ vlc_mutex_lock(&media->parsed_lock);
+ needed = media->has_asked_preparse;
+ media->has_asked_preparse = true;
+ vlc_mutex_unlock(&media->parsed_lock);
+
+ if (needed)
+ media_parse(media);
}
/**************************************************************************
* Get parsed status for media object.
**************************************************************************/
int
-libvlc_media_is_parsed( libvlc_media_t * p_md )
+libvlc_media_is_parsed(libvlc_media_t *media)
{
- assert( p_md );
-
- if( !p_md->p_input_item )
- return false;
+ bool parsed;
- return input_item_IsPreparsed( p_md->p_input_item );
+ vlc_mutex_lock(&media->parsed_lock);
+ parsed = media->is_parsed;
+ vlc_mutex_unlock(&media->parsed_lock);
+ return parsed;
}
/**************************************************************************
diff --git a/src/control/media_internal.h b/src/control/media_internal.h
index cd1c42a..c74c7d0 100644
--- a/src/control/media_internal.h
+++ b/src/control/media_internal.h
@@ -46,7 +46,6 @@ struct libvlc_media_t
bool is_parsed;
bool has_asked_preparse;
- bool has_asked_art;
};
/* Media Descriptor */
More information about the vlc-commits
mailing list