diff options
-rw-r--r-- | deadbeef.h | 1 | ||||
-rw-r--r-- | playlist.c | 34 | ||||
-rw-r--r-- | playlist.h | 5 | ||||
-rw-r--r-- | plugins.c | 1 | ||||
-rw-r--r-- | plugins/gtkui/gtkui.c | 22 | ||||
-rw-r--r-- | streamer.c | 116 | ||||
-rw-r--r-- | streamer.h | 6 |
7 files changed, 148 insertions, 37 deletions
@@ -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); @@ -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; @@ -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 @@ -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); @@ -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; + } +} @@ -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 |