summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/menus/playlist_menu.c3
-rwxr-xr-xapps/playlist.c74
-rw-r--r--apps/playlist.h8
3 files changed, 48 insertions, 37 deletions
diff --git a/apps/menus/playlist_menu.c b/apps/menus/playlist_menu.c
index be3ad30..f4fa6bc 100644
--- a/apps/menus/playlist_menu.c
+++ b/apps/menus/playlist_menu.c
@@ -61,7 +61,7 @@ int save_playlist_screen(struct playlist_info* playlist)
if (!kbd_input(temp, sizeof(temp)))
{
- playlist_save(playlist, temp);
+ playlist_save(playlist, temp, NULL, 0);
/* reload in case playlist was saved to cwd */
reload_directory();
@@ -113,4 +113,3 @@ MAKE_MENU(playlist_options, ID2P(LANG_PLAYLISTS), NULL,
Icon_Playlist,
&create_playlist_item, &view_cur_playlist,
&save_playlist, &clear_catalog_directory_item);
-
diff --git a/apps/playlist.c b/apps/playlist.c
index a066dd2..b0f7964 100755
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -105,6 +105,7 @@
#include "root_menu.h"
#include "plugin.h" /* To borrow a temp buffer to rewrite a .m3u8 file */
#include "panic.h"
+#include "logdiskf.h"
#define PLAYLIST_CONTROL_FILE_VERSION 2
@@ -523,6 +524,9 @@ static int add_indices_to_playlist(struct playlist_info* playlist,
bool store_index;
unsigned char *p;
int result = 0;
+ /* get emergency buffer so we don't fail horribly */
+ if (!buflen)
+ buffer = __builtin_alloca((buflen = 64));
if(-1 == playlist->fd)
playlist->fd = open_utf8(playlist->filename, O_RDONLY);
@@ -1983,8 +1987,6 @@ static int move_callback(int handle, void* current, void* new)
playlist->indices = new;
else if (current == playlist->filenames)
playlist->filenames = new;
- /* buffer can possibly point to a new buffer temporarily (playlist_save()).
- * just don't overwrite the pointer to that temp buffer */
else if (current == playlist->buffer)
playlist->buffer = new;
@@ -3528,8 +3530,11 @@ int playlist_get_track_info(struct playlist_info* playlist, int index,
return 0;
}
-/* save the current dynamic playlist to specified file */
-int playlist_save(struct playlist_info* playlist, char *filename)
+/* save the current dynamic playlist to specified file. The
+ * temp_buffer (if not NULL) is used as a scratchpad when loading indices
+ * (slow if not used). */
+int playlist_save(struct playlist_info* playlist, char *filename,
+ void* temp_buffer, size_t temp_buffer_size)
{
int fd;
int i, index;
@@ -3538,6 +3543,17 @@ int playlist_save(struct playlist_info* playlist, char *filename)
char tmp_buf[MAX_PATH+1];
int result = 0;
bool overwrite_current = false;
+ int *seek_buf;
+ bool reparse;
+
+ ALIGN_BUFFER(temp_buffer, temp_buffer_size, sizeof(int));
+ seek_buf = temp_buffer;
+
+ /* without temp_buffer, or when it's depleted, and we overwrite the current
+ * playlist then the newly saved playlist has to be reparsed. With
+ * sufficient temp_buffer the indicies be remembered and added without
+ * reparsing */
+ reparse = temp_buffer_size == 0;
if (!playlist)
playlist = &current_playlist;
@@ -3556,23 +3572,9 @@ int playlist_save(struct playlist_info* playlist, char *filename)
if (!strncmp(playlist->filename, path, strlen(path)))
{
- /* Attempting to overwrite current playlist file.*/
-
- if (playlist->buffer_size < (int)(playlist->amount * sizeof(int)))
- {
- /* not enough buffer space to store updated indices */
- /* Try to get a buffer */
- playlist->buffer = plugin_get_buffer((size_t*)&playlist->buffer_size);
- if (playlist->buffer_size < (int)(playlist->amount * sizeof(int)))
- {
- splash(HZ*2, ID2P(LANG_PLAYLIST_ACCESS_ERROR));
- result = -1;
- goto reset_old_buffer;
- }
- }
-
- /* use temporary pathname */
- snprintf(path, sizeof(path), "%s_temp", playlist->filename);
+ /* Attempting to overwrite current playlist file.
+ * use temporary pathname and overwrite later */
+ strlcat(path, "_temp", sizeof(path));
overwrite_current = true;
}
@@ -3624,8 +3626,8 @@ int playlist_save(struct playlist_info* playlist, char *filename)
break;
}
- if (overwrite_current)
- playlist->seek_buf[count] = lseek(fd, 0, SEEK_CUR);
+ if (overwrite_current && !reparse)
+ seek_buf[count] = lseek(fd, 0, SEEK_CUR);
if (fdprintf(fd, "%s\n", tmp_buf) < 0)
{
@@ -3635,6 +3637,10 @@ int playlist_save(struct playlist_info* playlist, char *filename)
}
count++;
+ /* when our temp buffer is depleted we have to fall
+ * back to reparsing the playlist (slow) */
+ if (count*sizeof(int) >= temp_buffer_size)
+ reparse = true;
if ((count % PLAYLIST_DISPLAY_COUNT) == 0)
display_playlist_count(count, ID2P(LANG_PLAYLIST_SAVE_COUNT),
@@ -3666,17 +3672,25 @@ int playlist_save(struct playlist_info* playlist, char *filename)
playlist->fd = open_utf8(playlist->filename, O_RDONLY);
if (playlist->fd >= 0)
{
- index = playlist->first_index;
- for (i=0, count=0; i<playlist->amount; i++)
+ if (!reparse)
{
- if (!(playlist->indices[index] & PLAYLIST_QUEUE_MASK))
+ index = playlist->first_index;
+ for (i=0, count=0; i<playlist->amount; i++)
{
- playlist->indices[index] = playlist->seek_buf[count];
- count++;
+ if (!(playlist->indices[index] & PLAYLIST_QUEUE_MASK))
+ {
+ playlist->indices[index] = seek_buf[count];
+ count++;
+ }
+ index = (index+1)%playlist->amount;
}
- index = (index+1)%playlist->amount;
}
-
+ else
+ {
+ NOTEF("reparsing current playlist (slow)");
+ playlist->amount = 0;
+ add_indices_to_playlist(playlist, temp_buffer, temp_buffer_size);
+ }
/* we need to recreate control because inserted tracks are
now part of the playlist and shuffle has been
invalidated */
diff --git a/apps/playlist.h b/apps/playlist.h
index 6314e9a..a331838 100644
--- a/apps/playlist.h
+++ b/apps/playlist.h
@@ -88,10 +88,7 @@ struct playlist_info
bool in_ram; /* playlist stored in ram (dirplay) */
int buffer_handle; /* handle to the below buffer (-1 if non-buflib) */
- union {
- volatile char *buffer;/* buffer for in-ram playlists */
- int *seek_buf; /* buffer for seeks in real playlists */
- };
+ volatile char *buffer;/* buffer for in-ram playlists */
int buffer_size; /* size of buffer */
int buffer_end_pos; /* last position where buffer was written */
int index; /* index of current playing track */
@@ -184,7 +181,8 @@ char *playlist_get_name(const struct playlist_info* playlist, char *buf,
int buf_size);
int playlist_get_track_info(struct playlist_info* playlist, int index,
struct playlist_track_info* info);
-int playlist_save(struct playlist_info* playlist, char *filename);
+int playlist_save(struct playlist_info* playlist, char *filename,
+ void* temp_buffer, size_t temp_buffer_size);
int playlist_directory_tracksearch(const char* dirname, bool recurse,
int (*callback)(char*, void*),
void* context);