diff --git a/include/vlc_input_item.h b/include/vlc_input_item.h index dcd38c9a03..d869312bdf 100644 --- a/include/vlc_input_item.h +++ b/include/vlc_input_item.h @@ -291,8 +291,18 @@ VLC_API void input_item_Release(input_item_t *); #define vlc_gc_incref(i) input_item_Hold(i) #define vlc_gc_decref(i) input_item_Release(i) -VLC_API int libvlc_MetaRequest(libvlc_int_t *, input_item_t *); -VLC_API int libvlc_ArtRequest(libvlc_int_t *, input_item_t *); +typedef enum input_item_meta_request_option_t +{ + META_REQUEST_OPTION_NONE = 0, + META_REQUEST_OPTION_LOCAL = 1 << 0, + META_REQUEST_OPTION_NETWORK = 1 << 1, + META_REQUEST_OPTION_ANY = 1 << 2 +} input_item_meta_request_option_t; + +VLC_API int libvlc_MetaRequest(libvlc_int_t *, input_item_t *, + input_item_meta_request_option_t ); +VLC_API int libvlc_ArtRequest(libvlc_int_t *, input_item_t *, + input_item_meta_request_option_t ); /****************** * Input stats diff --git a/lib/media.c b/lib/media.c index bac11da057..1f6fb9e8a1 100644 --- a/lib/media.c +++ b/lib/media.c @@ -633,8 +633,8 @@ static int media_parse(libvlc_media_t *media) input_item_t *item = media->p_input_item; /* TODO: Fetch art on need basis. But how not to break compatibility? */ - libvlc_ArtRequest(libvlc, item); - return libvlc_MetaRequest(libvlc, item); + libvlc_ArtRequest(libvlc, item, META_REQUEST_OPTION_NONE); + return libvlc_MetaRequest(libvlc, item, META_REQUEST_OPTION_NONE); } /************************************************************************** diff --git a/modules/gui/macosx/playlist.m b/modules/gui/macosx/playlist.m index 217f82a0ad..01735a7ab0 100644 --- a/modules/gui/macosx/playlist.m +++ b/modules/gui/macosx/playlist.m @@ -913,7 +913,7 @@ if (p_item) { if (p_item->i_children == -1) - libvlc_MetaRequest(p_intf->p_libvlc, p_item->p_input); + libvlc_MetaRequest(p_intf->p_libvlc, p_item->p_input, META_REQUEST_OPTION_NONE); else msg_Dbg(p_intf, "preparsing nodes not implemented"); } @@ -938,7 +938,7 @@ p_item = [[o_outline_view itemAtRow: indexes[i]] pointerValue]; if (p_item && p_item->i_children == -1) - libvlc_ArtRequest(p_intf->p_libvlc, p_item->p_input); + libvlc_ArtRequest(p_intf->p_libvlc, p_item->p_input, META_REQUEST_OPTION_NONE); } [self playlistUpdated]; } diff --git a/modules/gui/macosx/playlistinfo.m b/modules/gui/macosx/playlistinfo.m index a818f3f6e4..40bb85f8dd 100644 --- a/modules/gui/macosx/playlistinfo.m +++ b/modules/gui/macosx/playlistinfo.m @@ -212,7 +212,7 @@ static VLCInfo *_o_sharedInstance = nil; [o_image_well setImage: [NSImage imageNamed: @"noart.png"]]; } else { if (!input_item_IsPreparsed(p_item)) - libvlc_MetaRequest(VLCIntf->p_libvlc, p_item); + libvlc_MetaRequest(VLCIntf->p_libvlc, p_item, META_REQUEST_OPTION_NONE); /* fill uri info */ char * psz_url = decode_URI(input_item_GetURI(p_item)); @@ -365,7 +365,7 @@ error: - (IBAction)downloadCoverArt:(id)sender { playlist_t * p_playlist = pl_Get(VLCIntf); - if (p_item) libvlc_ArtRequest(VLCIntf->p_libvlc, p_item); + if (p_item) libvlc_ArtRequest(VLCIntf->p_libvlc, p_item, META_REQUEST_OPTION_NONE); } - (input_item_t *)item diff --git a/modules/gui/qt4/input_manager.cpp b/modules/gui/qt4/input_manager.cpp index bce4002184..11fde76fd2 100644 --- a/modules/gui/qt4/input_manager.cpp +++ b/modules/gui/qt4/input_manager.cpp @@ -654,7 +654,7 @@ void InputManager::requestArtUpdate( input_item_t *p_item ) if ( status & ( ITEM_ART_NOTFOUND|ITEM_ART_FETCHED ) ) return; } - libvlc_ArtRequest( p_intf->p_libvlc, p_item ); + libvlc_ArtRequest( p_intf->p_libvlc, p_item, META_REQUEST_OPTION_NONE ); /* No input will signal the cover art to update, * let's do it ourself */ if ( b_current_item ) diff --git a/src/libvlc.c b/src/libvlc.c index dd2f30ad88..946ce2e3f1 100644 --- a/src/libvlc.c +++ b/src/libvlc.c @@ -619,14 +619,15 @@ static void GetFilenames( libvlc_int_t *p_vlc, unsigned n, * Requests extraction of the meta data for an input item (a.k.a. preparsing). * The actual extraction is asynchronous. */ -int libvlc_MetaRequest(libvlc_int_t *libvlc, input_item_t *item) +int libvlc_MetaRequest(libvlc_int_t *libvlc, input_item_t *item, + input_item_meta_request_option_t i_options) { libvlc_priv_t *priv = libvlc_priv(libvlc); if (unlikely(priv->parser == NULL)) return VLC_ENOMEM; - playlist_preparser_Push(priv->parser, item); + playlist_preparser_Push(priv->parser, item, i_options); return VLC_SUCCESS; } @@ -634,13 +635,14 @@ int libvlc_MetaRequest(libvlc_int_t *libvlc, input_item_t *item) * Requests retrieving/downloading art for an input item. * The retrieval is performed asynchronously. */ -int libvlc_ArtRequest(libvlc_int_t *libvlc, input_item_t *item) +int libvlc_ArtRequest(libvlc_int_t *libvlc, input_item_t *item, + input_item_meta_request_option_t i_options) { libvlc_priv_t *priv = libvlc_priv(libvlc); if (unlikely(priv->parser == NULL)) return VLC_ENOMEM; - playlist_preparser_fetcher_Push(priv->parser, item); + playlist_preparser_fetcher_Push(priv->parser, item, i_options); return VLC_SUCCESS; } diff --git a/src/playlist/fetcher.c b/src/playlist/fetcher.c index 97c5a0f190..079ac9c733 100644 --- a/src/playlist/fetcher.c +++ b/src/playlist/fetcher.c @@ -43,15 +43,19 @@ /***************************************************************************** * Structures/definitions *****************************************************************************/ +typedef struct playlist_fetcher_entry_t +{ + input_item_t *p_item; + input_item_meta_request_option_t i_options; +} playlist_fetcher_entry_t; + struct playlist_fetcher_t { vlc_object_t *object; vlc_mutex_t lock; vlc_cond_t wait; bool b_live; - int i_waiting; - input_item_t **pp_waiting; - + DECL_ARRAY(playlist_fetcher_entry_t) waiting; DECL_ARRAY(playlist_album_t) albums; meta_fetcher_scope_t e_scope; }; @@ -72,8 +76,6 @@ playlist_fetcher_t *playlist_fetcher_New( vlc_object_t *parent ) vlc_mutex_init( &p_fetcher->lock ); vlc_cond_init( &p_fetcher->wait ); p_fetcher->b_live = false; - p_fetcher->i_waiting = 0; - p_fetcher->pp_waiting = NULL; bool b_access = var_InheritBool( parent, "metadata-network-access" ); if ( !b_access ) @@ -82,18 +84,19 @@ playlist_fetcher_t *playlist_fetcher_New( vlc_object_t *parent ) p_fetcher->e_scope = ( b_access ) ? FETCHER_SCOPE_ANY : FETCHER_SCOPE_LOCAL; ARRAY_INIT( p_fetcher->albums ); + ARRAY_INIT( p_fetcher->waiting ); return p_fetcher; } -void playlist_fetcher_Push( playlist_fetcher_t *p_fetcher, - input_item_t *p_item ) +void playlist_fetcher_Push( playlist_fetcher_t *p_fetcher, input_item_t *p_item, + input_item_meta_request_option_t i_options ) { vlc_gc_incref( p_item ); + playlist_fetcher_entry_t entry = { p_item, i_options }; vlc_mutex_lock( &p_fetcher->lock ); - INSERT_ELEM( p_fetcher->pp_waiting, p_fetcher->i_waiting, - p_fetcher->i_waiting, p_item ); + ARRAY_APPEND( p_fetcher->waiting, entry ); if( !p_fetcher->b_live ) { if( vlc_clone_detach( NULL, Thread, p_fetcher, @@ -110,11 +113,9 @@ void playlist_fetcher_Delete( playlist_fetcher_t *p_fetcher ) { vlc_mutex_lock( &p_fetcher->lock ); /* Remove any left-over item, the fetcher will exit */ - while( p_fetcher->i_waiting > 0 ) - { - vlc_gc_decref( p_fetcher->pp_waiting[0] ); - REMOVE_ELEM( p_fetcher->pp_waiting, p_fetcher->i_waiting, 0 ); - } + for (int i=0;iwaiting.i_size; i++) + vlc_gc_decref( p_fetcher->waiting.p_elems[i].p_item ); + ARRAY_RESET( p_fetcher->waiting ); while( p_fetcher->b_live ) vlc_cond_wait( &p_fetcher->wait, &p_fetcher->lock ); @@ -122,6 +123,7 @@ void playlist_fetcher_Delete( playlist_fetcher_t *p_fetcher ) vlc_cond_destroy( &p_fetcher->wait ); vlc_mutex_destroy( &p_fetcher->lock ); + free( p_fetcher ); } @@ -364,12 +366,14 @@ static void *Thread( void *p_data ) for( ;; ) { input_item_t *p_item = NULL; + input_item_meta_request_option_t i_options; vlc_mutex_lock( &p_fetcher->lock ); - if( p_fetcher->i_waiting != 0 ) + if( p_fetcher->waiting.i_size != 0 ) { - p_item = p_fetcher->pp_waiting[0]; - REMOVE_ELEM( p_fetcher->pp_waiting, p_fetcher->i_waiting, 0 ); + p_item = p_fetcher->waiting.p_elems[0].p_item; + i_options = p_fetcher->waiting.p_elems[0].i_options; + ARRAY_REMOVE( p_fetcher->waiting, 0 ); } else { diff --git a/src/playlist/fetcher.h b/src/playlist/fetcher.h index 9d7cae110e..c7d9c2d7f8 100644 --- a/src/playlist/fetcher.h +++ b/src/playlist/fetcher.h @@ -25,6 +25,8 @@ #ifndef _PLAYLIST_FETCHER_H #define _PLAYLIST_FETCHER_H 1 +#include + /** * Fetcher opaque structure. * @@ -44,7 +46,8 @@ playlist_fetcher_t *playlist_fetcher_New( vlc_object_t * ); * The input item is retained until the art fetching is done or until the * fetcher object is destroyed. */ -void playlist_fetcher_Push( playlist_fetcher_t *, input_item_t * ); +void playlist_fetcher_Push( playlist_fetcher_t *, input_item_t *, + input_item_meta_request_option_t ); /** * This function destroys the fetcher object and thread. diff --git a/src/playlist/item.c b/src/playlist/item.c index 088d8d77f2..92814819d9 100644 --- a/src/playlist/item.c +++ b/src/playlist/item.c @@ -769,7 +769,7 @@ static void GoAndPreparse( playlist_t *p_playlist, int i_mode, char *psz_album = input_item_GetAlbum( p_item->p_input ); if( sys->p_preparser != NULL && !input_item_IsPreparsed( p_item->p_input ) && (EMPTY_STR(psz_artist) || EMPTY_STR(psz_album)) ) - playlist_preparser_Push( sys->p_preparser, p_item->p_input ); + playlist_preparser_Push( sys->p_preparser, p_item->p_input, 0 ); free( psz_artist ); free( psz_album ); } diff --git a/src/playlist/preparser.c b/src/playlist/preparser.c index df6b64f515..b44b9f8db8 100644 --- a/src/playlist/preparser.c +++ b/src/playlist/preparser.c @@ -71,9 +71,11 @@ playlist_preparser_t *playlist_preparser_New( vlc_object_t *parent ) return p_preparser; } -void playlist_preparser_Push( playlist_preparser_t *p_preparser, input_item_t *p_item ) +void playlist_preparser_Push( playlist_preparser_t *p_preparser, input_item_t *p_item, + input_item_meta_request_option_t i_options ) { vlc_gc_incref( p_item ); + VLC_UNUSED( i_options ); vlc_mutex_lock( &p_preparser->lock ); INSERT_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting, @@ -90,10 +92,10 @@ void playlist_preparser_Push( playlist_preparser_t *p_preparser, input_item_t *p } void playlist_preparser_fetcher_Push( playlist_preparser_t *p_preparser, - input_item_t *p_item ) + input_item_t *p_item, input_item_meta_request_option_t i_options ) { if( p_preparser->p_fetcher != NULL ) - playlist_fetcher_Push( p_preparser->p_fetcher, p_item ); + playlist_fetcher_Push( p_preparser->p_fetcher, p_item, i_options ); } void playlist_preparser_Delete( playlist_preparser_t *p_preparser ) @@ -185,7 +187,7 @@ static void Art( playlist_preparser_t *p_preparser, input_item_t *p_item ) vlc_mutex_unlock( &p_item->lock ); if( b_fetch && p_fetcher ) - playlist_fetcher_Push( p_fetcher, p_item ); + playlist_fetcher_Push( p_fetcher, p_item, 0 ); } /** diff --git a/src/playlist/preparser.h b/src/playlist/preparser.h index 1d298c7dc8..54b276fcc8 100644 --- a/src/playlist/preparser.h +++ b/src/playlist/preparser.h @@ -25,6 +25,7 @@ #ifndef _PLAYLIST_PREPARSER_H #define _PLAYLIST_PREPARSER_H 1 +#include /** * Preparser opaque structure. * @@ -45,9 +46,11 @@ playlist_preparser_t *playlist_preparser_New( vlc_object_t * ); * The input item is retained until the preparsing is done or until the * preparser object is deleted. */ -void playlist_preparser_Push( playlist_preparser_t *, input_item_t * ); +void playlist_preparser_Push( playlist_preparser_t *, input_item_t *, + input_item_meta_request_option_t ); -void playlist_preparser_fetcher_Push( playlist_preparser_t *, input_item_t * ); +void playlist_preparser_fetcher_Push( playlist_preparser_t *, input_item_t *, + input_item_meta_request_option_t ); /** * This function destroys the preparser object and thread. diff --git a/src/playlist/thread.c b/src/playlist/thread.c index b32ea28ac7..c41ea19220 100644 --- a/src/playlist/thread.c +++ b/src/playlist/thread.c @@ -233,7 +233,7 @@ static int PlayItem( playlist_t *p_playlist, playlist_item_t *p_item ) if( !b_has_art || strncmp( psz_arturl, "attachment://", 13 ) ) { PL_DEBUG( "requesting art for %s", psz_name ); - libvlc_ArtRequest( p_playlist->p_libvlc, p_input ); + libvlc_ArtRequest( p_playlist->p_libvlc, p_input, META_REQUEST_OPTION_NONE ); } free( psz_arturl ); free( psz_name );