diff options
author | Alexey Yakovenko <wakeroid@gmail.com> | 2010-05-23 14:04:21 +0200 |
---|---|---|
committer | Alexey Yakovenko <wakeroid@gmail.com> | 2010-05-23 14:04:21 +0200 |
commit | 734685586bfe193097defa77ca607b19b3f87f44 (patch) | |
tree | a187d8fe129f51bb33ca63442d82fad93fab1140 | |
parent | 39ce5b6e7b5829f2e3552f8a6cba49767478d2e8 (diff) | |
parent | 7149aa6e4e7cb1bd71d1a0cb41f48000d5416941 (diff) |
Merge branch 'master' into i18n
Conflicts:
main.c
-rw-r--r-- | main.c | 34 | ||||
-rw-r--r-- | plugins/artwork/albumartorg.c | 13 | ||||
-rw-r--r-- | plugins/artwork/artwork.c | 4 | ||||
-rw-r--r-- | plugins/artwork/lastfm.c | 13 | ||||
-rw-r--r-- | plugins/gtkui/coverart.c | 15 | ||||
-rw-r--r-- | plugins/gtkui/ddblistview.c | 10 | ||||
-rw-r--r-- | plugins/gtkui/ddbtabstrip.c | 4 | ||||
-rw-r--r-- | plugins/vfs_curl/vfs_curl.c | 38 | ||||
-rw-r--r-- | plugins/vorbis/vorbis.c | 96 |
9 files changed, 163 insertions, 64 deletions
@@ -38,6 +38,7 @@ #include <sys/fcntl.h> #include <sys/errno.h> #include <signal.h> +#include <execinfo.h> #ifdef HAVE_CONFIG_H # include <config.h> #endif @@ -428,9 +429,40 @@ sigterm_handler (int sig) { exit (0); } +void +sigsegv_handler (int sig) { + fprintf (stderr, "Segmentation Fault\n"); + int j, nptrs; +#define SIZE 100 + void *buffer[100]; + char **strings; + + nptrs = backtrace(buffer, SIZE); + printf("backtrace() returned %d addresses\n", nptrs); + + /* The call + * backtrace_symbols_fd(buffer, + * nptrs, + * STDOUT_FILENO) + would produce similar output to the following: */ + + strings = backtrace_symbols(buffer, nptrs); + if (strings == NULL) { + perror("backtrace_symbols"); + exit(EXIT_FAILURE); + } + + for (j = 0; j < nptrs; j++) + printf("%s\n", strings[j]); + + free(strings); + exit (0); +} + int main (int argc, char *argv[]) { - setlocale (LC_ALL, ""); + signal (SIGSEGV, sigsegv_handler); + setlocale (LC_ALL, ""); setlocale (LC_NUMERIC, "C"); #ifdef ENABLE_NLS // fprintf (stderr, "enabling gettext support: package=" PACKAGE ", dir=" LOCALEDIR "...\n"); diff --git a/plugins/artwork/albumartorg.c b/plugins/artwork/albumartorg.c index 18b494a4..d438cf9c 100644 --- a/plugins/artwork/albumartorg.c +++ b/plugins/artwork/albumartorg.c @@ -74,9 +74,11 @@ fetch_from_albumart_org (const char *artist, const char *album, const char *dest } current_file = fp; - FILE *out = fopen (dest, "w+b"); + char temp[PATH_MAX]; + snprintf (temp, sizeof (temp), "%s.part", dest); + FILE *out = fopen (temp, "w+b"); if (!out) { - trace ("fetch_from_albumart_org: failed to open %s for writing\n", dest); + trace ("fetch_from_albumart_org: failed to open %s for writing\n", temp); current_file = NULL; deadbeef->fclose (fp); return -1; @@ -98,9 +100,16 @@ fetch_from_albumart_org (const char *artist, const char *album, const char *dest deadbeef->fclose (fp); if (error) { + unlink (temp); + return -1; + } + + if (rename (temp, dest) != 0) { + unlink (temp); unlink (dest); return -1; } + return 0; } diff --git a/plugins/artwork/artwork.c b/plugins/artwork/artwork.c index ef2d0e00..4af9658b 100644 --- a/plugins/artwork/artwork.c +++ b/plugins/artwork/artwork.c @@ -435,7 +435,7 @@ fetcher_thread (void *none) char* get_album_art (const char *fname, const char *artist, const char *album, artwork_callback callback, void *user_data) { -// trace ("get_album_art: %s (%s - %s)\n", fname, artist, album); + trace ("get_album_art: %s (%s - %s)\n", fname, artist, album); char path [1024]; if (!album) { @@ -470,7 +470,7 @@ get_album_art (const char *fname, const char *artist, const char *album, artwork } } -// trace ("found %s in cache\n", path); + trace ("found %s in cache\n", path); return strdup (path); } diff --git a/plugins/artwork/lastfm.c b/plugins/artwork/lastfm.c index 2aed6d7c..bf76ccca 100644 --- a/plugins/artwork/lastfm.c +++ b/plugins/artwork/lastfm.c @@ -64,9 +64,11 @@ fetch_from_lastfm (const char *artist, const char *album, const char *dest) } current_file = fp; - FILE *out = fopen (dest, "w+b"); + char temp[PATH_MAX]; + snprintf (temp, sizeof (temp), "%s.part", dest); + FILE *out = fopen (temp, "w+b"); if (!out) { - trace ("fetch_from_lastfm: failed to open %s for writing\n", dest); + trace ("fetch_from_lastfm: failed to open %s for writing\n", temp); deadbeef->fclose (fp); current_file = NULL; return -1; @@ -88,8 +90,15 @@ fetch_from_lastfm (const char *artist, const char *album, const char *dest) deadbeef->fclose (fp); if (error) { + unlink (temp); + return -1; + } + + if (rename (temp, dest) != 0) { + unlink (temp); unlink (dest); return -1; } + return 0; } diff --git a/plugins/gtkui/coverart.c b/plugins/gtkui/coverart.c index af6ed4d3..778d83f1 100644 --- a/plugins/gtkui/coverart.c +++ b/plugins/gtkui/coverart.c @@ -140,17 +140,18 @@ loading_thread (void *none) { usleep (500000); continue; } - trace ("loading image %s\n", queue->fname); - GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (queue->fname, NULL); +// GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (queue->fname, NULL); + GError *error; + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_scale (queue->fname, queue->width, queue->width, TRUE, &error); if (!pixbuf) { - trace ("GDK failed to load pixbuf from file %s\n", queue->fname); pixbuf = gdk_pixbuf_new_from_file (DEFAULT_COVER_PATH, NULL); } if (!pixbuf) { // make default empty image pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 2, 2); } +#if 0 else { int w, h; w = gdk_pixbuf_get_width (pixbuf); @@ -179,6 +180,7 @@ loading_thread (void *none) { pixbuf = scaled; } } +#endif if (cache_min != -1) { deadbeef->mutex_lock (mutex); cache[cache_min].pixbuf = pixbuf; @@ -217,9 +219,10 @@ get_pixbuf (const char *fname, int width) { if (cache[i].pixbuf) { if (!strcmp (fname, cache[i].fname) && cache[i].width == width) { gettimeofday (&cache[i].tm, NULL); - g_object_ref (cache[i].pixbuf); + GdkPixbuf *pb = cache[i].pixbuf; + g_object_ref (pb); deadbeef->mutex_unlock (mutex); - return cache[i].pixbuf; + return pb; } } } @@ -242,7 +245,7 @@ get_cover_art (const char *fname, const char *artist, const char *album, int wid return NULL; } char *image_fname = coverart_plugin->get_album_art (fname, artist, album, cover_avail_callback, (void *)(intptr_t)width); - if (fname) { + if (image_fname) { GdkPixbuf *pb = get_pixbuf (image_fname, width); free (image_fname); return pb; diff --git a/plugins/gtkui/ddblistview.c b/plugins/gtkui/ddblistview.c index c9f4c6da..3ddd3568 100644 --- a/plugins/gtkui/ddblistview.c +++ b/plugins/gtkui/ddblistview.c @@ -28,7 +28,6 @@ #include <stdlib.h> #include <time.h> #include <string.h> -#include <assert.h> #include <unistd.h> #include <ctype.h> #include <assert.h> @@ -37,6 +36,8 @@ #include "drawing.h" #include "gtkui.h" +#pragma GCC optimize("O0") + #define min(x,y) ((x)<(y)?(x):(y)) #define max(x,y) ((x)>(y)?(x):(y)) @@ -707,6 +708,7 @@ ddb_listview_list_expose_event (GtkWidget *widget, void ddb_listview_list_expose (DdbListview *listview, int x, int y, int w, int h) { +// printf ("listview height: %d\n", listview->list->allocation.height); GtkWidget *widget = listview->list; if (widget->window && listview->backbuf) { draw_drawable (widget->window, widget->style->black_gc, listview->backbuf, x, y, x, y, w, h); @@ -974,6 +976,12 @@ ddb_listview_list_drag_leave (GtkWidget *widget, // debug function for gdk_draw_drawable static inline void draw_drawable (GdkDrawable *window, GdkGC *gc, GdkDrawable *drawable, int x1, int y1, int x2, int y2, int w, int h) { + gint width1, height1; + gint width2, height2; + gdk_drawable_get_size (window, &width1, &height1); + gdk_drawable_get_size (drawable, &width2, &height2); +// assert (y1 >= 0 && y1 + h < height2); +// assert (y2 >= 0 && y2 + h < height1); // printf ("dd: %p %p %p %d %d %d %d %d %d\n", window, gc, drawable, x1, y1, x2, y2, w, h); gdk_draw_drawable (window, gc, drawable, x1, y1, x2, y2, w, h); } diff --git a/plugins/gtkui/ddbtabstrip.c b/plugins/gtkui/ddbtabstrip.c index 6f01499b..82b11003 100644 --- a/plugins/gtkui/ddbtabstrip.c +++ b/plugins/gtkui/ddbtabstrip.c @@ -461,7 +461,7 @@ tabstrip_render (DdbTabStrip *ts) { } if (need_draw_moving) { x = -ts->hscrollpos + tabs_left_margin; - for (idx = 0; idx < 10; idx++) { + for (idx = 0; idx < cnt; idx++) { w = widths[idx]; if (idx == ts->dragging) { #if 0 @@ -475,7 +475,7 @@ tabstrip_render (DdbTabStrip *ts) { break; } if (w > 0) { -// gtk_paint_box (widget->style, backbuf, GTK_STATE_SELECTED, GTK_SHADOW_OUT, NULL, widget, "button", x, 0, w, h); + //gtk_paint_box (widget->style, backbuf, GTK_STATE_SELECTED, GTK_SHADOW_OUT, NULL, widget, "button", x, 0, w, h); ddb_tabstrip_draw_tab (widget, backbuf, 1, x, y, w, h); char tab_title[100]; plt_get_title_wrapper (idx, tab_title, sizeof (tab_title)); diff --git a/plugins/vfs_curl/vfs_curl.c b/plugins/vfs_curl/vfs_curl.c index 22b00216..eb64b17d 100644 --- a/plugins/vfs_curl/vfs_curl.c +++ b/plugins/vfs_curl/vfs_curl.c @@ -25,8 +25,10 @@ #include <time.h> #include "../../deadbeef.h" -//#define trace(...) { fprintf(stderr, __VA_ARGS__); } -#define trace(fmt,...) +#pragma GCC optimize("O0") + +#define trace(...) { fprintf(stderr, __VA_ARGS__); } +//#define trace(fmt,...) #define min(x,y) ((x)<(y)?(x):(y)) #define max(x,y) ((x)>(y)?(x):(y)) @@ -40,12 +42,13 @@ static DB_functions_t *deadbeef; #define TIMEOUT 10 // in seconds -#define STATUS_INITIAL 0 -//#define STATUS_STARTING 1 -#define STATUS_READING 2 -#define STATUS_FINISHED 3 -#define STATUS_ABORTED 4 -#define STATUS_SEEK 5 +enum { + STATUS_INITIAL = 0, + STATUS_READING = 1, + STATUS_FINISHED = 2, + STATUS_ABORTED = 3, + STATUS_SEEK = 4, +}; typedef struct { DB_vfs_t *vfs; @@ -495,7 +498,7 @@ http_thread_func (void *ctx) { curl_easy_setopt (curl, CURLOPT_MAXREDIRS, 10); headers = curl_slist_append (headers, "Icy-Metadata:1"); curl_easy_setopt (curl, CURLOPT_HTTPHEADER, headers); - if (fp->pos > 0) { + if (fp->pos > 0 && fp->length >= 0) { curl_easy_setopt (curl, CURLOPT_RESUME_FROM, fp->pos); } if (deadbeef->conf_get_int ("network.proxy", 0)) { @@ -551,6 +554,23 @@ http_thread_func (void *ctx) { trace ("curl error:\n%s\n", http_err); } deadbeef->mutex_lock (fp->mutex); + if (status == 0 && fp->length < 0 && fp->status != STATUS_ABORTED && fp->status != STATUS_SEEK) { + trace ("vfs_curl: restarting stream\n"); + fp->status = STATUS_INITIAL; + fp->skipbytes = 0; + if (fp->content_type) { + free (fp->content_type); + fp->content_type = NULL; + } + fp->seektoend = 0; + fp->gotheader = 0; + fp->icyheader = 0; + fp->gotsomeheader = 0; + fp->wait_meta = 0; + fp->icy_metaint = 0; + deadbeef->mutex_unlock (fp->mutex); + continue; + } if (fp->status != STATUS_SEEK) { deadbeef->mutex_unlock (fp->mutex); break; diff --git a/plugins/vorbis/vorbis.c b/plugins/vorbis/vorbis.c index 6704f8fe..a7b95b29 100644 --- a/plugins/vorbis/vorbis.c +++ b/plugins/vorbis/vorbis.c @@ -144,7 +144,7 @@ cvorbis_init (DB_fileinfo_t *_info, DB_playItem_t *it) { ogg_info_t *info = (ogg_info_t *)_info; info->info.file = NULL; info->vi = NULL; - info->cur_bit_stream = -1; + info->cur_bit_stream = it->tracknum; info->ptrack = it; deadbeef->pl_item_ref (it); @@ -187,7 +187,7 @@ cvorbis_init (DB_fileinfo_t *_info, DB_playItem_t *it) { } // deadbeef->pl_set_item_duration (it, ov_time_total (&vorbis_file, -1)); } - info->vi = ov_info (&info->vorbis_file, -1); + info->vi = ov_info (&info->vorbis_file, info->cur_bit_stream); if (!info->vi) { // not a vorbis stream trace ("not a vorbis stream\n"); return -1; @@ -385,46 +385,64 @@ cvorbis_insert (DB_playItem_t *after, const char *fname) { trace ("ov_open_callbacks returned %d\n", err); return NULL; } - vi = ov_info (&vorbis_file, -1); - if (!vi) { // not a vorbis stream - trace ("vorbis: failed to ov_open %s\n", fname); - return NULL; - } - float duration = ov_time_total (&vorbis_file, -1); - int totalsamples = ov_pcm_total (&vorbis_file, -1); - DB_playItem_t *it = deadbeef->pl_item_alloc (); - it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id); - it->fname = strdup (fname); - it->filetype = "OggVorbis"; - deadbeef->pl_set_item_duration (it, duration); + long nstreams = ov_streams (&vorbis_file); + int currentsample = 0; + for (int stream = 0; stream < nstreams; stream++) { + vi = ov_info (&vorbis_file, stream); + if (!vi) { // not a vorbis stream + trace ("vorbis: ov_info failed for file %s stream %d\n", fname, stream); + continue; + } + float duration = ov_time_total (&vorbis_file, stream); + int totalsamples = ov_pcm_total (&vorbis_file, stream); - // metainfo - vorbis_comment *vc = ov_comment (&vorbis_file, -1); - update_vorbis_comments (it, vc); - int samplerate = vi->rate; - ov_clear (&vorbis_file); + DB_playItem_t *it = deadbeef->pl_item_alloc (); + it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id); + it->fname = strdup (fname); + it->filetype = "OggVorbis"; + it->tracknum = stream; + deadbeef->pl_set_item_duration (it, duration); + if (nstreams > 0) { + it->startsample = currentsample; + it->endsample = currentsample + totalsamples; + deadbeef->pl_set_item_flags (it, DDB_IS_SUBTRACK); + } - DB_playItem_t *cue = deadbeef->pl_insert_cue (after, it, totalsamples, samplerate); - if (cue) { - deadbeef->pl_item_unref (it); - deadbeef->pl_item_unref (cue); - return cue; - } - - // embedded cue - const char *cuesheet = deadbeef->pl_find_meta (it, "cuesheet"); - if (cuesheet) { - cue = deadbeef->pl_insert_cue_from_buffer (after, it, cuesheet, strlen (cuesheet), totalsamples, samplerate); - if (cue) { - deadbeef->pl_item_unref (it); - deadbeef->pl_item_unref (cue); - return cue; + // metainfo + vorbis_comment *vc = ov_comment (&vorbis_file, stream); + update_vorbis_comments (it, vc); + int samplerate = vi->rate; + + if (nstreams == 1) { + DB_playItem_t *cue = deadbeef->pl_insert_cue (after, it, totalsamples, samplerate); + if (cue) { + deadbeef->pl_item_unref (it); + deadbeef->pl_item_unref (cue); + ov_clear (&vorbis_file); + return cue; + } + + // embedded cue + const char *cuesheet = deadbeef->pl_find_meta (it, "cuesheet"); + if (cuesheet) { + cue = deadbeef->pl_insert_cue_from_buffer (after, it, cuesheet, strlen (cuesheet), totalsamples, samplerate); + if (cue) { + deadbeef->pl_item_unref (it); + deadbeef->pl_item_unref (cue); + ov_clear (&vorbis_file); + return cue; + } + } + } + else { + currentsample += totalsamples; } - } - after = deadbeef->pl_insert_item (after, it); - deadbeef->pl_item_unref (it); + after = deadbeef->pl_insert_item (after, it); + deadbeef->pl_item_unref (it); + } + ov_clear (&vorbis_file); return after; } @@ -464,14 +482,14 @@ cvorbis_read_metadata (DB_playItem_t *it) { trace ("cvorbis_read_metadata: ov_open_callbacks returned %d\n", res); goto error; } - vi = ov_info (&vorbis_file, -1); + vi = ov_info (&vorbis_file, it->tracknum); if (!vi) { // not a vorbis stream trace ("cvorbis_read_metadata: failed to ov_open %s\n", it->fname); goto error; } // metainfo - vorbis_comment *vc = ov_comment (&vorbis_file, -1); + vorbis_comment *vc = ov_comment (&vorbis_file, it->tracknum); if (vc) { update_vorbis_comments (it, vc); } |