1
0
Fork 0
forked from len0rd/rockbox

Playlists: Fix resuming from control commands with first_index > 0

add_track_to_playlist_unlocked only increased a playlist's
first index as necessary when its position parameter was
negative (i.e. one of the special insert positions was
specified).

A negative value was not stored in the control file, but
was always converted into an absolute position. Thus, any
adjustments to first_index weren't repeated when resuming
from the control file.

In particular, shuffled playlists were affected (in case of
first_index > 0), when inserting at positions <= first_index,
including appending a track to the end of a playlist. This
works by inserting at first_index and increasing first_index
by 1 afterwards.

Similarly, adding tracks in a shuffled fashion could increase
first index, whenever that was the value randomly calculated
for a track position, effectively appending it (I assume this
is on purpose).

To make sure that first_index adjustments are recovered when
resuming from the control file, and to be able to differentiate
between a prepended or appended track, store the special value
PLAYLIST_INSERT_LAST_ROTATED as the insert position in the
control file whenever first_index would have been used before,
and a special position (other than PLAYLIST_PREPEND) was
provided to the function.

Change-Id: I31f26796627fb136daeddd046cb1892bdf1b4014
This commit is contained in:
Christian Soffke 2023-11-05 02:32:39 +01:00
parent dd1063fc2c
commit e9b4275d1f
2 changed files with 35 additions and 7 deletions

View file

@ -1208,6 +1208,8 @@ static int remove_all_tracks_unlocked(struct playlist_info *playlist, bool write
* PLAYLIST_INSERT_FIRST - Add track immediately after current song, no * PLAYLIST_INSERT_FIRST - Add track immediately after current song, no
* matter what other tracks have been inserted * matter what other tracks have been inserted
* PLAYLIST_INSERT_LAST - Add track to end of playlist * PLAYLIST_INSERT_LAST - Add track to end of playlist
* PLAYLIST_INSERT_LAST_ROTATED - Add track to end of playlist, by inserting at
* first_index, then increasing first_index by 1
* PLAYLIST_INSERT_SHUFFLED - Add track at some random point between the * PLAYLIST_INSERT_SHUFFLED - Add track at some random point between the
* current playing track and end of playlist * current playing track and end of playlist
* PLAYLIST_INSERT_LAST_SHUFFLED - Add tracks in random order to the end of * PLAYLIST_INSERT_LAST_SHUFFLED - Add tracks in random order to the end of
@ -1260,11 +1262,15 @@ static int add_track_to_playlist_unlocked(struct playlist_info* playlist,
playlist->last_insert_pos = position; playlist->last_insert_pos = position;
break; break;
case PLAYLIST_INSERT_LAST: case PLAYLIST_INSERT_LAST:
if (playlist->first_index > 0) if (playlist->first_index <= 0)
position = insert_position = playlist->first_index; {
else
position = insert_position = playlist->amount; position = insert_position = playlist->amount;
playlist->last_insert_pos = position;
break;
}
/* fallthrough */
case PLAYLIST_INSERT_LAST_ROTATED:
position = insert_position = playlist->first_index;
playlist->last_insert_pos = position; playlist->last_insert_pos = position;
break; break;
case PLAYLIST_INSERT_SHUFFLED: case PLAYLIST_INSERT_SHUFFLED:
@ -1330,16 +1336,37 @@ static int add_track_to_playlist_unlocked(struct playlist_info* playlist,
if (orig_position < 0) if (orig_position < 0)
{ {
if (playlist->amount > 0 && insert_position <= playlist->index && if (playlist->amount > 0 && insert_position <= playlist->index &&
playlist->started) playlist->started && orig_position != PLAYLIST_INSERT_LAST_ROTATED)
playlist->index++; playlist->index++;
/*
* When inserting into a playlist at positions before or equal to first_index
* (unless PLAYLIST_PREPEND is specified explicitly), adjust first_index, so
* that track insertion near the end does not affect the start of the playlist
*/
if (playlist->amount > 0 && insert_position <= playlist->first_index && if (playlist->amount > 0 && insert_position <= playlist->first_index &&
orig_position != PLAYLIST_PREPEND && playlist->started) orig_position != PLAYLIST_PREPEND && playlist->started)
{
/*
* To ensure proper resuming from control file for a track that is supposed
* to be appended, but is inserted at first_index, store position as special
* value.
* If we were to store the position unchanged, i.e. use first_index,
* track would be prepended, instead, after resuming.
*/
if (insert_position == playlist->first_index)
position = PLAYLIST_INSERT_LAST_ROTATED;
playlist->first_index++; playlist->first_index++;
} }
}
else if (playlist->amount > 0 && insert_position < playlist->first_index &&
playlist->started)
playlist->first_index++;
if (insert_position < playlist->last_insert_pos || if (insert_position < playlist->last_insert_pos ||
(insert_position == playlist->last_insert_pos && position < 0)) (insert_position == playlist->last_insert_pos && position < 0 &&
position != PLAYLIST_INSERT_LAST_ROTATED))
playlist->last_insert_pos++; playlist->last_insert_pos++;
if (seek_pos < 0 && playlist->control_fd >= 0) if (seek_pos < 0 && playlist->control_fd >= 0)

View file

@ -62,7 +62,8 @@ enum {
PLAYLIST_INSERT_FIRST = -4, PLAYLIST_INSERT_FIRST = -4,
PLAYLIST_INSERT_SHUFFLED = -5, PLAYLIST_INSERT_SHUFFLED = -5,
PLAYLIST_REPLACE = -6, PLAYLIST_REPLACE = -6,
PLAYLIST_INSERT_LAST_SHUFFLED = -7 PLAYLIST_INSERT_LAST_SHUFFLED = -7,
PLAYLIST_INSERT_LAST_ROTATED = -8
}; };
struct playlist_info struct playlist_info