diff options
author | William Wilgus <wilgus.william@gmail.com> | 2023-09-12 00:02:06 -0400 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2023-09-12 22:07:41 -0400 |
commit | d8b995c6424c942381a52f411555b51a62bedec5 (patch) | |
tree | 365bfa84e3047fe90e27478a202f07337af234a9 | |
parent | 84450dfd5d544987d1afb4b66c0dc3002566b24e (diff) | |
download | rockbox-d8b995c642.tar.gz rockbox-d8b995c642.zip |
speed up adding files from filetree WIP
open an insert context
add tracks using the opened context
release opened context and sync the playlist
Change-Id: Idea700ffcf42a38dc23e131c92a6c5d325833170
-rw-r--r-- | apps/filetree.c | 41 | ||||
-rw-r--r-- | apps/playlist.c | 286 | ||||
-rw-r--r-- | apps/playlist.h | 16 |
3 files changed, 166 insertions, 177 deletions
diff --git a/apps/filetree.c b/apps/filetree.c index 7e6ba4eb8d..3e20c89924 100644 --- a/apps/filetree.c +++ b/apps/filetree.c @@ -72,29 +72,46 @@ static int strnatcasecmp_n(const char *a, const char *b, size_t n) int ft_build_playlist(struct tree_context* c, int start_index) { int i; - int res = 0; int start=start_index; + int res; struct playlist_info *playlist = playlist_get_current(); tree_lock_cache(c); struct entry *entries = tree_get_entries(c); - for(i = 0;i < c->filesindir;i++) + struct playlist_insert_context pl_context; + + res = playlist_insert_context_create(playlist, &pl_context, + PLAYLIST_REPLACE, false, false); + if (res >= 0) { - if((entries[i].attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO) + cpu_boost(true); + for(i = 0;i < c->filesindir;i++) { - res = playlist_insert_track(playlist, entries[i].name, - PLAYLIST_INSERT_LAST, false, false); - if (res < 0) +#if 0 /*only needed if displaying progress */ + /* user abort */ + if (action_userabort(TIMEOUT_NOBLOCK)) + { break; + } +#endif + if((entries[i].attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO) + { + res = playlist_insert_context_add(&pl_context, entries[i].name); + if (res < 0) + break; + } + else + { + /* Adjust the start index when se skip non-MP3 entries */ + if(i < start) + start_index--; + } } - else - { - /* Adjust the start index when se skip non-MP3 entries */ - if(i < start) - start_index--; - } + cpu_boost(false); } + + playlist_insert_context_release(&pl_context); tree_unlock_cache(c); return start_index; diff --git a/apps/playlist.c b/apps/playlist.c index 1314656c83..69634fb96d 100644 --- a/apps/playlist.c +++ b/apps/playlist.c @@ -166,13 +166,6 @@ #define PLAYLIST_QUEUED 0x20000000 #define PLAYLIST_SKIPPED 0x10000000 -struct directory_search_context { - struct playlist_info* playlist; - int position; - bool queue; - int count; -}; - static struct playlist_info current_playlist; static void dc_init_filerefs(struct playlist_info *playlist, @@ -1435,41 +1428,7 @@ static int add_track_to_playlist_unlocked(struct playlist_info* playlist, */ static int directory_search_callback(char* filename, void* context) { - struct directory_search_context* c = - (struct directory_search_context*) context; - int insert_pos; - - insert_pos = add_track_to_playlist_unlocked(c->playlist, filename, - c->position, c->queue, -1); - - if (insert_pos < 0) - return -1; - - (c->count)++; - - /* After first INSERT_FIRST switch to INSERT so that all the - rest of the tracks get inserted one after the other */ - if (c->position == PLAYLIST_INSERT_FIRST) - c->position = PLAYLIST_INSERT; - - if (((c->count)%PLAYLIST_DISPLAY_COUNT) == 0) - { - unsigned char* count_str; - - if (c->queue) - count_str = ID2P(LANG_PLAYLIST_QUEUE_COUNT); - else - count_str = ID2P(LANG_PLAYLIST_INSERT_COUNT); - - display_playlist_count(c->count, count_str, false); - - if ((c->count) == PLAYLIST_DISPLAY_COUNT && - (audio_status() & AUDIO_STATUS_PLAY) && - c->playlist->started) - audio_flush_and_reload_tracks(); - } - - return 0; + return playlist_insert_context_add(context, filename); } /* @@ -2441,27 +2400,27 @@ int playlist_get_track_info(struct playlist_info* playlist, int index, } /* - * Insert all tracks from specified directory into playlist. + * initialize an insert context to add tracks to a playlist + * don't forget to release it when finished adding files */ -int playlist_insert_directory(struct playlist_info* playlist, - const char *dirname, int position, bool queue, - bool recurse) +int playlist_insert_context_create(struct playlist_info* playlist, + struct playlist_insert_context *context, + int position, bool queue, bool progress) { - int result; - unsigned char *count_str; - struct directory_search_context context; if (!playlist) playlist = ¤t_playlist; + context->playlist = playlist; + context->initialized = false; + dc_thread_stop(playlist); playlist_write_lock(playlist); if (check_control(playlist) < 0) { notify_control_access_error(); - result = -1; - goto out; + return -1; } if (position == PLAYLIST_REPLACE) @@ -2470,41 +2429,101 @@ int playlist_insert_directory(struct playlist_info* playlist, position = PLAYLIST_INSERT_LAST; else { - result = -1; - goto out; + return -1; } } + context->playlist = playlist; + context->position = position; + context->queue = queue; + context->count = 0; + context->progress = progress; + context->initialized = true; + if (queue) - count_str = ID2P(LANG_PLAYLIST_QUEUE_COUNT); + context->count_langid = LANG_PLAYLIST_QUEUE_COUNT; else - count_str = ID2P(LANG_PLAYLIST_INSERT_COUNT); + context->count_langid = LANG_PLAYLIST_INSERT_COUNT; - display_playlist_count(0, count_str, false); + return 0; +} - context.playlist = playlist; - context.position = position; - context.queue = queue; - context.count = 0; +/* + * add tracks to playlist using opened insert context + */ +int playlist_insert_context_add(struct playlist_insert_context *context, + const char *filename) +{ + struct playlist_insert_context* c = context; + int insert_pos; - cpu_boost(true); + insert_pos = add_track_to_playlist_unlocked(c->playlist, filename, + c->position, c->queue, -1); - result = playlist_directory_tracksearch(dirname, recurse, - directory_search_callback, &context); + if (insert_pos < 0) + return -1; - sync_control_unlocked(playlist); + (c->count)++; - cpu_boost(false); + /* After first INSERT_FIRST switch to INSERT so that all the + rest of the tracks get inserted one after the other */ + if (c->position == PLAYLIST_INSERT_FIRST) + c->position = PLAYLIST_INSERT; - display_playlist_count(context.count, count_str, true); + if (((c->count)%PLAYLIST_DISPLAY_COUNT) == 0) + { + if (c->progress) + display_playlist_count(c->count, ID2P(c->count_langid), false); + + if ((c->count) == PLAYLIST_DISPLAY_COUNT && + (audio_status() & AUDIO_STATUS_PLAY) && + c->playlist->started) + audio_flush_and_reload_tracks(); + } + + return 0; +} + +/* + * release opened insert context, sync playlist + */ +void playlist_insert_context_release(struct playlist_insert_context *context) +{ + + struct playlist_info* playlist = context->playlist; + if (context->initialized) + sync_control_unlocked(playlist); + if (context->progress) + display_playlist_count(context->count, ID2P(context->count_langid), true); -out: playlist_write_unlock(playlist); dc_thread_start(playlist, true); if ((audio_status() & AUDIO_STATUS_PLAY) && playlist->started) audio_flush_and_reload_tracks(); +} + +/* + * Insert all tracks from specified directory into playlist. + */ +int playlist_insert_directory(struct playlist_info* playlist, + const char *dirname, int position, bool queue, + bool recurse) +{ + int result = -1; + struct playlist_insert_context context; + result = playlist_insert_context_create(playlist, &context, + position, queue, true); + if (result >= 0) + { + cpu_boost(true); + + result = playlist_directory_tracksearch(dirname, recurse, + directory_search_callback, &context); + cpu_boost(false); + } + playlist_insert_context_release(&context); return result; } @@ -2514,133 +2533,70 @@ out: int playlist_insert_playlist(struct playlist_info* playlist, const char *filename, int position, bool queue) { - int fd; + int fd = -1; int max; char *dir; - unsigned char *count_str; + char temp_buf[MAX_PATH+1]; char trackname[MAX_PATH+1]; - int count = 0; + int result = -1; bool utf8 = is_m3u8_name(filename); - if (!playlist) - playlist = ¤t_playlist; - - dc_thread_stop(playlist); - playlist_write_lock(playlist); - + struct playlist_insert_context pl_context; cpu_boost(true); - if (check_control(playlist) < 0) + if (playlist_insert_context_create(playlist, &pl_context, position, queue, true) >= 0) { - notify_control_access_error(); - goto out; - } - - fd = open_utf8(filename, O_RDONLY); - if (fd < 0) - { - notify_access_error(); - goto out; - } - - /* we need the directory name for formatting purposes */ - size_t dirlen = path_dirname(filename, (const char **)&dir); - dir = strmemdupa(dir, dirlen); - - if (queue) - count_str = ID2P(LANG_PLAYLIST_QUEUE_COUNT); - else - count_str = ID2P(LANG_PLAYLIST_INSERT_COUNT); - - display_playlist_count(count, count_str, false); - - if (position == PLAYLIST_REPLACE) - { - if (remove_all_tracks_unlocked(playlist, true) == 0) - position = PLAYLIST_INSERT_LAST; - else + fd = open_utf8(filename, O_RDONLY); + if (fd < 0) { - close(fd); + notify_access_error(); goto out; } - } - while ((max = read_line(fd, temp_buf, sizeof(temp_buf))) > 0) - { - /* user abort */ - if (action_userabort(TIMEOUT_NOBLOCK)) - break; + /* we need the directory name for formatting purposes */ + size_t dirlen = path_dirname(filename, (const char **)&dir); + dir = strmemdupa(dir, dirlen); - if (temp_buf[0] != '#' && temp_buf[0] != '\0') + while ((max = read_line(fd, temp_buf, sizeof(temp_buf))) > 0) { - int insert_pos; - - if (!utf8) - { - /* Use trackname as a temporay buffer. Note that trackname must - * be as large as temp_buf. - */ - max = convert_m3u_name(temp_buf, max, sizeof(temp_buf), trackname); - } - - /* we need to format so that relative paths are correctly - handled */ - if (format_track_path(trackname, temp_buf, sizeof(trackname), dir) < 0) - { - goto out; - } - - insert_pos = add_track_to_playlist_unlocked(playlist, trackname, - position, queue, -1); - - if (insert_pos < 0) - { - goto out; - } - - /* After first INSERT_FIRST switch to INSERT so that all the - rest of the tracks get inserted one after the other */ - if (position == PLAYLIST_INSERT_FIRST) - position = PLAYLIST_INSERT; - - count++; + /* user abort */ + if (action_userabort(TIMEOUT_NOBLOCK)) + break; - if ((count%PLAYLIST_DISPLAY_COUNT) == 0) + if (temp_buf[0] != '#' && temp_buf[0] != '\0') { - display_playlist_count(count, count_str, false); + if (!utf8) + { + /* Use trackname as a temporay buffer. Note that trackname must + * be as large as temp_buf. + */ + max = convert_m3u_name(temp_buf, max, sizeof(temp_buf), trackname); + } - if (count == PLAYLIST_DISPLAY_COUNT && - (audio_status() & AUDIO_STATUS_PLAY) && - playlist->started) + /* we need to format so that relative paths are correctly + handled */ + if (format_track_path(trackname, temp_buf, sizeof(trackname), dir) < 0) { - audio_flush_and_reload_tracks(); + goto out; } + + if (playlist_insert_context_add(&pl_context, trackname) < 0) + goto out; } - } - /* let the other threads work */ - yield(); + /* let the other threads work */ + yield(); + } } - close(fd); - - sync_control_unlocked(playlist); - - display_playlist_count(count, count_str, true); - - if ((audio_status() & AUDIO_STATUS_PLAY) && playlist->started) - audio_flush_and_reload_tracks(); - result = 0; out: + close(fd); cpu_boost(false); - - playlist_write_unlock(playlist); - dc_thread_start(playlist, true); - + playlist_insert_context_release(&pl_context); return result; } diff --git a/apps/playlist.h b/apps/playlist.h index a12180f286..6d86270bc4 100644 --- a/apps/playlist.h +++ b/apps/playlist.h @@ -98,6 +98,16 @@ struct playlist_track_info int display_index; /* index of track for display */ }; +struct playlist_insert_context { + struct playlist_info* playlist; + int position; + bool queue; + bool progress; + bool initialized; + int count; + int32_t count_langid; +}; + /* Exported functions only for current playlist. */ void playlist_init(void) INIT_ATTR; void playlist_shutdown(void); @@ -132,6 +142,12 @@ void playlist_close(struct playlist_info* playlist); void playlist_sync(struct playlist_info* playlist); int playlist_insert_track(struct playlist_info* playlist, const char *filename, int position, bool queue, bool sync); +int playlist_insert_context_create(struct playlist_info* playlist, + struct playlist_insert_context *context, + int position, bool queue, bool progress); +int playlist_insert_context_add(struct playlist_insert_context *context, + const char *filename); +void playlist_insert_context_release(struct playlist_insert_context *context); int playlist_insert_directory(struct playlist_info* playlist, const char *dirname, int position, bool queue, bool recurse); |