summaryrefslogtreecommitdiffstats
path: root/common/playlist.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-12-28 21:32:03 +0100
committerwm4 <wm4@nowhere>2019-12-28 21:32:15 +0100
commit5a261507173d28c762ba4f605d7983d928d4bf24 (patch)
treef178d1bfce80e7033232fc353ea292d37be3112f /common/playlist.c
parent582f3f7cc01f81345df5c20a012b1f47587e6a97 (diff)
downloadmpv-5a261507173d28c762ba4f605d7983d928d4bf24.tar.bz2
mpv-5a261507173d28c762ba4f605d7983d928d4bf24.tar.xz
command: add a playlist-unshuffle command
Has a number of restrictions. See: #2491, #7294
Diffstat (limited to 'common/playlist.c')
-rw-r--r--common/playlist.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/common/playlist.c b/common/playlist.c
index 300fc48bf9..1fd202b98f 100644
--- a/common/playlist.c
+++ b/common/playlist.c
@@ -33,6 +33,7 @@ struct playlist_entry *playlist_entry_new(const char *filename)
char *local_filename = mp_file_url_to_filename(e, bstr0(filename));
e->filename = local_filename ? local_filename : talloc_strdup(e, filename);
e->stream_flags = STREAM_ORIGIN_DIRECT;
+ e->original_index = -1;
return e;
}
@@ -141,6 +142,8 @@ void playlist_add_file(struct playlist *pl, const char *filename)
void playlist_shuffle(struct playlist *pl)
{
+ for (int n = 0; n < pl->num_entries; n++)
+ pl->entries[n]->original_index = n;
for (int n = 0; n < pl->num_entries - 1; n++) {
int j = (int)((double)(pl->num_entries - n) * rand() / (RAND_MAX + 1.0));
MPSWAP(struct playlist_entry *, pl->entries[n], pl->entries[n + j]);
@@ -148,6 +151,25 @@ void playlist_shuffle(struct playlist *pl)
playlist_update_indexes(pl, 0, -1);
}
+#define CMP_INT(a, b) ((a) == (b) ? 0 : ((a) > (b) ? 1 : -1))
+
+static int cmp_unshuffle(const void *a, const void *b)
+{
+ struct playlist_entry *ea = *(struct playlist_entry **)a;
+ struct playlist_entry *eb = *(struct playlist_entry **)b;
+
+ if (ea->original_index >= 0 && ea->original_index != eb->original_index)
+ return CMP_INT(ea->original_index, eb->original_index);
+ return CMP_INT(ea->pl_index, eb->pl_index);
+}
+
+void playlist_unshuffle(struct playlist *pl)
+{
+ if (pl->num_entries)
+ qsort(pl->entries, pl->num_entries, sizeof(pl->entries[0]), cmp_unshuffle);
+ playlist_update_indexes(pl, 0, -1);
+}
+
// (Explicitly ignores current_was_replaced.)
struct playlist_entry *playlist_get_first(struct playlist *pl)
{