X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Fplaylist%2Ffetcher.c;h=470896bef50746bdc036a881d5e269f402f00a03;hb=f5b549f5a73c98934d500e13949d09d45b147583;hp=d2b6356301d9cabf884b4c829f399409b0c7c985;hpb=96f642093714c7c14b4a279c79169a34711e4551;p=vlc diff --git a/src/playlist/fetcher.c b/src/playlist/fetcher.c index d2b6356301..470896bef5 100644 --- a/src/playlist/fetcher.c +++ b/src/playlist/fetcher.c @@ -25,23 +25,26 @@ # include "config.h" #endif +#include + #include #include #include #include +#include +#include +#include +#include #include "art.h" #include "fetcher.h" #include "playlist_internal.h" - /***************************************************************************** * Structures/definitions *****************************************************************************/ struct playlist_fetcher_t { - VLC_COMMON_MEMBERS; - playlist_t *p_playlist; vlc_mutex_t lock; @@ -62,14 +65,10 @@ static void *Thread( void * ); *****************************************************************************/ playlist_fetcher_t *playlist_fetcher_New( playlist_t *p_playlist ) { - playlist_fetcher_t *p_fetcher = - vlc_custom_create( p_playlist, sizeof(*p_fetcher), - VLC_OBJECT_GENERIC, "playlist fetcher" ); - + playlist_fetcher_t *p_fetcher = malloc( sizeof(*p_fetcher) ); if( !p_fetcher ) return NULL; - vlc_object_attach( p_fetcher, p_playlist ); p_fetcher->p_playlist = p_playlist; vlc_mutex_init( &p_fetcher->lock ); vlc_cond_init( &p_fetcher->wait ); @@ -82,7 +81,8 @@ playlist_fetcher_t *playlist_fetcher_New( playlist_t *p_playlist ) 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 ) { vlc_gc_incref( p_item ); @@ -91,15 +91,12 @@ void playlist_fetcher_Push( playlist_fetcher_t *p_fetcher, input_item_t *p_item p_fetcher->i_waiting, p_item ); if( !p_fetcher->b_live ) { - vlc_thread_t th; - - if( vlc_clone( &th, Thread, p_fetcher, VLC_THREAD_PRIORITY_LOW ) ) - msg_Err( p_fetcher, "cannot spawn secondary preparse thread" ); + if( vlc_clone_detach( NULL, Thread, p_fetcher, + VLC_THREAD_PRIORITY_LOW ) ) + msg_Err( p_fetcher->p_playlist, + "cannot spawn secondary preparse thread" ); else - { - vlc_detach( th ); p_fetcher->b_live = true; - } } vlc_mutex_unlock( &p_fetcher->lock ); } @@ -114,14 +111,13 @@ void playlist_fetcher_Delete( playlist_fetcher_t *p_fetcher ) REMOVE_ELEM( p_fetcher->pp_waiting, p_fetcher->i_waiting, 0 ); } - vlc_object_kill( p_fetcher ); while( p_fetcher->b_live ) vlc_cond_wait( &p_fetcher->wait, &p_fetcher->lock ); vlc_mutex_unlock( &p_fetcher->lock ); vlc_cond_destroy( &p_fetcher->wait ); vlc_mutex_destroy( &p_fetcher->lock ); - vlc_object_release( p_fetcher ); + free( p_fetcher ); } @@ -138,12 +134,10 @@ void playlist_fetcher_Delete( playlist_fetcher_t *p_fetcher ) static int FindArt( playlist_fetcher_t *p_fetcher, input_item_t *p_item ) { int i_ret; - module_t *p_module; - char *psz_title, *psz_artist, *psz_album; - psz_artist = input_item_GetArtist( p_item ); - psz_album = input_item_GetAlbum( p_item ); - psz_title = input_item_GetTitle( p_item ); + char *psz_artist = input_item_GetArtist( p_item ); + char *psz_album = input_item_GetAlbum( p_item ); + char *psz_title = input_item_GetTitle( p_item ); if( !psz_title ) psz_title = input_item_GetName( p_item ); @@ -159,7 +153,8 @@ static int FindArt( playlist_fetcher_t *p_fetcher, input_item_t *p_item ) if( !strcmp( album.psz_artist, psz_artist ) && !strcmp( album.psz_album, psz_album ) ) { - msg_Dbg( p_fetcher, " %s - %s has already been searched", + msg_Dbg( p_fetcher->p_playlist, + " %s - %s has already been searched", psz_artist, psz_album ); /* TODO-fenrir if we cache art filename too, we can go faster */ free( psz_artist ); @@ -187,7 +182,7 @@ static int FindArt( playlist_fetcher_t *p_fetcher, input_item_t *p_item ) char *psz_arturl = input_item_GetArtURL( p_item ); if( psz_arturl ) { - /* We already have an URL */ + /* We already have a URL */ if( !strncmp( psz_arturl, "file://", strlen( "file://" ) ) ) { free( psz_arturl ); @@ -205,7 +200,7 @@ static int FindArt( playlist_fetcher_t *p_fetcher, input_item_t *p_item ) psz_artist = input_item_GetArtist( p_item ); if( psz_album && psz_artist ) { - msg_Dbg( p_fetcher, "searching art for %s - %s", + msg_Dbg( p_fetcher->p_playlist, "searching art for %s - %s", psz_artist, psz_album ); } else @@ -214,24 +209,33 @@ static int FindArt( playlist_fetcher_t *p_fetcher, input_item_t *p_item ) if( !psz_title ) psz_title = input_item_GetName( p_item ); - msg_Dbg( p_fetcher, "searching art for %s", psz_title ); + msg_Dbg( p_fetcher->p_playlist, "searching art for %s", psz_title ); free( psz_title ); } /* Fetch the art url */ - p_fetcher->p_private = p_item; - - p_module = module_need( p_fetcher, "art finder", NULL, false ); + i_ret = VLC_EGENERIC; - if( p_module ) + vlc_object_t *p_parent = VLC_OBJECT(p_fetcher->p_playlist); + art_finder_t *p_finder = + vlc_custom_create( p_parent, sizeof( *p_finder ), "art finder" ); + if( p_finder != NULL) { - module_unneed( p_fetcher, p_module ); - i_ret = 1; - } - else - { - msg_Dbg( p_fetcher, "unable to find art" ); - i_ret = VLC_EGENERIC; + module_t *p_module; + + p_finder->p_item = p_item; + + p_module = module_need( p_finder, "art finder", NULL, false ); + if( p_module ) + { + module_unneed( p_finder, p_module ); + /* Try immediately if found in cache by download URL */ + if( !playlist_FindArtInCache( p_item ) ) + i_ret = 0; + else + i_ret = 1; + } + vlc_object_release( p_finder ); } /* Record this album */ @@ -264,18 +268,19 @@ static int DownloadArt( playlist_fetcher_t *p_fetcher, input_item_t *p_item ) if( !strncmp( psz_arturl , "file://", 7 ) ) { - msg_Dbg( p_fetcher, "Album art is local file, no need to cache" ); + msg_Dbg( p_fetcher->p_playlist, + "Album art is local file, no need to cache" ); free( psz_arturl ); return VLC_SUCCESS; } if( !strncmp( psz_arturl , "APIC", 4 ) ) { - msg_Warn( p_fetcher, "APIC fetch not supported yet" ); + msg_Warn( p_fetcher->p_playlist, "APIC fetch not supported yet" ); goto error; } - stream_t *p_stream = stream_UrlNew( p_fetcher, psz_arturl ); + stream_t *p_stream = stream_UrlNew( p_fetcher->p_playlist, psz_arturl ); if( !p_stream ) goto error; @@ -288,7 +293,7 @@ static int DownloadArt( playlist_fetcher_t *p_fetcher, input_item_t *p_item ) if( i_data >= INT_MAX - i_read ) break; - p_data = realloc( p_data, i_data + i_read ); + p_data = realloc_or_free( p_data, i_data + i_read ); if( !p_data ) break; @@ -319,6 +324,26 @@ error: return VLC_EGENERIC; } +/** + * FetchMeta, run the "meta fetcher". They are going to do network + * connections, and gather information upon the playing media. + * (even artwork). + */ +static void FetchMeta( playlist_fetcher_t *p_fetcher, input_item_t *p_item ) +{ + demux_meta_t *p_demux_meta = vlc_custom_create(p_fetcher->p_playlist, + sizeof(*p_demux_meta), "demux meta" ); + if( !p_demux_meta ) + return; + + p_demux_meta->p_demux = NULL; + p_demux_meta->p_item = p_item; + + module_t *p_meta_fetcher = module_need( p_demux_meta, "meta fetcher", NULL, false ); + if( p_meta_fetcher ) + module_unneed( p_demux_meta, p_meta_fetcher ); + vlc_object_release( p_demux_meta ); +} static int InputEvent( vlc_object_t *p_this, char const *psz_cmd, vlc_value_t oldval, vlc_value_t newval, void *p_data ) @@ -406,17 +431,14 @@ static void *Thread( void *p_data ) /* Wait that the input item is preparsed if it is being played */ WaitPreparsed( p_fetcher, p_item ); - /* */ - if( !vlc_object_alive( p_fetcher ) ) - goto end; + /* Triggers "meta fetcher", eventually fetch meta on the network. + * They are identical to "meta reader" expect that may actually + * takes time. That's why they are running here. + * The result of this fetch is not cached. */ + FetchMeta( p_fetcher, p_item ); /* Find art, and download it if needed */ int i_ret = FindArt( p_fetcher, p_item ); - - /* */ - if( !vlc_object_alive( p_fetcher ) ) - goto end; - if( i_ret == 1 ) i_ret = DownloadArt( p_fetcher, p_item ); @@ -434,8 +456,6 @@ static void *Thread( void *p_data ) input_item_SetArtNotFound( p_item, true ); } free( psz_name ); - - end: vlc_gc_decref( p_item ); } return NULL;