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-d8b995c6424c942381a52f411555b51a62bedec5.tar.gz rockbox-d8b995c6424c942381a52f411555b51a62bedec5.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) | |||
72 | int ft_build_playlist(struct tree_context* c, int start_index) | 72 | int ft_build_playlist(struct tree_context* c, int start_index) |
73 | { | 73 | { |
74 | int i; | 74 | int i; |
75 | int res = 0; | ||
76 | int start=start_index; | 75 | int start=start_index; |
76 | int res; | ||
77 | struct playlist_info *playlist = playlist_get_current(); | 77 | struct playlist_info *playlist = playlist_get_current(); |
78 | 78 | ||
79 | tree_lock_cache(c); | 79 | tree_lock_cache(c); |
80 | struct entry *entries = tree_get_entries(c); | 80 | struct entry *entries = tree_get_entries(c); |
81 | 81 | ||
82 | for(i = 0;i < c->filesindir;i++) | 82 | struct playlist_insert_context pl_context; |
83 | |||
84 | res = playlist_insert_context_create(playlist, &pl_context, | ||
85 | PLAYLIST_REPLACE, false, false); | ||
86 | if (res >= 0) | ||
83 | { | 87 | { |
84 | if((entries[i].attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO) | 88 | cpu_boost(true); |
89 | for(i = 0;i < c->filesindir;i++) | ||
85 | { | 90 | { |
86 | res = playlist_insert_track(playlist, entries[i].name, | 91 | #if 0 /*only needed if displaying progress */ |
87 | PLAYLIST_INSERT_LAST, false, false); | 92 | /* user abort */ |
88 | if (res < 0) | 93 | if (action_userabort(TIMEOUT_NOBLOCK)) |
94 | { | ||
89 | break; | 95 | break; |
96 | } | ||
97 | #endif | ||
98 | if((entries[i].attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO) | ||
99 | { | ||
100 | res = playlist_insert_context_add(&pl_context, entries[i].name); | ||
101 | if (res < 0) | ||
102 | break; | ||
103 | } | ||
104 | else | ||
105 | { | ||
106 | /* Adjust the start index when se skip non-MP3 entries */ | ||
107 | if(i < start) | ||
108 | start_index--; | ||
109 | } | ||
90 | } | 110 | } |
91 | else | 111 | cpu_boost(false); |
92 | { | ||
93 | /* Adjust the start index when se skip non-MP3 entries */ | ||
94 | if(i < start) | ||
95 | start_index--; | ||
96 | } | ||
97 | } | 112 | } |
113 | |||
114 | playlist_insert_context_release(&pl_context); | ||
98 | 115 | ||
99 | tree_unlock_cache(c); | 116 | tree_unlock_cache(c); |
100 | return start_index; | 117 | 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 @@ | |||
166 | #define PLAYLIST_QUEUED 0x20000000 | 166 | #define PLAYLIST_QUEUED 0x20000000 |
167 | #define PLAYLIST_SKIPPED 0x10000000 | 167 | #define PLAYLIST_SKIPPED 0x10000000 |
168 | 168 | ||
169 | struct directory_search_context { | ||
170 | struct playlist_info* playlist; | ||
171 | int position; | ||
172 | bool queue; | ||
173 | int count; | ||
174 | }; | ||
175 | |||
176 | static struct playlist_info current_playlist; | 169 | static struct playlist_info current_playlist; |
177 | 170 | ||
178 | static void dc_init_filerefs(struct playlist_info *playlist, | 171 | static void dc_init_filerefs(struct playlist_info *playlist, |
@@ -1435,41 +1428,7 @@ static int add_track_to_playlist_unlocked(struct playlist_info* playlist, | |||
1435 | */ | 1428 | */ |
1436 | static int directory_search_callback(char* filename, void* context) | 1429 | static int directory_search_callback(char* filename, void* context) |
1437 | { | 1430 | { |
1438 | struct directory_search_context* c = | 1431 | return playlist_insert_context_add(context, filename); |
1439 | (struct directory_search_context*) context; | ||
1440 | int insert_pos; | ||
1441 | |||
1442 | insert_pos = add_track_to_playlist_unlocked(c->playlist, filename, | ||
1443 | c->position, c->queue, -1); | ||
1444 | |||
1445 | if (insert_pos < 0) | ||
1446 | return -1; | ||
1447 | |||
1448 | (c->count)++; | ||
1449 | |||
1450 | /* After first INSERT_FIRST switch to INSERT so that all the | ||
1451 | rest of the tracks get inserted one after the other */ | ||
1452 | if (c->position == PLAYLIST_INSERT_FIRST) | ||
1453 | c->position = PLAYLIST_INSERT; | ||
1454 | |||
1455 | if (((c->count)%PLAYLIST_DISPLAY_COUNT) == 0) | ||
1456 | { | ||
1457 | unsigned char* count_str; | ||
1458 | |||
1459 | if (c->queue) | ||
1460 | count_str = ID2P(LANG_PLAYLIST_QUEUE_COUNT); | ||
1461 | else | ||
1462 | count_str = ID2P(LANG_PLAYLIST_INSERT_COUNT); | ||
1463 | |||
1464 | display_playlist_count(c->count, count_str, false); | ||
1465 | |||
1466 | if ((c->count) == PLAYLIST_DISPLAY_COUNT && | ||
1467 | (audio_status() & AUDIO_STATUS_PLAY) && | ||
1468 | c->playlist->started) | ||
1469 | audio_flush_and_reload_tracks(); | ||
1470 | } | ||
1471 | |||
1472 | return 0; | ||
1473 | } | 1432 | } |
1474 | 1433 | ||
1475 | /* | 1434 | /* |
@@ -2441,27 +2400,27 @@ int playlist_get_track_info(struct playlist_info* playlist, int index, | |||
2441 | } | 2400 | } |
2442 | 2401 | ||
2443 | /* | 2402 | /* |
2444 | * Insert all tracks from specified directory into playlist. | 2403 | * initialize an insert context to add tracks to a playlist |
2404 | * don't forget to release it when finished adding files | ||
2445 | */ | 2405 | */ |
2446 | int playlist_insert_directory(struct playlist_info* playlist, | 2406 | int playlist_insert_context_create(struct playlist_info* playlist, |
2447 | const char *dirname, int position, bool queue, | 2407 | struct playlist_insert_context *context, |
2448 | bool recurse) | 2408 | int position, bool queue, bool progress) |
2449 | { | 2409 | { |
2450 | int result; | ||
2451 | unsigned char *count_str; | ||
2452 | struct directory_search_context context; | ||
2453 | 2410 | ||
2454 | if (!playlist) | 2411 | if (!playlist) |
2455 | playlist = ¤t_playlist; | 2412 | playlist = ¤t_playlist; |
2456 | 2413 | ||
2414 | context->playlist = playlist; | ||
2415 | context->initialized = false; | ||
2416 | |||
2457 | dc_thread_stop(playlist); | 2417 | dc_thread_stop(playlist); |
2458 | playlist_write_lock(playlist); | 2418 | playlist_write_lock(playlist); |
2459 | 2419 | ||
2460 | if (check_control(playlist) < 0) | 2420 | if (check_control(playlist) < 0) |
2461 | { | 2421 | { |
2462 | notify_control_access_error(); | 2422 | notify_control_access_error(); |
2463 | result = -1; | 2423 | return -1; |
2464 | goto out; | ||
2465 | } | 2424 | } |
2466 | 2425 | ||
2467 | if (position == PLAYLIST_REPLACE) | 2426 | if (position == PLAYLIST_REPLACE) |
@@ -2470,41 +2429,101 @@ int playlist_insert_directory(struct playlist_info* playlist, | |||
2470 | position = PLAYLIST_INSERT_LAST; | 2429 | position = PLAYLIST_INSERT_LAST; |
2471 | else | 2430 | else |
2472 | { | 2431 | { |
2473 | result = -1; | 2432 | return -1; |
2474 | goto out; | ||
2475 | } | 2433 | } |
2476 | } | 2434 | } |
2477 | 2435 | ||
2436 | context->playlist = playlist; | ||
2437 | context->position = position; | ||
2438 | context->queue = queue; | ||
2439 | context->count = 0; | ||
2440 | context->progress = progress; | ||
2441 | context->initialized = true; | ||
2442 | |||
2478 | if (queue) | 2443 | if (queue) |
2479 | count_str = ID2P(LANG_PLAYLIST_QUEUE_COUNT); | 2444 | context->count_langid = LANG_PLAYLIST_QUEUE_COUNT; |
2480 | else | 2445 | else |
2481 | count_str = ID2P(LANG_PLAYLIST_INSERT_COUNT); | 2446 | context->count_langid = LANG_PLAYLIST_INSERT_COUNT; |
2482 | 2447 | ||
2483 | display_playlist_count(0, count_str, false); | 2448 | return 0; |
2449 | } | ||
2484 | 2450 | ||
2485 | context.playlist = playlist; | 2451 | /* |
2486 | context.position = position; | 2452 | * add tracks to playlist using opened insert context |
2487 | context.queue = queue; | 2453 | */ |
2488 | context.count = 0; | 2454 | int playlist_insert_context_add(struct playlist_insert_context *context, |
2455 | const char *filename) | ||
2456 | { | ||
2457 | struct playlist_insert_context* c = context; | ||
2458 | int insert_pos; | ||
2489 | 2459 | ||
2490 | cpu_boost(true); | 2460 | insert_pos = add_track_to_playlist_unlocked(c->playlist, filename, |
2461 | c->position, c->queue, -1); | ||
2491 | 2462 | ||
2492 | result = playlist_directory_tracksearch(dirname, recurse, | 2463 | if (insert_pos < 0) |
2493 | directory_search_callback, &context); | 2464 | return -1; |
2494 | 2465 | ||
2495 | sync_control_unlocked(playlist); | 2466 | (c->count)++; |
2496 | 2467 | ||
2497 | cpu_boost(false); | 2468 | /* After first INSERT_FIRST switch to INSERT so that all the |
2469 | rest of the tracks get inserted one after the other */ | ||
2470 | if (c->position == PLAYLIST_INSERT_FIRST) | ||
2471 | c->position = PLAYLIST_INSERT; | ||
2498 | 2472 | ||
2499 | display_playlist_count(context.count, count_str, true); | 2473 | if (((c->count)%PLAYLIST_DISPLAY_COUNT) == 0) |
2474 | { | ||
2475 | if (c->progress) | ||
2476 | display_playlist_count(c->count, ID2P(c->count_langid), false); | ||
2477 | |||
2478 | if ((c->count) == PLAYLIST_DISPLAY_COUNT && | ||
2479 | (audio_status() & AUDIO_STATUS_PLAY) && | ||
2480 | c->playlist->started) | ||
2481 | audio_flush_and_reload_tracks(); | ||
2482 | } | ||
2483 | |||
2484 | return 0; | ||
2485 | } | ||
2486 | |||
2487 | /* | ||
2488 | * release opened insert context, sync playlist | ||
2489 | */ | ||
2490 | void playlist_insert_context_release(struct playlist_insert_context *context) | ||
2491 | { | ||
2492 | |||
2493 | struct playlist_info* playlist = context->playlist; | ||
2494 | if (context->initialized) | ||
2495 | sync_control_unlocked(playlist); | ||
2496 | if (context->progress) | ||
2497 | display_playlist_count(context->count, ID2P(context->count_langid), true); | ||
2500 | 2498 | ||
2501 | out: | ||
2502 | playlist_write_unlock(playlist); | 2499 | playlist_write_unlock(playlist); |
2503 | dc_thread_start(playlist, true); | 2500 | dc_thread_start(playlist, true); |
2504 | 2501 | ||
2505 | if ((audio_status() & AUDIO_STATUS_PLAY) && playlist->started) | 2502 | if ((audio_status() & AUDIO_STATUS_PLAY) && playlist->started) |
2506 | audio_flush_and_reload_tracks(); | 2503 | audio_flush_and_reload_tracks(); |
2504 | } | ||
2505 | |||
2506 | /* | ||
2507 | * Insert all tracks from specified directory into playlist. | ||
2508 | */ | ||
2509 | int playlist_insert_directory(struct playlist_info* playlist, | ||
2510 | const char *dirname, int position, bool queue, | ||
2511 | bool recurse) | ||
2512 | { | ||
2513 | int result = -1; | ||
2514 | struct playlist_insert_context context; | ||
2515 | result = playlist_insert_context_create(playlist, &context, | ||
2516 | position, queue, true); | ||
2517 | if (result >= 0) | ||
2518 | { | ||
2519 | cpu_boost(true); | ||
2520 | |||
2521 | result = playlist_directory_tracksearch(dirname, recurse, | ||
2522 | directory_search_callback, &context); | ||
2507 | 2523 | ||
2524 | cpu_boost(false); | ||
2525 | } | ||
2526 | playlist_insert_context_release(&context); | ||
2508 | return result; | 2527 | return result; |
2509 | } | 2528 | } |
2510 | 2529 | ||
@@ -2514,133 +2533,70 @@ out: | |||
2514 | int playlist_insert_playlist(struct playlist_info* playlist, const char *filename, | 2533 | int playlist_insert_playlist(struct playlist_info* playlist, const char *filename, |
2515 | int position, bool queue) | 2534 | int position, bool queue) |
2516 | { | 2535 | { |
2517 | int fd; | 2536 | int fd = -1; |
2518 | int max; | 2537 | int max; |
2519 | char *dir; | 2538 | char *dir; |
2520 | unsigned char *count_str; | 2539 | |
2521 | char temp_buf[MAX_PATH+1]; | 2540 | char temp_buf[MAX_PATH+1]; |
2522 | char trackname[MAX_PATH+1]; | 2541 | char trackname[MAX_PATH+1]; |
2523 | int count = 0; | 2542 | |
2524 | int result = -1; | 2543 | int result = -1; |
2525 | bool utf8 = is_m3u8_name(filename); | 2544 | bool utf8 = is_m3u8_name(filename); |
2526 | 2545 | ||
2527 | if (!playlist) | 2546 | struct playlist_insert_context pl_context; |
2528 | playlist = ¤t_playlist; | ||
2529 | |||
2530 | dc_thread_stop(playlist); | ||
2531 | playlist_write_lock(playlist); | ||
2532 | |||
2533 | cpu_boost(true); | 2547 | cpu_boost(true); |
2534 | 2548 | ||
2535 | if (check_control(playlist) < 0) | 2549 | if (playlist_insert_context_create(playlist, &pl_context, position, queue, true) >= 0) |
2536 | { | 2550 | { |
2537 | notify_control_access_error(); | 2551 | fd = open_utf8(filename, O_RDONLY); |
2538 | goto out; | 2552 | if (fd < 0) |
2539 | } | ||
2540 | |||
2541 | fd = open_utf8(filename, O_RDONLY); | ||
2542 | if (fd < 0) | ||
2543 | { | ||
2544 | notify_access_error(); | ||
2545 | goto out; | ||
2546 | } | ||
2547 | |||
2548 | /* we need the directory name for formatting purposes */ | ||
2549 | size_t dirlen = path_dirname(filename, (const char **)&dir); | ||
2550 | dir = strmemdupa(dir, dirlen); | ||
2551 | |||
2552 | if (queue) | ||
2553 | count_str = ID2P(LANG_PLAYLIST_QUEUE_COUNT); | ||
2554 | else | ||
2555 | count_str = ID2P(LANG_PLAYLIST_INSERT_COUNT); | ||
2556 | |||
2557 | display_playlist_count(count, count_str, false); | ||
2558 | |||
2559 | if (position == PLAYLIST_REPLACE) | ||
2560 | { | ||
2561 | if (remove_all_tracks_unlocked(playlist, true) == 0) | ||
2562 | position = PLAYLIST_INSERT_LAST; | ||
2563 | else | ||
2564 | { | 2553 | { |
2565 | close(fd); | 2554 | notify_access_error(); |
2566 | goto out; | 2555 | goto out; |
2567 | } | 2556 | } |
2568 | } | ||
2569 | 2557 | ||
2570 | while ((max = read_line(fd, temp_buf, sizeof(temp_buf))) > 0) | 2558 | /* we need the directory name for formatting purposes */ |
2571 | { | 2559 | size_t dirlen = path_dirname(filename, (const char **)&dir); |
2572 | /* user abort */ | 2560 | dir = strmemdupa(dir, dirlen); |
2573 | if (action_userabort(TIMEOUT_NOBLOCK)) | ||
2574 | break; | ||
2575 | 2561 | ||
2576 | if (temp_buf[0] != '#' && temp_buf[0] != '\0') | 2562 | while ((max = read_line(fd, temp_buf, sizeof(temp_buf))) > 0) |
2577 | { | 2563 | { |
2578 | int insert_pos; | 2564 | /* user abort */ |
2579 | 2565 | if (action_userabort(TIMEOUT_NOBLOCK)) | |
2580 | if (!utf8) | 2566 | break; |
2581 | { | ||
2582 | /* Use trackname as a temporay buffer. Note that trackname must | ||
2583 | * be as large as temp_buf. | ||
2584 | */ | ||
2585 | max = convert_m3u_name(temp_buf, max, sizeof(temp_buf), trackname); | ||
2586 | } | ||
2587 | |||
2588 | /* we need to format so that relative paths are correctly | ||
2589 | handled */ | ||
2590 | if (format_track_path(trackname, temp_buf, sizeof(trackname), dir) < 0) | ||
2591 | { | ||
2592 | goto out; | ||
2593 | } | ||
2594 | |||
2595 | insert_pos = add_track_to_playlist_unlocked(playlist, trackname, | ||
2596 | position, queue, -1); | ||
2597 | |||
2598 | if (insert_pos < 0) | ||
2599 | { | ||
2600 | goto out; | ||
2601 | } | ||
2602 | |||
2603 | /* After first INSERT_FIRST switch to INSERT so that all the | ||
2604 | rest of the tracks get inserted one after the other */ | ||
2605 | if (position == PLAYLIST_INSERT_FIRST) | ||
2606 | position = PLAYLIST_INSERT; | ||
2607 | |||
2608 | count++; | ||
2609 | 2567 | ||
2610 | if ((count%PLAYLIST_DISPLAY_COUNT) == 0) | 2568 | if (temp_buf[0] != '#' && temp_buf[0] != '\0') |
2611 | { | 2569 | { |
2612 | display_playlist_count(count, count_str, false); | 2570 | if (!utf8) |
2571 | { | ||
2572 | /* Use trackname as a temporay buffer. Note that trackname must | ||
2573 | * be as large as temp_buf. | ||
2574 | */ | ||
2575 | max = convert_m3u_name(temp_buf, max, sizeof(temp_buf), trackname); | ||
2576 | } | ||
2613 | 2577 | ||
2614 | if (count == PLAYLIST_DISPLAY_COUNT && | 2578 | /* we need to format so that relative paths are correctly |
2615 | (audio_status() & AUDIO_STATUS_PLAY) && | 2579 | handled */ |
2616 | playlist->started) | 2580 | if (format_track_path(trackname, temp_buf, sizeof(trackname), dir) < 0) |
2617 | { | 2581 | { |
2618 | audio_flush_and_reload_tracks(); | 2582 | goto out; |
2619 | } | 2583 | } |
2584 | |||
2585 | if (playlist_insert_context_add(&pl_context, trackname) < 0) | ||
2586 | goto out; | ||
2620 | } | 2587 | } |
2621 | } | ||
2622 | 2588 | ||
2623 | /* let the other threads work */ | 2589 | /* let the other threads work */ |
2624 | yield(); | 2590 | yield(); |
2591 | } | ||
2625 | } | 2592 | } |
2626 | 2593 | ||
2627 | close(fd); | ||
2628 | |||
2629 | sync_control_unlocked(playlist); | ||
2630 | |||
2631 | display_playlist_count(count, count_str, true); | ||
2632 | |||
2633 | if ((audio_status() & AUDIO_STATUS_PLAY) && playlist->started) | ||
2634 | audio_flush_and_reload_tracks(); | ||
2635 | |||
2636 | result = 0; | 2594 | result = 0; |
2637 | 2595 | ||
2638 | out: | 2596 | out: |
2597 | close(fd); | ||
2639 | cpu_boost(false); | 2598 | cpu_boost(false); |
2640 | 2599 | playlist_insert_context_release(&pl_context); | |
2641 | playlist_write_unlock(playlist); | ||
2642 | dc_thread_start(playlist, true); | ||
2643 | |||
2644 | return result; | 2600 | return result; |
2645 | } | 2601 | } |
2646 | 2602 | ||
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 | |||
98 | int display_index; /* index of track for display */ | 98 | int display_index; /* index of track for display */ |
99 | }; | 99 | }; |
100 | 100 | ||
101 | struct playlist_insert_context { | ||
102 | struct playlist_info* playlist; | ||
103 | int position; | ||
104 | bool queue; | ||
105 | bool progress; | ||
106 | bool initialized; | ||
107 | int count; | ||
108 | int32_t count_langid; | ||
109 | }; | ||
110 | |||
101 | /* Exported functions only for current playlist. */ | 111 | /* Exported functions only for current playlist. */ |
102 | void playlist_init(void) INIT_ATTR; | 112 | void playlist_init(void) INIT_ATTR; |
103 | void playlist_shutdown(void); | 113 | void playlist_shutdown(void); |
@@ -132,6 +142,12 @@ void playlist_close(struct playlist_info* playlist); | |||
132 | void playlist_sync(struct playlist_info* playlist); | 142 | void playlist_sync(struct playlist_info* playlist); |
133 | int playlist_insert_track(struct playlist_info* playlist, const char *filename, | 143 | int playlist_insert_track(struct playlist_info* playlist, const char *filename, |
134 | int position, bool queue, bool sync); | 144 | int position, bool queue, bool sync); |
145 | int playlist_insert_context_create(struct playlist_info* playlist, | ||
146 | struct playlist_insert_context *context, | ||
147 | int position, bool queue, bool progress); | ||
148 | int playlist_insert_context_add(struct playlist_insert_context *context, | ||
149 | const char *filename); | ||
150 | void playlist_insert_context_release(struct playlist_insert_context *context); | ||
135 | int playlist_insert_directory(struct playlist_info* playlist, | 151 | int playlist_insert_directory(struct playlist_info* playlist, |
136 | const char *dirname, int position, bool queue, | 152 | const char *dirname, int position, bool queue, |
137 | bool recurse); | 153 | bool recurse); |