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 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)
61 61
62 if (!kbd_input(temp, sizeof(temp))) 62 if (!kbd_input(temp, sizeof(temp)))
63 { 63 {
64 playlist_save(playlist, temp); 64 playlist_save(playlist, temp, NULL, 0);
65 65
66 /* reload in case playlist was saved to cwd */ 66 /* reload in case playlist was saved to cwd */
67 reload_directory(); 67 reload_directory();
@@ -113,4 +113,3 @@ MAKE_MENU(playlist_options, ID2P(LANG_PLAYLISTS), NULL,
113 Icon_Playlist, 113 Icon_Playlist,
114 &create_playlist_item, &view_cur_playlist, 114 &create_playlist_item, &view_cur_playlist,
115 &save_playlist, &clear_catalog_directory_item); 115 &save_playlist, &clear_catalog_directory_item);
116
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 @@
105#include "root_menu.h" 105#include "root_menu.h"
106#include "plugin.h" /* To borrow a temp buffer to rewrite a .m3u8 file */ 106#include "plugin.h" /* To borrow a temp buffer to rewrite a .m3u8 file */
107#include "panic.h" 107#include "panic.h"
108#include "logdiskf.h"
108 109
109#define PLAYLIST_CONTROL_FILE_VERSION 2 110#define PLAYLIST_CONTROL_FILE_VERSION 2
110 111
@@ -523,6 +524,9 @@ static int add_indices_to_playlist(struct playlist_info* playlist,
523 bool store_index; 524 bool store_index;
524 unsigned char *p; 525 unsigned char *p;
525 int result = 0; 526 int result = 0;
527 /* get emergency buffer so we don't fail horribly */
528 if (!buflen)
529 buffer = __builtin_alloca((buflen = 64));
526 530
527 if(-1 == playlist->fd) 531 if(-1 == playlist->fd)
528 playlist->fd = open_utf8(playlist->filename, O_RDONLY); 532 playlist->fd = open_utf8(playlist->filename, O_RDONLY);
@@ -1983,8 +1987,6 @@ static int move_callback(int handle, void* current, void* new)
1983 playlist->indices = new; 1987 playlist->indices = new;
1984 else if (current == playlist->filenames) 1988 else if (current == playlist->filenames)
1985 playlist->filenames = new; 1989 playlist->filenames = new;
1986 /* buffer can possibly point to a new buffer temporarily (playlist_save()).
1987 * just don't overwrite the pointer to that temp buffer */
1988 else if (current == playlist->buffer) 1990 else if (current == playlist->buffer)
1989 playlist->buffer = new; 1991 playlist->buffer = new;
1990 1992
@@ -3528,8 +3530,11 @@ int playlist_get_track_info(struct playlist_info* playlist, int index,
3528 return 0; 3530 return 0;
3529} 3531}
3530 3532
3531/* save the current dynamic playlist to specified file */ 3533/* save the current dynamic playlist to specified file. The
3532int playlist_save(struct playlist_info* playlist, char *filename) 3534 * temp_buffer (if not NULL) is used as a scratchpad when loading indices
3535 * (slow if not used). */
3536int playlist_save(struct playlist_info* playlist, char *filename,
3537 void* temp_buffer, size_t temp_buffer_size)
3533{ 3538{
3534 int fd; 3539 int fd;
3535 int i, index; 3540 int i, index;
@@ -3538,6 +3543,17 @@ int playlist_save(struct playlist_info* playlist, char *filename)
3538 char tmp_buf[MAX_PATH+1]; 3543 char tmp_buf[MAX_PATH+1];
3539 int result = 0; 3544 int result = 0;
3540 bool overwrite_current = false; 3545 bool overwrite_current = false;
3546 int *seek_buf;
3547 bool reparse;
3548
3549 ALIGN_BUFFER(temp_buffer, temp_buffer_size, sizeof(int));
3550 seek_buf = temp_buffer;
3551
3552 /* without temp_buffer, or when it's depleted, and we overwrite the current
3553 * playlist then the newly saved playlist has to be reparsed. With
3554 * sufficient temp_buffer the indicies be remembered and added without
3555 * reparsing */
3556 reparse = temp_buffer_size == 0;
3541 3557
3542 if (!playlist) 3558 if (!playlist)
3543 playlist = &current_playlist; 3559 playlist = &current_playlist;
@@ -3556,23 +3572,9 @@ int playlist_save(struct playlist_info* playlist, char *filename)
3556 3572
3557 if (!strncmp(playlist->filename, path, strlen(path))) 3573 if (!strncmp(playlist->filename, path, strlen(path)))
3558 { 3574 {
3559 /* Attempting to overwrite current playlist file.*/ 3575 /* Attempting to overwrite current playlist file.
3560 3576 * use temporary pathname and overwrite later */
3561 if (playlist->buffer_size < (int)(playlist->amount * sizeof(int))) 3577 strlcat(path, "_temp", sizeof(path));
3562 {
3563 /* not enough buffer space to store updated indices */
3564 /* Try to get a buffer */
3565 playlist->buffer = plugin_get_buffer((size_t*)&playlist->buffer_size);
3566 if (playlist->buffer_size < (int)(playlist->amount * sizeof(int)))
3567 {
3568 splash(HZ*2, ID2P(LANG_PLAYLIST_ACCESS_ERROR));
3569 result = -1;
3570 goto reset_old_buffer;
3571 }
3572 }
3573
3574 /* use temporary pathname */
3575 snprintf(path, sizeof(path), "%s_temp", playlist->filename);
3576 overwrite_current = true; 3578 overwrite_current = true;
3577 } 3579 }
3578 3580
@@ -3624,8 +3626,8 @@ int playlist_save(struct playlist_info* playlist, char *filename)
3624 break; 3626 break;
3625 } 3627 }
3626 3628
3627 if (overwrite_current) 3629 if (overwrite_current && !reparse)
3628 playlist->seek_buf[count] = lseek(fd, 0, SEEK_CUR); 3630 seek_buf[count] = lseek(fd, 0, SEEK_CUR);
3629 3631
3630 if (fdprintf(fd, "%s\n", tmp_buf) < 0) 3632 if (fdprintf(fd, "%s\n", tmp_buf) < 0)
3631 { 3633 {
@@ -3635,6 +3637,10 @@ int playlist_save(struct playlist_info* playlist, char *filename)
3635 } 3637 }
3636 3638
3637 count++; 3639 count++;
3640 /* when our temp buffer is depleted we have to fall
3641 * back to reparsing the playlist (slow) */
3642 if (count*sizeof(int) >= temp_buffer_size)
3643 reparse = true;
3638 3644
3639 if ((count % PLAYLIST_DISPLAY_COUNT) == 0) 3645 if ((count % PLAYLIST_DISPLAY_COUNT) == 0)
3640 display_playlist_count(count, ID2P(LANG_PLAYLIST_SAVE_COUNT), 3646 display_playlist_count(count, ID2P(LANG_PLAYLIST_SAVE_COUNT),
@@ -3666,17 +3672,25 @@ int playlist_save(struct playlist_info* playlist, char *filename)
3666 playlist->fd = open_utf8(playlist->filename, O_RDONLY); 3672 playlist->fd = open_utf8(playlist->filename, O_RDONLY);
3667 if (playlist->fd >= 0) 3673 if (playlist->fd >= 0)
3668 { 3674 {
3669 index = playlist->first_index; 3675 if (!reparse)
3670 for (i=0, count=0; i<playlist->amount; i++)
3671 { 3676 {
3672 if (!(playlist->indices[index] & PLAYLIST_QUEUE_MASK)) 3677 index = playlist->first_index;
3678 for (i=0, count=0; i<playlist->amount; i++)
3673 { 3679 {
3674 playlist->indices[index] = playlist->seek_buf[count]; 3680 if (!(playlist->indices[index] & PLAYLIST_QUEUE_MASK))
3675 count++; 3681 {
3682 playlist->indices[index] = seek_buf[count];
3683 count++;
3684 }
3685 index = (index+1)%playlist->amount;
3676 } 3686 }
3677 index = (index+1)%playlist->amount;
3678 } 3687 }
3679 3688 else
3689 {
3690 NOTEF("reparsing current playlist (slow)");
3691 playlist->amount = 0;
3692 add_indices_to_playlist(playlist, temp_buffer, temp_buffer_size);
3693 }
3680 /* we need to recreate control because inserted tracks are 3694 /* we need to recreate control because inserted tracks are
3681 now part of the playlist and shuffle has been 3695 now part of the playlist and shuffle has been
3682 invalidated */ 3696 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
88 bool in_ram; /* playlist stored in ram (dirplay) */ 88 bool in_ram; /* playlist stored in ram (dirplay) */
89 int buffer_handle; /* handle to the below buffer (-1 if non-buflib) */ 89 int buffer_handle; /* handle to the below buffer (-1 if non-buflib) */
90 90
91 union { 91 volatile char *buffer;/* buffer for in-ram playlists */
92 volatile char *buffer;/* buffer for in-ram playlists */
93 int *seek_buf; /* buffer for seeks in real playlists */
94 };
95 int buffer_size; /* size of buffer */ 92 int buffer_size; /* size of buffer */
96 int buffer_end_pos; /* last position where buffer was written */ 93 int buffer_end_pos; /* last position where buffer was written */
97 int index; /* index of current playing track */ 94 int index; /* index of current playing track */
@@ -184,7 +181,8 @@ char *playlist_get_name(const struct playlist_info* playlist, char *buf,
184 int buf_size); 181 int buf_size);
185int playlist_get_track_info(struct playlist_info* playlist, int index, 182int playlist_get_track_info(struct playlist_info* playlist, int index,
186 struct playlist_track_info* info); 183 struct playlist_track_info* info);
187int playlist_save(struct playlist_info* playlist, char *filename); 184int playlist_save(struct playlist_info* playlist, char *filename,
185 void* temp_buffer, size_t temp_buffer_size);
188int playlist_directory_tracksearch(const char* dirname, bool recurse, 186int playlist_directory_tracksearch(const char* dirname, bool recurse,
189 int (*callback)(char*, void*), 187 int (*callback)(char*, void*),
190 void* context); 188 void* context);