path: root/common
diff options
authorwm4 <wm4@nowhere>2014-09-09 00:38:38 +0200
committerwm4 <wm4@nowhere>2014-09-09 01:23:10 +0200
commitc0fbab7a7cfcca8c1fa6ac5ea532924b35938923 (patch)
tree12830798510d03bbdef2c8663a7a1c63c92619ad /common
parent9cb1e2c58ca21f12b65167eb8a3640bda8eadfd5 (diff)
player: deal with some corner cases with playlist navigation
The purpose is making accessing the current playlist entry saner when commands are executed during initialization, termination, or after playlist navigation commands. For example, the "playlist_remove current" command will invalidate playlist->current - but some things still access the playlist entry even on uninit. Until now, checking stop_play implicitly took care of it, so it worked, but it was still messy. Introduce the mpctx->playing field, which points to the current playlist entry, even if the entry was removed and/or the playlist's current entry was moved (e.g. due to playlist navigation).
Diffstat (limited to 'common')
2 files changed, 16 insertions, 1 deletions
diff --git a/common/playlist.c b/common/playlist.c
index 46ae36d643..857f5cb030 100644
--- a/common/playlist.c
+++ b/common/playlist.c
@@ -106,10 +106,18 @@ static void playlist_unlink(struct playlist *pl, struct playlist_entry *entry)
entry->pl = NULL;
+void playlist_entry_unref(struct playlist_entry *e)
+ e->reserved--;
+ if (e->reserved < 0)
+ talloc_free(e);
void playlist_remove(struct playlist *pl, struct playlist_entry *entry)
playlist_unlink(pl, entry);
- talloc_free(entry);
+ entry->removed = true;
+ playlist_entry_unref(entry);
void playlist_clear(struct playlist *pl)
diff --git a/common/playlist.h b/common/playlist.h
index 6c609733da..e0ac816774 100644
--- a/common/playlist.h
+++ b/common/playlist.h
@@ -41,6 +41,11 @@ struct playlist_entry {
bool playback_short : 1;
// Set to true if not at least 1 frame (audio or video) could be played.
bool init_failed : 1;
+ // Entry was removed with playlist_remove (etc.), but not deallocated.
+ bool removed : 1;
+ // Additional refcount. Normally (reserved==0), the entry is owned by the
+ // playlist, and this can be used to keep the entry alive.
+ int reserved;
// Used to reject loading of unsafe entries from external playlists.
// Can have any of the following bit flags set:
// STREAM_SAFE_ONLY: only allow streams marked with is_safe
@@ -89,4 +94,6 @@ struct playlist_entry *playlist_entry_from_index(struct playlist *pl, int index)
struct mpv_global;
struct playlist *playlist_parse_file(const char *file, struct mpv_global *global);
+void playlist_entry_unref(struct playlist_entry *e);