diff options
author | Thomas Martitz <kugel@rockbox.org> | 2014-04-08 22:52:37 +0200 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2014-04-15 23:54:28 +0200 |
commit | bebf71a08bb8e8f6022852ce6545cf0de580229d (patch) | |
tree | 8a5d4999da166d2c6420e5fa789349a01a7afa35 | |
parent | 466441dc14f2463dbd48aa6ab268317269100e4a (diff) | |
download | rockbox-bebf71a08bb8e8f6022852ce6545cf0de580229d.tar.gz rockbox-bebf71a08bb8e8f6022852ce6545cf0de580229d.zip |
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
-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); |