From 2d90e869b49fc72111a61ee715aa081fc92d169a Mon Sep 17 00:00:00 2001 From: Antoine Cellerier Date: Sun, 24 Sep 2006 22:01:28 +0000 Subject: [PATCH] Some more (mostly) untested stuff: * Secondary queue items now have a b_fetch_art flag * You can use the playlist_AskForArtEnqueue function to ask for art from an interface. This will enqueue at the begining of the secondary queue * other stuff which i don't remember :) * (fix issues with previous (and unrelated) DIR_SEP commit) --- include/vlc_common.h | 3 +++ include/vlc_input.h | 2 ++ include/vlc_playlist.h | 3 ++- include/vlc_symbols.h | 8 +++++++ src/input/meta.c | 29 +++++++++++++++++++----- src/input/subtitles.c | 6 ++--- src/playlist/control.c | 21 ++++++++++++++++++ src/playlist/engine.c | 38 ++++++++++++++++++++------------ src/playlist/playlist_internal.h | 15 ++++++++++++- src/playlist/thread.c | 8 +++---- 10 files changed, 104 insertions(+), 29 deletions(-) diff --git a/include/vlc_common.h b/include/vlc_common.h index 00b4462f01..cce8fa2d55 100644 --- a/include/vlc_common.h +++ b/include/vlc_common.h @@ -237,6 +237,7 @@ typedef struct services_discovery_t services_discovery_t; typedef struct services_discovery_sys_t services_discovery_sys_t; typedef struct playlist_add_t playlist_add_t; typedef struct playlist_preparse_t playlist_preparse_t; +typedef struct playlist_secondary_preparse_t playlist_secondary_preparse_t; /* Modules */ typedef struct module_bank_t module_bank_t; @@ -1280,7 +1281,9 @@ VLC_EXPORT( const char *, VLC_Changeset, ( void ) ); #endif #if defined( WIN32 ) || defined( UNDER_CE ) +# define DIR_SEP_CHAR '\\' # define DIR_SEP "\\" #else +# define DIR_SEP_CHAR '/' # define DIR_SEP "/" #endif diff --git a/include/vlc_input.h b/include/vlc_input.h index 64fc5b9a5c..c1a22ea428 100644 --- a/include/vlc_input.h +++ b/include/vlc_input.h @@ -476,6 +476,8 @@ VLC_EXPORT( void, input_DestroyThread, ( input_thread_t * ) ); #define input_MetaFetch(a,b) __input_MetaFetch(VLC_OBJECT(a),b) VLC_EXPORT( int, __input_MetaFetch, ( vlc_object_t *, input_item_t * ) ); +#define input_ArtFetch(a,b) __input_ArtFetch(VLC_OBJECT(a),b) +VLC_EXPORT( int, __input_ArtFetch, ( vlc_object_t *, input_item_t * ) ); enum input_query_e { diff --git a/include/vlc_playlist.h b/include/vlc_playlist.h index 0c79e48853..7069c14548 100644 --- a/include/vlc_playlist.h +++ b/include/vlc_playlist.h @@ -145,7 +145,7 @@ struct playlist_t mtime_t i_vout_destroyed_date; mtime_t i_sout_destroyed_date; playlist_preparse_t *p_preparse; /**< Preparser object */ - playlist_preparse_t *p_secondary_preparse; /**< Preparser object */ + playlist_secondary_preparse_t *p_secondary_preparse;/**< Preparser object */ vlc_mutex_t gc_lock; /**< Lock to protect the garbage collection */ @@ -237,6 +237,7 @@ VLC_EXPORT( void, playlist_LockClear, ( playlist_t * ) ); VLC_EXPORT( int, playlist_PreparseEnqueue, (playlist_t *, input_item_t *) ); VLC_EXPORT( int, playlist_PreparseEnqueueItem, (playlist_t *, playlist_item_t *) ); +VLC_EXPORT( int, playlist_AskForArtEnqueue, (playlist_t *, input_item_t *) ); /* Services discovery */ diff --git a/include/vlc_symbols.h b/include/vlc_symbols.h index 42306c59df..c9ba14399d 100644 --- a/include/vlc_symbols.h +++ b/include/vlc_symbols.h @@ -546,6 +546,9 @@ struct module_symbols_t int (*__input_MetaFetch_inner) (vlc_object_t *, input_item_t *); int (*input_DownloadAndCacheArt_inner) (vlc_object_t *p_parent, input_item_t *p_item); uint32_t (*input_GetMetaEngineFlags_inner) (vlc_meta_t *p_meta); + int (*__input_ArtFetch_inner) (vlc_object_t *, input_item_t *); + void *input_AskForArt_deprecated; + int (*playlist_AskForArtEnqueue_inner) (playlist_t *, input_item_t *); }; # if defined (__PLUGIN__) # define aout_FiltersCreatePipeline (p_symbols)->aout_FiltersCreatePipeline_inner @@ -1022,6 +1025,8 @@ struct module_symbols_t # define __input_MetaFetch (p_symbols)->__input_MetaFetch_inner # define input_DownloadAndCacheArt (p_symbols)->input_DownloadAndCacheArt_inner # define input_GetMetaEngineFlags (p_symbols)->input_GetMetaEngineFlags_inner +# define __input_ArtFetch (p_symbols)->__input_ArtFetch_inner +# define playlist_AskForArtEnqueue (p_symbols)->playlist_AskForArtEnqueue_inner # elif defined (HAVE_DYNAMIC_PLUGINS) && !defined (__BUILTIN__) /****************************************************************** * STORE_SYMBOLS: store VLC APIs into p_symbols for plugin access. @@ -1501,6 +1506,8 @@ struct module_symbols_t ((p_symbols)->__input_MetaFetch_inner) = __input_MetaFetch; \ ((p_symbols)->input_DownloadAndCacheArt_inner) = input_DownloadAndCacheArt; \ ((p_symbols)->input_GetMetaEngineFlags_inner) = input_GetMetaEngineFlags; \ + ((p_symbols)->__input_ArtFetch_inner) = __input_ArtFetch; \ + ((p_symbols)->playlist_AskForArtEnqueue_inner) = playlist_AskForArtEnqueue; \ (p_symbols)->net_ConvertIPv4_deprecated = NULL; \ (p_symbols)->vlc_input_item_GetInfo_deprecated = NULL; \ (p_symbols)->vlc_input_item_AddInfo_deprecated = NULL; \ @@ -1554,6 +1561,7 @@ struct module_symbols_t (p_symbols)->__intf_IntfProgress_deprecated = NULL; \ (p_symbols)->streaming_ChainToPsz_deprecated = NULL; \ (p_symbols)->__input_SecondaryPreparse_deprecated = NULL; \ + (p_symbols)->input_AskForArt_deprecated = NULL; \ # endif /* __PLUGIN__ */ #endif /* __VLC_SYMBOLS_H */ diff --git a/src/input/meta.c b/src/input/meta.c index 564f212b8e..433f0f966a 100644 --- a/src/input/meta.c +++ b/src/input/meta.c @@ -32,7 +32,7 @@ # include #endif -int input_FindArt( vlc_object_t *p_parent, input_item_t *p_item ); +int input_FindArtInCache( vlc_object_t *p_parent, input_item_t *p_item ); int __input_MetaFetch( vlc_object_t *p_parent, input_item_t *p_item ) { @@ -55,7 +55,7 @@ int __input_MetaFetch( vlc_object_t *p_parent, input_item_t *p_item ) i_optional |= VLC_META_ENGINE_ART_URL; } - input_FindArt( p_parent, p_item ); + input_FindArtInCache( p_parent, p_item ); i_meta = input_GetMetaEngineFlags( p_item->p_meta ); i_mandatory &= ~i_meta; @@ -87,18 +87,34 @@ int __input_MetaFetch( vlc_object_t *p_parent, input_item_t *p_item ) return VLC_SUCCESS; } +int __input_ArtFetch( vlc_object_t *p_parent, input_item_t *p_item ) +{ + if( !p_item->p_meta ) + return VLC_EGENERIC; + + /* TODO: call art fetcher modules */ + + if( !p_item->p_meta->psz_arturl || !*p_item->p_meta->psz_arturl ) + return VLC_EGENERIC; + + if( strncmp( "file://", p_item->p_meta->psz_arturl, 7 ) ) + { + return input_DownloadAndCacheArt( p_parent, p_item ); + } + return VLC_SUCCESS; +} + #ifndef MAX_PATH # define MAX_PATH 250 #endif -int input_FindArt( vlc_object_t *p_parent, input_item_t *p_item ) +int input_FindArtInCache( vlc_object_t *p_parent, input_item_t *p_item ) { char *psz_artist; char *psz_album; - char *psz_type; char psz_filename[MAX_PATH]; int i; struct stat a; - const char ppsz_type[] = { ".jpg", ".png", ".gif", ".bmp", "" }; + const char *ppsz_type[] = { ".jpg", ".png", ".gif", ".bmp", "" }; if( !p_item->p_meta ) return VLC_EGENERIC; @@ -111,13 +127,14 @@ int input_FindArt( vlc_object_t *p_parent, input_item_t *p_item ) "file://%s" DIR_SEP CONFIG_DIR DIR_SEP "art" DIR_SEP "%s" DIR_SEP "%s" DIR_SEP "art%s", p_parent->p_libvlc->psz_homedir, - psz_artist, psz_album, psz_type ); + psz_artist, psz_album, ppsz_type[i] ); /* Check if file exists */ if( utf8_stat( psz_filename+7, &a ) == 0 ) { msg_Dbg( p_parent, "album art %s already exists in cache" , psz_filename ); + vlc_meta_SetArtURL( p_item->p_meta, psz_filename ); return VLC_SUCCESS; } } diff --git a/src/input/subtitles.c b/src/input/subtitles.c index 9ce393d3ff..51cf836a3a 100644 --- a/src/input/subtitles.c +++ b/src/input/subtitles.c @@ -222,7 +222,7 @@ static char **paths_to_list( char *psz_dir, char *psz_path ) psz_subdir[0] == '.' ? psz_dir : "", psz_subdir, psz_subdir[strlen(psz_subdir) - 1] == - DIR_SEP ? '\0' : DIR_SEP ); + DIR_SEP_CHAR ? '\0' : DIR_SEP_CHAR ); subdirs[i] = psz_temp; i++; } @@ -277,7 +277,7 @@ char **subtitles_Detect( input_thread_t *p_this, char *psz_path, } /* extract filename & dirname from psz_fname */ - tmp = strrchr( psz_fname, DIR_SEP ); + tmp = strrchr( psz_fname, DIR_SEP_CHAR ); if( tmp ) { int dirlen = 0; @@ -304,7 +304,7 @@ char **subtitles_Detect( input_thread_t *p_this, char *psz_path, } dirlen = strlen( f_dir ); f_dir = (char *)realloc(f_dir, dirlen +2 ); - f_dir[dirlen] = DIR_SEP; + f_dir[dirlen] = DIR_SEP_CHAR; f_dir[dirlen+1] = '\0'; f_fname = FromLocaleDup( psz_fname ); } diff --git a/src/playlist/control.c b/src/playlist/control.c index 3ad3484148..3049ea5b67 100644 --- a/src/playlist/control.c +++ b/src/playlist/control.c @@ -214,6 +214,27 @@ int playlist_PreparseEnqueueItem( playlist_t *p_playlist, return VLC_SUCCESS; } +int playlist_AskForArtEnqueue( playlist_t *p_playlist, + input_item_t *p_item ) +{ + int i; + preparse_item_t p; + p.p_item = p_item; + p.b_fetch_art = VLC_TRUE; + + vlc_mutex_lock( &p_playlist->p_secondary_preparse->object_lock ); + for( i = 0; i < p_playlist->p_secondary_preparse->i_waiting && + p_playlist->p_secondary_preparse->p_waiting->b_fetch_art == VLC_TRUE; + i++ ); + vlc_gc_incref( p_item ); + INSERT_ELEM( p_playlist->p_secondary_preparse->p_waiting, + p_playlist->p_secondary_preparse->i_waiting, + i, + p ); + vlc_mutex_unlock( &p_playlist->p_secondary_preparse->object_lock ); + return VLC_SUCCESS; +} + void PreparseEnqueueItemSub( playlist_t *p_playlist, playlist_item_t *p_item ) { diff --git a/src/playlist/engine.c b/src/playlist/engine.c index b360bfe5b4..8b0be1f724 100644 --- a/src/playlist/engine.c +++ b/src/playlist/engine.c @@ -459,6 +459,7 @@ void playlist_PreparseLoop( playlist_preparse_t *p_obj ) if( p_current ) { vlc_bool_t b_preparsed = VLC_FALSE; + preparse_item_t p; if( strncmp( p_current->psz_uri, "http:", 5 ) && strncmp( p_current->psz_uri, "rtsp:", 5 ) && strncmp( p_current->psz_uri, "udp:", 4 ) && @@ -488,21 +489,24 @@ void playlist_PreparseLoop( playlist_preparse_t *p_obj ) * TODO: - use i_mandatory stuff here instead of hardcoded T/A * - don't do this for things we won't get meta for, like * videos + * -> done in input_MetaFetch atm */ - if( !(p_current->p_meta->psz_title && *p_current->p_meta->psz_title + /*if( !(p_current->p_meta->psz_title && *p_current->p_meta->psz_title && p_current->p_meta->psz_artist && *p_current->p_meta->psz_artist) ) - { + {*/ + p.p_item = p_current; + p.b_fetch_art = VLC_FALSE; vlc_mutex_lock( &p_playlist->p_secondary_preparse->object_lock); - INSERT_ELEM( p_playlist->p_secondary_preparse->pp_waiting, + INSERT_ELEM( p_playlist->p_secondary_preparse->p_waiting, p_playlist->p_secondary_preparse->i_waiting, p_playlist->p_secondary_preparse->i_waiting, - p_current ); + p ); vlc_mutex_unlock( &p_playlist->p_secondary_preparse->object_lock); - } + /*} else - vlc_gc_decref( p_current ); + vlc_gc_decref( p_current );*/ PL_UNLOCK; } else @@ -519,7 +523,7 @@ void playlist_PreparseLoop( playlist_preparse_t *p_obj ) } /** Main loop for secondary preparser queue */ -void playlist_SecondaryPreparseLoop( playlist_preparse_t *p_obj ) +void playlist_SecondaryPreparseLoop( playlist_secondary_preparse_t *p_obj ) { playlist_t *p_playlist = (playlist_t *)p_obj->p_parent; @@ -527,15 +531,21 @@ void playlist_SecondaryPreparseLoop( playlist_preparse_t *p_obj ) if( p_obj->i_waiting > 0 ) { - input_item_t *p_current = p_obj->pp_waiting[0]; - REMOVE_ELEM( p_obj->pp_waiting, p_obj->i_waiting, 0 ); + vlc_bool_t b_fetch_art = p_obj->p_waiting->b_fetch_art; + input_item_t *p_item = p_obj->p_waiting->p_item; + REMOVE_ELEM( p_obj->p_waiting, p_obj->i_waiting, 0 ); vlc_mutex_unlock( &p_obj->object_lock ); - if( p_current ) + if( p_item ) { - input_MetaFetch( p_playlist, p_current ); - p_current->p_meta->i_status |= ITEM_META_FETCHED; - var_SetInteger( p_playlist, "item-change", p_current->i_id ); - vlc_gc_decref( p_current ); + input_MetaFetch( p_playlist, p_item ); + p_item->p_meta->i_status |= ITEM_META_FETCHED; + if( b_fetch_art == VLC_TRUE ) + { + input_ArtFetch( p_playlist, p_item ); + p_item->p_meta->i_status |= ITEM_ART_FETCHED; + } + var_SetInteger( p_playlist, "item-change", p_item->i_id ); + vlc_gc_decref( p_item ); } else PL_UNLOCK; diff --git a/src/playlist/playlist_internal.h b/src/playlist/playlist_internal.h index e9304a1710..63a664e11c 100644 --- a/src/playlist/playlist_internal.h +++ b/src/playlist/playlist_internal.h @@ -39,6 +39,19 @@ struct playlist_preparse_t input_item_t **pp_waiting; }; +typedef struct preparse_item_t +{ + input_item_t *p_item; + vlc_bool_t b_fetch_art; +} preparse_item_t; + +struct playlist_secondary_preparse_t +{ + VLC_COMMON_MEMBERS + vlc_mutex_t lock; + int i_waiting; + preparse_item_t *p_waiting; +}; /***************************************************************************** * Prototypes @@ -52,7 +65,7 @@ void playlist_Destroy ( playlist_t * ); void playlist_MainLoop( playlist_t * ); void playlist_LastLoop( playlist_t * ); void playlist_PreparseLoop( playlist_preparse_t * ); -void playlist_SecondaryPreparseLoop( playlist_preparse_t * ); +void playlist_SecondaryPreparseLoop( playlist_secondary_preparse_t * ); /* Control */ playlist_item_t * playlist_NextItem ( playlist_t * ); diff --git a/src/playlist/thread.c b/src/playlist/thread.c index 7b37431fce..5efe4231ea 100644 --- a/src/playlist/thread.c +++ b/src/playlist/thread.c @@ -33,7 +33,7 @@ *****************************************************************************/ static void RunControlThread ( playlist_t * ); static void RunPreparse( playlist_preparse_t * ); -static void RunSecondaryPreparse( playlist_preparse_t * ); +static void RunSecondaryPreparse( playlist_secondary_preparse_t * ); static playlist_t * CreatePlaylist( vlc_object_t *p_parent ); static void HandlePlaylist( playlist_t * ); @@ -96,7 +96,7 @@ void __playlist_ThreadCreate( vlc_object_t *p_parent ) // Secondary Preparse p_playlist->p_secondary_preparse = vlc_object_create( p_playlist, - sizeof( playlist_preparse_t ) ); + sizeof( playlist_secondary_preparse_t ) ); if( !p_playlist->p_secondary_preparse ) { msg_Err( p_playlist, "unable to create secondary preparser" ); @@ -104,7 +104,7 @@ void __playlist_ThreadCreate( vlc_object_t *p_parent ) return; } p_playlist->p_secondary_preparse->i_waiting = 0; - p_playlist->p_secondary_preparse->pp_waiting = NULL; + p_playlist->p_secondary_preparse->p_waiting = NULL; vlc_object_attach( p_playlist->p_secondary_preparse, p_playlist ); if( vlc_thread_create( p_playlist->p_secondary_preparse, @@ -218,7 +218,7 @@ static void RunPreparse ( playlist_preparse_t *p_obj ) } } -static void RunSecondaryPreparse( playlist_preparse_t *p_obj ) +static void RunSecondaryPreparse( playlist_secondary_preparse_t *p_obj ) { playlist_t *p_playlist = (playlist_t *)p_obj->p_parent; /* Tell above that we're ready */ -- 2.39.2