diff options
-rw-r--r-- | apps/menus/playlist_menu.c | 3 | ||||
-rwxr-xr-x | apps/playlist.c | 74 | ||||
-rw-r--r-- | apps/playlist.h | 8 |
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 |
3532 | int 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). */ | ||
3536 | int 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 = ¤t_playlist; | 3559 | playlist = ¤t_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); |
185 | int playlist_get_track_info(struct playlist_info* playlist, int index, | 182 | int playlist_get_track_info(struct playlist_info* playlist, int index, |
186 | struct playlist_track_info* info); | 183 | struct playlist_track_info* info); |
187 | int playlist_save(struct playlist_info* playlist, char *filename); | 184 | int playlist_save(struct playlist_info* playlist, char *filename, |
185 | void* temp_buffer, size_t temp_buffer_size); | ||
188 | int playlist_directory_tracksearch(const char* dirname, bool recurse, | 186 | int playlist_directory_tracksearch(const char* dirname, bool recurse, |
189 | int (*callback)(char*, void*), | 187 | int (*callback)(char*, void*), |
190 | void* context); | 188 | void* context); |