summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deadbeef.h1
-rw-r--r--playlist.c34
-rw-r--r--playlist.h5
-rw-r--r--plugins.c1
-rw-r--r--plugins/gtkui/gtkui.c22
-rw-r--r--streamer.c116
-rw-r--r--streamer.h6
7 files changed, 148 insertions, 37 deletions
diff --git a/deadbeef.h b/deadbeef.h
index e7401cf9..95445cca 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -263,6 +263,7 @@ typedef struct {
void (*streamer_set_bitrate) (int bitrate);
int (*streamer_get_apx_bitrate) (void);
struct DB_fileinfo_s *(*streamer_get_current_fileinfo) (void);
+ int (*streamer_get_current_playlist) (void);
// process control
const char *(*get_config_dir) (void);
void (*quit) (void);
diff --git a/playlist.c b/playlist.c
index b8e7cac8..59d60eae 100644
--- a/playlist.c
+++ b/playlist.c
@@ -227,6 +227,16 @@ void
plt_remove (int plt) {
int i;
PLT_LOCK;
+
+ // find playlist and notify streamer
+ playlist_t *p = playlists_head;
+ playlist_t *prev = NULL;
+ for (i = 0; p && i < plt; i++) {
+ prev = p;
+ p = p->next;
+ }
+ streamer_notify_playlist_deleted (p);
+
if (!plt_loading && (playlists_head && !playlists_head->next)) {
trace ("warning: deleting last playlist\n");
pl_clear ();
@@ -237,12 +247,6 @@ plt_remove (int plt) {
plug_trigger_event (DB_EV_PLAYLISTSWITCH, 0);
return;
}
- playlist_t *prev = NULL;
- playlist_t *p = playlists_head;
- for (i = 0; p && i < plt; i++) {
- prev = p;
- p = p->next;
- }
if (i != plt) {
trace ("plt_remove %d failed\n", i);
}
@@ -311,6 +315,22 @@ plt_get_curr (void) {
}
int
+plt_get_idx_of (playlist_t *plt) {
+ int i;
+ PLT_LOCK;
+ playlist_t *p = playlists_head;
+ for (i = 0; p && i < playlists_count; i++) {
+ if (p == plt) {
+ PLT_UNLOCK;
+ return i;
+ }
+ p = p->next;
+ }
+ PLT_UNLOCK;
+ return -1;
+}
+
+int
plt_get_title (int plt, char *buffer, int bufsize) {
int i;
PLT_LOCK;
@@ -1961,7 +1981,7 @@ pl_delete_all_meta (playItem_t *it) {
while (it->meta) {
metaInfo_t *m = it->meta;
it->meta = m->next;
- free (m->value);
+ metacache_remove_string (m->value);
free (m);
}
it->meta = NULL;
diff --git a/playlist.h b/playlist.h
index d92050ac..37bd17b6 100644
--- a/playlist.h
+++ b/playlist.h
@@ -23,7 +23,7 @@
typedef struct metaInfo_s {
const char *key;
- char *value;
+ const char *value;
struct metaInfo_s *next;
} metaInfo_t;
@@ -116,6 +116,9 @@ int
plt_get_curr (void);
int
+plt_get_idx_of (playlist_t *plt);
+
+int
plt_get_title (int plt, char *buffer, int bufsize);
int
diff --git a/plugins.c b/plugins.c
index 89a0ce69..19ea0a20 100644
--- a/plugins.c
+++ b/plugins.c
@@ -86,6 +86,7 @@ static DB_functions_t deadbeef_api = {
.streamer_set_bitrate = streamer_set_bitrate,
.streamer_get_apx_bitrate = streamer_get_apx_bitrate,
.streamer_get_current_fileinfo = streamer_get_current_fileinfo,
+ .streamer_get_current_playlist = streamer_get_current_playlist,
// process control
.get_config_dir = plug_get_config_dir,
.quit = plug_quit,
diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c
index 07316648..8c011a5a 100644
--- a/plugins/gtkui/gtkui.c
+++ b/plugins/gtkui/gtkui.c
@@ -571,6 +571,12 @@ on_add_location_activate (GtkMenuItem *menuitem,
static void
songchanged (DdbListview *ps, int from, int to) {
+ int str_plt = deadbeef->streamer_get_current_playlist ();
+ int plt = deadbeef->plt_get_curr ();
+ if (plt != str_plt) {
+ // have nothing to do here -- active playlist is not the one with playing song
+ return;
+ }
if (!ddb_listview_is_scrolling (ps) && to != -1) {
if (deadbeef->conf_get_int ("playlist.scroll.followplayback", 0)) {
ddb_listview_scroll_to (ps, to);
@@ -582,13 +588,17 @@ songchanged (DdbListview *ps, int from, int to) {
if (from >= 0) {
DB_playItem_t *it = deadbeef->pl_get_for_idx_and_iter (from, PL_MAIN);
- ddb_listview_draw_row (ps, from, it);
- deadbeef->pl_item_unref (it);
+ if (it) {
+ ddb_listview_draw_row (ps, from, it);
+ deadbeef->pl_item_unref (it);
+ }
}
if (to >= 0) {
DB_playItem_t *it = deadbeef->pl_get_for_idx_and_iter (to, PL_MAIN);
- ddb_listview_draw_row (ps, to, it);
- deadbeef->pl_item_unref (it);
+ if (it) {
+ ddb_listview_draw_row (ps, to, it);
+ deadbeef->pl_item_unref (it);
+ }
}
}
@@ -606,7 +616,7 @@ update_win_title_idle (gpointer data) {
// show notification
#if HAVE_NOTIFY
if (to != -1 && deadbeef->conf_get_int ("gtkui.notify.enable", 0)) {
- DB_playItem_t *track = deadbeef->pl_get_for_idx (to);
+ DB_playItem_t *track = deadbeef->streamer_get_playing_track ();//deadbeef->pl_get_for_idx (to);
if (track) {
char cmd [1024];
deadbeef->pl_format_title (track, -1, cmd, sizeof (cmd), -1, deadbeef->conf_get_str ("gtkui.notify.format", NOTIFY_DEFAULT_FORMAT));
@@ -628,7 +638,7 @@ update_win_title_idle (gpointer data) {
// update window title
if (from >= 0 || to >= 0) {
if (to >= 0) {
- DB_playItem_t *it = deadbeef->pl_get_for_idx (to);
+ DB_playItem_t *it = deadbeef->streamer_get_playing_track ();;
if (it) { // it might have been deleted after event was sent
current_track_changed (it);
deadbeef->pl_item_unref (it);
diff --git a/streamer.c b/streamer.c
index 0ace51e9..5a91a739 100644
--- a/streamer.c
+++ b/streamer.c
@@ -79,6 +79,7 @@ static float playpos = 0; // play position of current song
static int avg_bitrate = -1; // avg bitrate of current song
static int last_bitrate = -1; // last bitrate of current song
+static playlist_t *streamer_playlist;
static playItem_t *playing_track;
static playItem_t *streaming_track;
static playItem_t *playlist_track;
@@ -92,22 +93,69 @@ static DB_FILE *streamer_file;
playItem_t *
streamer_get_streaming_track (void) {
+ pl_item_ref (streaming_track);
return streaming_track;
}
playItem_t *
streamer_get_playing_track (void) {
- return playing_track ? playing_track : playlist_track;
+ playItem_t *it = playing_track ? playing_track : playlist_track;
+ if (it) {
+ pl_item_ref (it);
+ }
+ return it;
+}
+
+int
+str_get_idx_of (playItem_t *it) {
+ plt_lock ();
+ if (!streamer_playlist) {
+ streamer_playlist = plt_get_curr_ptr ();
+ }
+ playItem_t *c = streamer_playlist->head[PL_MAIN];
+ int idx = 0;
+ while (c && c != it) {
+ c = c->next[PL_MAIN];
+ idx++;
+ }
+ if (!c) {
+ return -1;
+ }
+ plt_unlock ();
+ return idx;
+}
+
+playItem_t *
+str_get_for_idx (int idx) {
+ plt_lock ();
+ if (!streamer_playlist) {
+ streamer_playlist = plt_get_curr_ptr ();
+ }
+ playItem_t *it = streamer_playlist->head[PL_MAIN];
+ while (idx--) {
+ if (!it)
+ return NULL;
+ it = it->next[PL_MAIN];
+ }
+ if (it) {
+ pl_item_ref (it);
+ }
+ plt_unlock ();
+ return it;
}
+
int
streamer_move_to_nextsong (int reason) {
pl_global_lock ();
- playlist_t *plt = plt_get_curr_ptr ();
+ if (!streamer_playlist) {
+ streamer_playlist = plt_get_curr_ptr ();
+ }
+ playlist_t *plt = streamer_playlist;
playItem_t *it = pl_playqueue_getnext ();
if (it) {
pl_playqueue_pop ();
- int r = pl_get_idx_of (it);
+ int r = str_get_idx_of (it);
pl_item_unref (it);
streamer_set_nextsong (r, 1);
pl_global_unlock ();
@@ -145,7 +193,7 @@ streamer_move_to_nextsong (int reason) {
pl_global_unlock ();
return -1;
}
- int r = pl_get_idx_of (it);
+ int r = str_get_idx_of (it);
streamer_set_nextsong (r, 1);
pl_global_unlock ();
return 0;
@@ -153,7 +201,7 @@ streamer_move_to_nextsong (int reason) {
else {
trace ("pl_next_song: reason=%d, loop=%d\n", reason, pl_loop_mode);
if (reason == 0 && pl_loop_mode == PLAYBACK_MODE_LOOP_SINGLE) { // song finished, loop mode is "loop 1 track"
- int r = pl_get_idx_of (curr);
+ int r = str_get_idx_of (curr);
streamer_set_nextsong (r, 1);
pl_global_unlock ();
return 0;
@@ -181,7 +229,7 @@ streamer_move_to_nextsong (int reason) {
pl_global_unlock ();
return -1;
}
- int r = pl_get_idx_of (it);
+ int r = str_get_idx_of (it);
streamer_set_nextsong (r, 1);
pl_global_unlock ();
return 0;
@@ -191,7 +239,7 @@ streamer_move_to_nextsong (int reason) {
playItem_t *it = NULL;
if (curr) {
if (reason == 0 && pl_loop_mode == PLAYBACK_MODE_LOOP_SINGLE) { // loop same track
- int r = pl_get_idx_of (curr);
+ int r = str_get_idx_of (curr);
streamer_set_nextsong (r, 1);
pl_global_unlock ();
return 0;
@@ -213,14 +261,14 @@ streamer_move_to_nextsong (int reason) {
pl_global_unlock ();
return -1;
}
- int r = pl_get_idx_of (it);
+ int r = str_get_idx_of (it);
streamer_set_nextsong (r, 1);
pl_global_unlock ();
return 0;
}
else if (pl_order == PLAYBACK_ORDER_RANDOM) { // random
if (reason == 0 && pl_loop_mode == PLAYBACK_MODE_LOOP_SINGLE && curr) {
- int r = pl_get_idx_of (curr);
+ int r = str_get_idx_of (curr);
streamer_set_nextsong (r, 1);
pl_global_unlock ();
return 0;
@@ -234,7 +282,10 @@ streamer_move_to_nextsong (int reason) {
int
streamer_move_to_prevsong (void) {
plt_lock ();
- playlist_t *plt = plt_get_curr_ptr ();
+ if (!streamer_playlist) {
+ streamer_playlist = plt_get_curr_ptr ();
+ }
+ playlist_t *plt = streamer_playlist;
pl_playqueue_clear ();
if (!plt->head[PL_MAIN]) {
streamer_set_nextsong (-2, 1);
@@ -280,7 +331,7 @@ streamer_move_to_prevsong (void) {
plt_unlock ();
return -1;
}
- int r = pl_get_idx_of (it);
+ int r = str_get_idx_of (it);
streamer_set_nextsong (r, 1);
return 0;
}
@@ -299,7 +350,7 @@ streamer_move_to_prevsong (void) {
plt_unlock ();
return -1;
}
- int r = pl_get_idx_of (it);
+ int r = str_get_idx_of (it);
streamer_set_nextsong (r, 1);
plt_unlock ();
return 0;
@@ -343,8 +394,8 @@ streamer_song_removed_notify (playItem_t *it) {
static int
streamer_set_current (playItem_t *it) {
int from, to;
- from = playing_track ? pl_get_idx_of (playing_track) : -1;
- to = it ? pl_get_idx_of (it) : -1;
+ from = playing_track ? str_get_idx_of (playing_track) : -1;
+ to = it ? str_get_idx_of (it) : -1;
if (!playing_track || p_isstopped ()) {
streamer_buffering = 1;
playlist_track = it;
@@ -468,6 +519,9 @@ streamer_set_nextsong (int song, int pstate) {
nextsong = song;
nextsong_pstate = pstate;
if (p_isstopped ()) {
+ if (pstate == 1) { // means user initiated this
+ streamer_playlist = plt_get_curr_ptr ();
+ }
// no sense to wait until end of previous song, reset buffer
bytes_until_next_song = 0;
playpos = 0;
@@ -507,7 +561,7 @@ streamer_thread (void *ctx) {
badsong = -1;
continue;
}
- playItem_t *try = pl_get_for_idx (sng);
+ playItem_t *try = str_get_for_idx (sng);
if (!try) { // track is not in playlist
trace ("track #%d is not in playlist; stopping playback\n", sng);
p_stop ();
@@ -563,7 +617,7 @@ streamer_thread (void *ctx) {
}
}
else if (nextsong == -2 && (nextsong_pstate==0 || bytes_until_next_song == 0)) {
- int from = playing_track ? pl_get_idx_of (playing_track) : -1;
+ int from = playing_track ? str_get_idx_of (playing_track) : -1;
bytes_until_next_song = -1;
trace ("nextsong=-2\n");
nextsong = -1;
@@ -594,8 +648,8 @@ streamer_thread (void *ctx) {
continue;
}
trace ("bytes_until_next_song=0, starting playback of new song\n");
- int from = playing_track ? pl_get_idx_of (playing_track) : -1;
- int to = streaming_track ? pl_get_idx_of (streaming_track) : -1;
+ int from = playing_track ? str_get_idx_of (playing_track) : -1;
+ int to = streaming_track ? str_get_idx_of (streaming_track) : -1;
trace ("from=%d, to=%d\n", from, to);
trace ("sending songchanged\n");
messagepump_push (M_SONGCHANGED, 0, from, to);
@@ -694,7 +748,7 @@ streamer_thread (void *ctx) {
bytes_until_next_song = -1;
streamer_buffering = 1;
- int trk = pl_get_idx_of (streaming_track);
+ int trk = str_get_idx_of (streaming_track);
if (trk != -1) {
messagepump_push (M_TRACKCHANGED, 0, trk, 0);
}
@@ -724,7 +778,7 @@ streamer_thread (void *ctx) {
}
streamer_buffering = 1;
- int trk = pl_get_idx_of (streaming_track);
+ int trk = str_get_idx_of (streaming_track);
if (trk != -1) {
messagepump_push (M_TRACKCHANGED, 0, trk, 0);
}
@@ -777,7 +831,7 @@ streamer_thread (void *ctx) {
if (streambuffer_fill > 128000 && streamer_buffering || !streaming_track) {
streamer_buffering = 0;
if (streaming_track) {
- int trk = pl_get_idx_of (streaming_track);
+ int trk = str_get_idx_of (streaming_track);
if (trk != -1) {
messagepump_push (M_TRACKCHANGED, 0, trk, 0);
}
@@ -1365,13 +1419,13 @@ streamer_play_current_track (void) {
plug_trigger_event_paused (0);
}
else if (plt->current_row[PL_MAIN] != -1) {
- // play currently selected track
+ // play currently selected track in current playlist
p_stop ();
// get next song in queue
int idx = -1;
playItem_t *next = pl_playqueue_getnext ();
if (next) {
- idx = pl_get_idx_of (next);
+ idx = str_get_idx_of (next);
pl_playqueue_pop ();
}
else {
@@ -1379,6 +1433,7 @@ streamer_play_current_track (void) {
}
streamer_set_nextsong (idx, 1);
+ streamer_playlist = plt;
}
else {
// restart currently playing track
@@ -1391,3 +1446,18 @@ struct DB_fileinfo_s *
streamer_get_current_fileinfo (void) {
return fileinfo;
}
+
+int
+streamer_get_current_playlist (void) {
+ if (!streamer_playlist) {
+ streamer_playlist = plt_get_curr_ptr ();
+ }
+ return plt_get_idx_of (streamer_playlist);
+}
+
+void
+streamer_notify_playlist_deleted (playlist_t *plt) {
+ if (plt == streamer_playlist) {
+ streamer_playlist = NULL;
+ }
+}
diff --git a/streamer.h b/streamer.h
index b8398aea..77076206 100644
--- a/streamer.h
+++ b/streamer.h
@@ -95,4 +95,10 @@ streamer_move_to_randomsong (void);
struct DB_fileinfo_s *
streamer_get_current_fileinfo (void);
+int
+streamer_get_current_playlist (void);
+
+void
+streamer_notify_playlist_deleted (playlist_t *plt);
+
#endif // __STREAMER_H