diff options
author | roman.artiukhin <bahusdrive@gmail.com> | 2022-11-17 20:05:08 +0200 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2023-09-20 10:01:47 -0400 |
commit | 951e23951734b958d43f3e726b201fa2c52c2c01 (patch) | |
tree | 8c980482d1080137817b6db0c6bf5a90b5f3a55c | |
parent | 57409f52d5da3665a91c6cf2cbcef86ea1004ccf (diff) | |
download | rockbox-951e23951734b958d43f3e726b201fa2c52c2c01.tar.gz rockbox-951e23951734b958d43f3e726b201fa2c52c2c01.zip |
Cache folder album art
Fixes FS#13372
Change-Id: Ia50f5252cb8375a97c093abeda89d830bf003ff3
-rw-r--r-- | apps/playback.c | 77 |
1 files changed, 70 insertions, 7 deletions
diff --git a/apps/playback.c b/apps/playback.c index 865d0d724f..e0cd2c94a1 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -180,6 +180,9 @@ static struct albumart_slot | |||
180 | int used; /* Counter; increments if something uses it */ | 180 | int used; /* Counter; increments if something uses it */ |
181 | } albumart_slots[MAX_MULTIPLE_AA]; /* (A,O) */ | 181 | } albumart_slots[MAX_MULTIPLE_AA]; /* (A,O) */ |
182 | 182 | ||
183 | static char last_folder_aa_path[MAX_PATH] = "\0"; | ||
184 | static int last_folder_aa_hid[MAX_MULTIPLE_AA] = {0}; | ||
185 | |||
183 | #define FOREACH_ALBUMART(i) for (int i = 0; i < MAX_MULTIPLE_AA; i++) | 186 | #define FOREACH_ALBUMART(i) for (int i = 0; i < MAX_MULTIPLE_AA; i++) |
184 | #endif /* HAVE_ALBUMART */ | 187 | #endif /* HAVE_ALBUMART */ |
185 | 188 | ||
@@ -590,6 +593,20 @@ static bool track_list_commit_buf_info(struct track_buf_info *tbip, | |||
590 | return true; | 593 | return true; |
591 | } | 594 | } |
592 | 595 | ||
596 | #ifdef HAVE_ALBUMART | ||
597 | static inline void clear_cached_aa_handles(int* aa_handles) | ||
598 | { | ||
599 | if (last_folder_aa_path[0] == 0) | ||
600 | return; | ||
601 | |||
602 | FOREACH_ALBUMART(i) | ||
603 | { | ||
604 | if (aa_handles[i] == last_folder_aa_hid[i]) | ||
605 | aa_handles[i] = 0; | ||
606 | } | ||
607 | } | ||
608 | #endif //HAVE_ALBUMART | ||
609 | |||
593 | /* Free the track buffer entry and possibly remove it from the list if it | 610 | /* Free the track buffer entry and possibly remove it from the list if it |
594 | was succesfully added at some point */ | 611 | was succesfully added at some point */ |
595 | static void track_list_free_buf_info(struct track_buf_info *tbip) | 612 | static void track_list_free_buf_info(struct track_buf_info *tbip) |
@@ -631,6 +648,9 @@ static void track_list_free_buf_info(struct track_buf_info *tbip) | |||
631 | /* No movement allowed during bufclose calls */ | 648 | /* No movement allowed during bufclose calls */ |
632 | buf_pin_handle(hid, true); | 649 | buf_pin_handle(hid, true); |
633 | 650 | ||
651 | #ifdef HAVE_ALBUMART | ||
652 | clear_cached_aa_handles(tbip->info.aa_hid); | ||
653 | #endif | ||
634 | FOR_EACH_TRACK_INFO_HANDLE(i) | 654 | FOR_EACH_TRACK_INFO_HANDLE(i) |
635 | bufclose(tbip->info.handle[i]); | 655 | bufclose(tbip->info.handle[i]); |
636 | 656 | ||
@@ -818,6 +838,21 @@ size_t audio_buffer_available(void) | |||
818 | return MAX(core_size, size); | 838 | return MAX(core_size, size); |
819 | } | 839 | } |
820 | 840 | ||
841 | #ifdef HAVE_ALBUMART | ||
842 | static void clear_last_folder_album_art(void) | ||
843 | { | ||
844 | if(last_folder_aa_path[0] == 0) | ||
845 | return; | ||
846 | |||
847 | last_folder_aa_path[0] = 0; | ||
848 | FOREACH_ALBUMART(i) | ||
849 | { | ||
850 | bufclose(last_folder_aa_hid[i]); | ||
851 | last_folder_aa_hid[i] = 0; | ||
852 | } | ||
853 | } | ||
854 | #endif | ||
855 | |||
821 | /* Set up the audio buffer for playback | 856 | /* Set up the audio buffer for playback |
822 | * filebuflen must be pre-initialized with the maximum size */ | 857 | * filebuflen must be pre-initialized with the maximum size */ |
823 | static void audio_reset_buffer_noalloc( | 858 | static void audio_reset_buffer_noalloc( |
@@ -854,6 +889,10 @@ static void audio_reset_buffer_noalloc( | |||
854 | filebuf += allocsize; | 889 | filebuf += allocsize; |
855 | filebuflen -= allocsize; | 890 | filebuflen -= allocsize; |
856 | 891 | ||
892 | #ifdef HAVE_ALBUMART | ||
893 | clear_last_folder_album_art(); | ||
894 | #endif | ||
895 | |||
857 | buffering_reset(filebuf, filebuflen); | 896 | buffering_reset(filebuf, filebuflen); |
858 | 897 | ||
859 | buffer_state = AUDIOBUF_STATE_INITIALIZED; | 898 | buffer_state = AUDIOBUF_STATE_INITIALIZED; |
@@ -1695,9 +1734,31 @@ void set_albumart_mode(int setting) | |||
1695 | albumart_mode = setting; | 1734 | albumart_mode = setting; |
1696 | } | 1735 | } |
1697 | 1736 | ||
1737 | static int load_album_art_from_path(char *path, struct bufopen_bitmap_data *user_data, bool is_current_track, int i) | ||
1738 | { | ||
1739 | user_data->embedded_albumart = NULL; | ||
1740 | |||
1741 | bool same_path = strcmp(last_folder_aa_path, path) == 0; | ||
1742 | if (same_path && last_folder_aa_hid[i] != 0) | ||
1743 | return last_folder_aa_hid[i]; | ||
1744 | |||
1745 | // To simplify caching logic a bit we keep track only for first AA path | ||
1746 | // If other album arts use different path (like dimension specific arts) just skip caching for them | ||
1747 | bool is_cacheable = i == 0 && (is_current_track || last_folder_aa_path[0] == 0); | ||
1748 | if (!same_path && is_cacheable) | ||
1749 | { | ||
1750 | clear_last_folder_album_art(); | ||
1751 | strcpy(last_folder_aa_path, path); | ||
1752 | } | ||
1753 | int hid = bufopen(path, 0, TYPE_BITMAP, user_data); | ||
1754 | if (hid != ERR_BUFFER_FULL && (same_path || is_cacheable)) | ||
1755 | last_folder_aa_hid[i] = hid; | ||
1756 | return hid; | ||
1757 | } | ||
1758 | |||
1698 | /* Load any album art for the file - returns false if the buffer is full */ | 1759 | /* Load any album art for the file - returns false if the buffer is full */ |
1699 | static int audio_load_albumart(struct track_info *infop, | 1760 | static int audio_load_albumart(struct track_info *infop, |
1700 | struct mp3entry *track_id3) | 1761 | struct mp3entry *track_id3, bool is_current_track) |
1701 | { | 1762 | { |
1702 | FOREACH_ALBUMART(i) | 1763 | FOREACH_ALBUMART(i) |
1703 | { | 1764 | { |
@@ -1721,8 +1782,7 @@ static int audio_load_albumart(struct track_info *infop, | |||
1721 | if (find_albumart(track_id3, path, sizeof(path), | 1782 | if (find_albumart(track_id3, path, sizeof(path), |
1722 | &albumart_slots[i].dim)) | 1783 | &albumart_slots[i].dim)) |
1723 | { | 1784 | { |
1724 | user_data.embedded_albumart = NULL; | 1785 | hid = load_album_art_from_path(path, &user_data, is_current_track, i); |
1725 | hid = bufopen(path, 0, TYPE_BITMAP, &user_data); | ||
1726 | } | 1786 | } |
1727 | checked_image_file = true; | 1787 | checked_image_file = true; |
1728 | } | 1788 | } |
@@ -1732,6 +1792,8 @@ static int audio_load_albumart(struct track_info *infop, | |||
1732 | hid < 0 && hid != ERR_BUFFER_FULL && | 1792 | hid < 0 && hid != ERR_BUFFER_FULL && |
1733 | track_id3->has_embedded_albumart && track_id3->albumart.type == AA_TYPE_JPG) | 1793 | track_id3->has_embedded_albumart && track_id3->albumart.type == AA_TYPE_JPG) |
1734 | { | 1794 | { |
1795 | if (is_current_track) | ||
1796 | clear_last_folder_album_art(); | ||
1735 | user_data.embedded_albumart = &track_id3->albumart; | 1797 | user_data.embedded_albumart = &track_id3->albumart; |
1736 | hid = bufopen(track_id3->path, 0, TYPE_BITMAP, &user_data); | 1798 | hid = bufopen(track_id3->path, 0, TYPE_BITMAP, &user_data); |
1737 | } | 1799 | } |
@@ -1743,8 +1805,7 @@ static int audio_load_albumart(struct track_info *infop, | |||
1743 | if (find_albumart(track_id3, path, sizeof(path), | 1805 | if (find_albumart(track_id3, path, sizeof(path), |
1744 | &albumart_slots[i].dim)) | 1806 | &albumart_slots[i].dim)) |
1745 | { | 1807 | { |
1746 | user_data.embedded_albumart = NULL; | 1808 | hid = load_album_art_from_path(path, &user_data, is_current_track, i); |
1747 | hid = bufopen(path, 0, TYPE_BITMAP, &user_data); | ||
1748 | } | 1809 | } |
1749 | } | 1810 | } |
1750 | 1811 | ||
@@ -2037,7 +2098,7 @@ static int audio_finish_load_track(struct track_info *infop) | |||
2037 | 2098 | ||
2038 | #ifdef HAVE_ALBUMART | 2099 | #ifdef HAVE_ALBUMART |
2039 | /* Try to load album art for the track */ | 2100 | /* Try to load album art for the track */ |
2040 | int retval = audio_load_albumart(infop, track_id3); | 2101 | int retval = audio_load_albumart(infop, track_id3, infop->self_hid == cur_info.self_hid); |
2041 | if (retval == ERR_BITMAP_TOO_LARGE) | 2102 | if (retval == ERR_BITMAP_TOO_LARGE) |
2042 | { | 2103 | { |
2043 | /* No space for album art on buffer because the file is larger than the buffer. | 2104 | /* No space for album art on buffer because the file is larger than the buffer. |
@@ -2876,7 +2937,9 @@ static void audio_stop_playback(void) | |||
2876 | play_status = PLAY_STOPPED; | 2937 | play_status = PLAY_STOPPED; |
2877 | 2938 | ||
2878 | wipe_track_metadata(true); | 2939 | wipe_track_metadata(true); |
2879 | 2940 | #ifdef HAVE_ALBUMART | |
2941 | clear_last_folder_album_art(); | ||
2942 | #endif | ||
2880 | /* Go idle */ | 2943 | /* Go idle */ |
2881 | filling = STATE_IDLE; | 2944 | filling = STATE_IDLE; |
2882 | cancel_cpu_boost(); | 2945 | cancel_cpu_boost(); |