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;
#endif
#if defined( WIN32 ) || defined( UNDER_CE )
+# define DIR_SEP_CHAR '\\'
# define DIR_SEP "\\"
#else
+# define DIR_SEP_CHAR '/'
# define DIR_SEP "/"
#endif
#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
{
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 */
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 */
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
# 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.
((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; \
(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 */
# include <sys/stat.h>
#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 )
{
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;
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;
"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;
}
}
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++;
}
}
/* extract filename & dirname from psz_fname */
- tmp = strrchr( psz_fname, DIR_SEP );
+ tmp = strrchr( psz_fname, DIR_SEP_CHAR );
if( tmp )
{
int dirlen = 0;
}
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 );
}
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 )
{
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 ) &&
* 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
}
/** 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;
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;
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
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 * );
*****************************************************************************/
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 * );
// 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" );
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,
}
}
-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 */