# HG changeset patch # User Cristi Magherusan # Date 1184117431 -10800 # Node ID e2b45aa596ad1a63e2e7bf35c3b4957c6a18b1dc # Parent c9ff58a0feabe34937e8f698ed77b25c5fd39186 improved the metadata algorithm, but couldnt get rid of the crashes yet diff -r c9ff58a0feab -r e2b45aa596ad src/lastfm/Makefile --- a/src/lastfm/Makefile Tue Jul 10 23:04:17 2007 +0100 +++ b/src/lastfm/Makefile Wed Jul 11 04:30:31 2007 +0300 @@ -11,7 +11,7 @@ SOURCES = lastfm.c -CFLAGS += $(PICFLAGS) $(GTK_CFLAGS) $(GLIB_CFLAGS) $(PANGO_CFLAGS) $(BEEP_DEFINES) $(CURL_CFLAGS) -I../../intl -I../.. +CFLAGS += $(PICFLAGS) $(GTK_CFLAGS) $(GLIB_CFLAGS) $(PANGO_CFLAGS) $(BEEP_DEFINES) $(CURL_CFLAGS) -I../../intl -I../.. -ggdb -g3 CFLAGS += -Wall -pedantic -std=c99 $(GCC42_CFLAGS) #CFLAGS += -Wpointer-arith -Wimplicit -Wnested-externs -Wcast-align \ diff -r c9ff58a0feab -r e2b45aa596ad src/lastfm/lastfm.c --- a/src/lastfm/lastfm.c Tue Jul 10 23:04:17 2007 +0100 +++ b/src/lastfm/lastfm.c Wed Jul 11 04:30:31 2007 +0300 @@ -29,15 +29,15 @@ */ /* - Current status and known issues: - - Works fine ant is relatively stable unless DEBUG is enabled (read below) - - The adjust fails when having 2 or more opened streams at the same time. - * It will randomly adjust to any one of them, because the playlist keeps - pulling metadata - - When the network is disconnected opening a new track freezes the player - * This seems to recover after the connection is restablished - * Ordinary mp3 streams seem to share this behavior. Didnt tested if others do. -*/ + * Current status and known issues: + * - Works fine ant is relatively stable unless DEBUG is enabled (read below) + * - The adjust fails when having 2 or more opened streams at the same time. + * * It will randomly adjust to any one of them, because the playlist keeps + * pulling metadata + * - When the network is disconnected opening a new track freezes the player + * * This seems to recover after the connection is restablished + * * Ordinary mp3 streams seem to share this behavior. Didnt tested if others do. + */ #include #include @@ -50,8 +50,8 @@ #define DEBUG 1 /*Caution!!! setting DEBUG to 1 is very likely to crash the player because the g_print-ed values -aren't checked of being !=NULL -*/ + aren't checked of being !=NULL + */ size_t lastfm_store_res(void *ptr, size_t size, size_t nmemb, void *udata) { @@ -106,12 +106,12 @@ } } -void lastfm_store(gchar *var_name,gchar* var){ /*mowgli storage wrapper*/ - if (mowgli_global_storage_get(var_name)) - mowgli_global_storage_free(var_name); + void lastfm_store(gchar *var_name,gchar* var){ /*mowgli storage wrapper*/ + if (mowgli_global_storage_get(var_name)) + mowgli_global_storage_free(var_name); - mowgli_global_storage_put(var_name,var); -} + mowgli_global_storage_put(var_name,var); + } int lastfm_login(void) /*gets the session ID and the mp3 stream URL and stores them*/ { @@ -122,10 +122,7 @@ GString *res; login_uri=lastfm_get_login_uri(); if(login_uri==NULL) - { - g_free(login_uri); return LASTFM_MISSING_LOGIN_DATA; - } res = g_string_new(NULL); status = lastfm_get_data_from_uri(login_uri, res); #if DEBUG @@ -148,13 +145,14 @@ g_strfreev(split); g_string_erase(res, 0, -1); g_free(login_uri); + login_uri=NULL; return ret; } static gchar* parse(gchar* input_string,gchar* token) { - if (!g_str_has_prefix(input_string, token)) - return NULL; + if (!g_str_has_prefix(input_string, token)) + return NULL; return g_strdup(strchr(input_string, '=') + 1); } @@ -210,37 +208,47 @@ handle->lastfm_duration=0; handle->lastfm_progress=0; - if (handle->lastfm_artist) - g_free(handle->lastfm_artist); - - if (handle->lastfm_title) - g_free(handle->lastfm_title); - - if (handle->lastfm_album) - g_free(handle->lastfm_album); - - if (handle->lastfm_cover) - g_free(handle->lastfm_cover); - - if (handle->lastfm_station_name) - g_free(handle->lastfm_station_name); - + if (handle->lastfm_artist) + { + g_free(handle->lastfm_artist); + handle->lastfm_artist=NULL; + } + if (handle->lastfm_title) + { + g_free(handle->lastfm_title); + handle->lastfm_title=NULL; + } + if (handle->lastfm_album) + { + g_free(handle->lastfm_album); + handle->lastfm_album=NULL; + } + if (handle->lastfm_cover) + { + g_free(handle->lastfm_cover); + handle->lastfm_cover=NULL; + } + if (handle->lastfm_station_name) + { + g_free(handle->lastfm_station_name); + handle->lastfm_station_name=NULL; + } for (i = 0; split && split[i]; i++) { - if (g_str_has_prefix(split[i], "artist=")) - handle->lastfm_artist = parse(split[i],"artist="); + if (g_str_has_prefix(split[i], "artist=")) + handle->lastfm_artist = parse(split[i],"artist="); - if (g_str_has_prefix(split[i], "track=")) - handle->lastfm_title = parse(split[i],"track="); + if (g_str_has_prefix(split[i], "track=")) + handle->lastfm_title = parse(split[i],"track="); - if (g_str_has_prefix(split[i], "album=")) - handle->lastfm_album = parse(split[i],"album=" ); + if (g_str_has_prefix(split[i], "album=")) + handle->lastfm_album = parse(split[i],"album=" ); - if (g_str_has_prefix(split[i], "albumcover_medium=")) - handle->lastfm_cover = parse(split[i],"albumcover_medium="); + if (g_str_has_prefix(split[i], "albumcover_medium=")) + handle->lastfm_cover = parse(split[i],"albumcover_medium="); - if (g_str_has_prefix(split[i], "station=")) - handle->lastfm_station_name = parse(split[i],"station="); + if (g_str_has_prefix(split[i], "station=")) + handle->lastfm_station_name = parse(split[i],"station="); if (g_str_has_prefix(split[i], "trackduration=")) handle->lastfm_duration = g_ascii_strtoull(g_strdup(split[i] + 14), NULL, 10); @@ -270,7 +278,7 @@ if (status == CURLE_OK) { #if DEBUG - g_print("Received metadata:'%s'\n", fetched_metadata->str); + g_print("\n----Received metadata:----\n%s----END----", fetched_metadata->str); #endif if(parse_metadata( handle,fetched_metadata)) { @@ -286,61 +294,86 @@ gpointer lastfm_metadata_thread_func(gpointer arg) { - gint err=0, - sleep_duration=1, + gint sleep_duration=1, previous_track_duration=-1, - count=0, - status=0; - gboolean track_end_expected=FALSE; + count=1, + status=0, + err=0; + GTimeVal *t0,*t1; + t0=g_new0(GTimeVal,1); + t1=g_new0(GTimeVal,1); + gboolean track_end_expected=FALSE,track_beginning=TRUE; gchar* previous_track_title=NULL; LastFM *handle = (LastFM *)arg; // metadata is fetched 1 second after the stream is opened. - // if it's fetched ok i'm waiting for track_length-10 seconds + // if metadata was fetched ok i'm waiting for + // track_length - fetch_duration - 5 seconds // then start polling for new metadata each 2 seconds, until // the track gets changed from the previous iteration do { - sleep(1); - count++; if(count%sleep_duration==0) - { + { + g_get_current_time (t0); + g_mutex_lock(mutex); status=fetch_metadata(handle); + g_mutex_unlock(mutex); + g_get_current_time (t1); if(status==METADATA_FETCH_SUCCEEDED) { if(!track_end_expected) - { - sleep_duration=handle->lastfm_duration-10; - previous_track_duration=handle->lastfm_duration; - previous_track_title=g_strdup(handle->lastfm_title); - track_end_expected=TRUE; /*then the track_end will follow*/ - count=err=0; + { + if(track_beginning||(previous_track_duration==-1)) //fetch again 2 sec after track start + { + sleep_duration=2; + track_beginning=FALSE; + } + else + { + sleep_duration=handle->lastfm_duration-(t1->tv_sec - t0->tv_sec)-5; + previous_track_duration=handle->lastfm_duration; + previous_track_title=g_strdup(handle->lastfm_title); + track_end_expected=TRUE; /*then the track_end will follow*/ + count=err=0; + track_beginning=TRUE; + } } else - { //two tracks are considered identical if they have the same length and the same title - if((handle->lastfm_duration == previous_track_duration)&& - g_str_has_prefix(handle->lastfm_title, previous_track_title)) - { - sleep_duration=2; - err++; + { + //if the track has changed (two tracks are considered identical if they + //have the same length and the same title) + if((handle->lastfm_duration != previous_track_duration)|| + !g_str_has_prefix(handle->lastfm_title, previous_track_title)) + { + track_end_expected=FALSE; + if(previous_track_title) + { + g_free(previous_track_title); + previous_track_title=NULL; + } } - else //the tracks are different so i'm at the beginning of a new one - { - track_end_expected=FALSE; - g_free(previous_track_title); - } + sleep_duration=2; } #if DEBUG g_print("Current thread, ID = %p\n", (void *)g_thread_self()); #endif } - else - err+=5; - } + else + { + err++; + sleep_duration=2; + } #if DEBUG - g_print("Thread_count: %d\n",thread_count); + g_print("Thread_count: %d\n",thread_count); + g_print("Sleeping for %d seconds\n",sleep_duration); #endif + + } + sleep(1); + count++; + } - while (err<=7 && (g_thread_self()==metadata_thread )); + while (g_thread_self()==metadata_thread && err<10); #if DEBUG g_print("Exiting thread, ID = %p\n", (void *)g_thread_self()); @@ -357,11 +390,10 @@ int login_count = 0; while((login_count++ <= 3)&&(lastfm_login()!= LASTFM_LOGIN_OK)) sleep(5); - handle->lastfm_session_id = mowgli_global_storage_get("lastfm_session_id"); handle->lastfm_mp3_stream_url = mowgli_global_storage_get("lastfm_stream_uri"); lastfm_uri=mowgli_global_storage_get("lastfm_tuned_to_url"); - //only tune in if the existinfg uri is NULL or != our new one(from path) + //only tune in if the existing uri is NULL or != our new one(from path) //adjust doesnt work as it should when having more than one lastfm stream opened at a time if (!lastfm_uri || (!g_str_has_prefix(path,lastfm_uri)) ) if(!lastfm_adjust(path)==LASTFM_ADJUST_OK) @@ -369,7 +401,11 @@ metadata_thread = g_thread_create(lastfm_metadata_thread_func, handle, FALSE, NULL); thread_count++; +#if DEBUG + g_print("Thread_count: %d\n",thread_count); +#endif handle->proxy_fd = vfs_fopen(handle->lastfm_mp3_stream_url, mode); + file->handle = handle; return file; } @@ -381,12 +417,12 @@ if (file == NULL) return -1; if (file->handle) { - LastFM *handle = file->handle; - ret = vfs_fclose(handle->proxy_fd); - if (!ret) - handle->proxy_fd = NULL; - g_free(handle); - file->handle = NULL; + LastFM *handle = file->handle; + ret = vfs_fclose(handle->proxy_fd); + if (!ret) + handle->proxy_fd = NULL; + g_free(handle); + file->handle = NULL; } return ret; } @@ -458,8 +494,8 @@ return g_strdup_printf("last.fm radio: %s", handle->lastfm_station_name); if (!g_ascii_strncasecmp(field, "track-name", 10) && (handle->lastfm_title != NULL) && (handle->lastfm_artist != NULL)) return g_strdup_printf("%s - %s", handle->lastfm_artist, handle->lastfm_title); - if (!g_ascii_strncasecmp(field, "content-type", 12)) - return g_strdup("audio/mpeg"); + if (!g_ascii_strncasecmp(field, "content-type", 12)) + return g_strdup("audio/mpeg"); return NULL; } @@ -484,11 +520,13 @@ static void init(void) { vfs_register_transport(&lastfm_const); + if (!mutex) + mutex = g_mutex_new (); } static void cleanup(void) { - + g_mutex_free(mutex); mowgli_global_storage_free("lastfm_session_id"); mowgli_global_storage_free("lastfm_stream_uri"); #if DEBUG diff -r c9ff58a0feab -r e2b45aa596ad src/lastfm/lastfm.h --- a/src/lastfm/lastfm.h Tue Jul 10 23:04:17 2007 +0100 +++ b/src/lastfm/lastfm.h Wed Jul 11 04:30:31 2007 +0300 @@ -29,6 +29,7 @@ GThread* metadata_thread=NULL; gint thread_count=0; +static GMutex * mutex = NULL; VFSFile *lastfm_vfs_fopen_impl(const gchar * path, const gchar * mode);