1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
William Wilgus 2023-09-12 00:02:06 -04:00 committed by William Wilgus
parent 84450dfd5d
commit d8b995c642
3 changed files with 167 additions and 178 deletions

View file

@ -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 ft_build_playlist(struct tree_context* c, int start_index)
{ {
int i; int i;
int res = 0;
int start=start_index; int start=start_index;
int res;
struct playlist_info *playlist = playlist_get_current(); struct playlist_info *playlist = playlist_get_current();
tree_lock_cache(c); tree_lock_cache(c);
struct entry *entries = tree_get_entries(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, #if 0 /*only needed if displaying progress */
PLAYLIST_INSERT_LAST, false, false); /* user abort */
if (res < 0) if (action_userabort(TIMEOUT_NOBLOCK))
{
break; 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 cpu_boost(false);
{
/* Adjust the start index when se skip non-MP3 entries */
if(i < start)
start_index--;
}
} }
playlist_insert_context_release(&pl_context);
tree_unlock_cache(c); tree_unlock_cache(c);
return start_index; return start_index;

View file

@ -166,13 +166,6 @@
#define PLAYLIST_QUEUED 0x20000000 #define PLAYLIST_QUEUED 0x20000000
#define PLAYLIST_SKIPPED 0x10000000 #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 struct playlist_info current_playlist;
static void dc_init_filerefs(struct playlist_info *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) static int directory_search_callback(char* filename, void* context)
{ {
struct directory_search_context* c = return playlist_insert_context_add(context, filename);
(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;
} }
/* /*
@ -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, int playlist_insert_context_create(struct playlist_info* playlist,
const char *dirname, int position, bool queue, struct playlist_insert_context *context,
bool recurse) int position, bool queue, bool progress)
{ {
int result;
unsigned char *count_str;
struct directory_search_context context;
if (!playlist) if (!playlist)
playlist = &current_playlist; playlist = &current_playlist;
context->playlist = playlist;
context->initialized = false;
dc_thread_stop(playlist); dc_thread_stop(playlist);
playlist_write_lock(playlist); playlist_write_lock(playlist);
if (check_control(playlist) < 0) if (check_control(playlist) < 0)
{ {
notify_control_access_error(); notify_control_access_error();
result = -1; return -1;
goto out;
} }
if (position == PLAYLIST_REPLACE) if (position == PLAYLIST_REPLACE)
@ -2470,41 +2429,101 @@ int playlist_insert_directory(struct playlist_info* playlist,
position = PLAYLIST_INSERT_LAST; position = PLAYLIST_INSERT_LAST;
else else
{ {
result = -1; return -1;
goto out;
} }
} }
context->playlist = playlist;
context->position = position;
context->queue = queue;
context->count = 0;
context->progress = progress;
context->initialized = true;
if (queue) if (queue)
count_str = ID2P(LANG_PLAYLIST_QUEUE_COUNT); context->count_langid = LANG_PLAYLIST_QUEUE_COUNT;
else 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; * add tracks to playlist using opened insert context
context.queue = queue; */
context.count = 0; 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, if (insert_pos < 0)
directory_search_callback, &context); 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); playlist_write_unlock(playlist);
dc_thread_start(playlist, true); dc_thread_start(playlist, true);
if ((audio_status() & AUDIO_STATUS_PLAY) && playlist->started) if ((audio_status() & AUDIO_STATUS_PLAY) && playlist->started)
audio_flush_and_reload_tracks(); 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; return result;
} }
@ -2514,133 +2533,70 @@ out:
int playlist_insert_playlist(struct playlist_info* playlist, const char *filename, int playlist_insert_playlist(struct playlist_info* playlist, const char *filename,
int position, bool queue) int position, bool queue)
{ {
int fd; int fd = -1;
int max; int max;
char *dir; char *dir;
unsigned char *count_str;
char temp_buf[MAX_PATH+1]; char temp_buf[MAX_PATH+1];
char trackname[MAX_PATH+1]; char trackname[MAX_PATH+1];
int count = 0;
int result = -1; int result = -1;
bool utf8 = is_m3u8_name(filename); bool utf8 = is_m3u8_name(filename);
if (!playlist) struct playlist_insert_context pl_context;
playlist = &current_playlist;
dc_thread_stop(playlist);
playlist_write_lock(playlist);
cpu_boost(true); cpu_boost(true);
if (check_control(playlist) < 0) if (playlist_insert_context_create(playlist, &pl_context, position, queue, true) >= 0)
{ {
notify_control_access_error(); fd = open_utf8(filename, O_RDONLY);
goto out; if (fd < 0)
}
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
{ {
close(fd); notify_access_error();
goto out; goto out;
} }
}
while ((max = read_line(fd, temp_buf, sizeof(temp_buf))) > 0) /* we need the directory name for formatting purposes */
{ size_t dirlen = path_dirname(filename, (const char **)&dir);
/* user abort */ dir = strmemdupa(dir, dirlen);
if (action_userabort(TIMEOUT_NOBLOCK))
break;
if (temp_buf[0] != '#' && temp_buf[0] != '\0') while ((max = read_line(fd, temp_buf, sizeof(temp_buf))) > 0)
{ {
int insert_pos; /* user abort */
if (action_userabort(TIMEOUT_NOBLOCK))
break;
if (!utf8) if (temp_buf[0] != '#' && temp_buf[0] != '\0')
{ {
/* Use trackname as a temporay buffer. Note that trackname must if (!utf8)
* 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++;
if ((count%PLAYLIST_DISPLAY_COUNT) == 0)
{
display_playlist_count(count, count_str, false);
if (count == PLAYLIST_DISPLAY_COUNT &&
(audio_status() & AUDIO_STATUS_PLAY) &&
playlist->started)
{ {
audio_flush_and_reload_tracks(); /* 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;
}
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; result = 0;
out: out:
close(fd);
cpu_boost(false); cpu_boost(false);
playlist_insert_context_release(&pl_context);
playlist_write_unlock(playlist);
dc_thread_start(playlist, true);
return result; return result;
} }

View file

@ -98,6 +98,16 @@ struct playlist_track_info
int display_index; /* index of track for display */ 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. */ /* Exported functions only for current playlist. */
void playlist_init(void) INIT_ATTR; void playlist_init(void) INIT_ATTR;
void playlist_shutdown(void); void playlist_shutdown(void);
@ -132,6 +142,12 @@ void playlist_close(struct playlist_info* playlist);
void playlist_sync(struct playlist_info* playlist); void playlist_sync(struct playlist_info* playlist);
int playlist_insert_track(struct playlist_info* playlist, const char *filename, int playlist_insert_track(struct playlist_info* playlist, const char *filename,
int position, bool queue, bool sync); 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, int playlist_insert_directory(struct playlist_info* playlist,
const char *dirname, int position, bool queue, const char *dirname, int position, bool queue,
bool recurse); bool recurse);