summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/playlist.c10
-rw-r--r--common/playlist.h7
-rw-r--r--player/core.h3
-rw-r--r--player/loadfile.c38
4 files changed, 39 insertions, 19 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);
+
#endif
diff --git a/player/core.h b/player/core.h
index bd2a15d7d0..5c40e48674 100644
--- a/player/core.h
+++ b/player/core.h
@@ -187,7 +187,8 @@ typedef struct MPContext {
struct osd_progbar_state osd_progbar;
struct playlist *playlist;
- char *filename; // currently playing file
+ struct playlist_entry *playing; // currently playing file
+ char *filename; // always the same as playing->filename (or NULL)
struct mp_resolve_result *resolve_result;
enum stop_play_reason stop_play;
unsigned int initialized_flags; // which subsystems have been initialized
diff --git a/player/loadfile.c b/player/loadfile.c
index d81bfa7bc8..2917569017 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -1024,11 +1024,12 @@ static void play_current_file(struct MPContext *mpctx)
reset_playback_state(mpctx);
- if (mpctx->playlist->current)
- mpctx->filename = mpctx->playlist->current->filename;
-
- if (!mpctx->filename)
+ mpctx->playing = mpctx->playlist->current;
+ if (!mpctx->playing || !mpctx->playing->filename)
goto terminate_playback;
+ mpctx->playing->reserved += 1;
+
+ mpctx->filename = mpctx->playing->filename;
mpctx->add_osd_seek_info &= OSD_SEEK_INFO_EDITION;
@@ -1050,8 +1051,8 @@ static void play_current_file(struct MPContext *mpctx)
if (opts->position_resume)
mp_load_playback_resume(mpctx, mpctx->filename);
- load_per_file_options(mpctx->mconfig, mpctx->playlist->current->params,
- mpctx->playlist->current->num_params);
+ load_per_file_options(mpctx->mconfig, mpctx->playing->params,
+ mpctx->playing->num_params);
#if HAVE_LIBASS
if (opts->ass_style_override)
@@ -1083,7 +1084,7 @@ static void play_current_file(struct MPContext *mpctx)
}
int stream_flags = STREAM_READ;
if (!opts->load_unsafe_playlists)
- stream_flags |= mpctx->playlist->current->stream_flags;
+ stream_flags |= mpctx->playing->stream_flags;
mpctx->stream = stream_create(stream_filename, stream_flags, mpctx->global);
if (!mpctx->stream) { // error...
mp_process_input(mpctx);
@@ -1321,18 +1322,14 @@ terminate_playback:
if (mpctx->stop_play != PT_RESTART)
m_config_restore_backups(mpctx->mconfig);
- mpctx->filename = NULL;
mpctx->resolve_result = NULL;
- talloc_free(tmp);
- // Played/paused for longer than 3 seconds -> ok
- bool playback_short = mpctx->stop_play == AT_END_OF_FILE &&
- (playback_start < 0 || mp_time_sec() - playback_start < 3.0);
- bool init_failed = mpctx->stop_play == AT_END_OF_FILE &&
- (mpctx->shown_aframes == 0 && mpctx->shown_vframes == 0);
- if (mpctx->playlist->current && !mpctx->playlist->current_was_replaced) {
- mpctx->playlist->current->playback_short = playback_short;
- mpctx->playlist->current->init_failed = init_failed;
+ if (mpctx->playing && mpctx->stop_play == AT_END_OF_FILE) {
+ // Played/paused for longer than 3 seconds -> ok
+ mpctx->playing->playback_short =
+ playback_start < 0 || mp_time_sec() - playback_start < 3.0;
+ mpctx->playing->init_failed =
+ mpctx->shown_aframes == 0 && mpctx->shown_vframes == 0;
}
mp_notify(mpctx, MPV_EVENT_TRACKS_CHANGED, NULL);
@@ -1348,6 +1345,13 @@ terminate_playback:
default: end_event.reason = -1; break;
};
mp_notify(mpctx, MPV_EVENT_END_FILE, &end_event);
+
+ if (mpctx->playing)
+ playlist_entry_unref(mpctx->playing);
+ mpctx->playing = NULL;
+ mpctx->filename = NULL;
+
+ talloc_free(tmp);
}
// Determine the next file to play. Note that if this function returns non-NULL,