From bebf71a08bb8e8f6022852ce6545cf0de580229d Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Tue, 8 Apr 2014 22:52:37 +0200 Subject: playlist: Get rid of plugin buffer use in playlist_save(). The plugin buffer was used only to avoid reparsing the playlist, so non-essential. But when it was used it conflicted with the playlist viewer which already uses the plugin buffer for playlist purposes simultaneously. It only works by accident. Since the reparse avoidance is non-essential don't do it for now. A temp buffer can be passed to playlist_save() to enable it but the only caller (as of now) does not do that. Change-Id: I3f75f89d8551e1ec38800268b273105faba0efbf --- apps/menus/playlist_menu.c | 3 +- apps/playlist.c | 74 +++++++++++++++++++++++++++------------------- apps/playlist.h | 8 ++--- 3 files changed, 48 insertions(+), 37 deletions(-) (limited to 'apps') diff --git a/apps/menus/playlist_menu.c b/apps/menus/playlist_menu.c index be3ad307c4..f4fa6bc653 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 a066dd2ea0..b0f7964178 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 = ¤t_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; iamount; i++) + if (!reparse) { - if (!(playlist->indices[index] & PLAYLIST_QUEUE_MASK)) + index = playlist->first_index; + for (i=0, count=0; iamount; 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 6314e9a6ee..a331838fde 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); -- cgit