diff options
author | Thomas Martitz <kugel@rockbox.org> | 2009-10-16 19:14:41 +0000 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2009-10-16 19:14:41 +0000 |
commit | e9c10189e93fe53cff74ae8fa15d19b1c522d5e4 (patch) | |
tree | e3c39a41ff160194dfd9ce617893e0367a6fdcc8 | |
parent | a72ffe7bb533302dbf4e6c7c4f1e4bd4078d3ed6 (diff) | |
download | rockbox-e9c10189e93fe53cff74ae8fa15d19b1c522d5e4.tar.gz rockbox-e9c10189e93fe53cff74ae8fa15d19b1c522d5e4.zip |
Rework albumart buffering internally to allow for mutliple albumart sizes.
Playback now has a few albumart slots. Anything (most importantly: skins) can obtain such a slot.
The slot has fields for the size which is passed to bufopen then to image_load to buffer the albumart with the proper size.
Currently there's 1 slot. We can increase it for remotes if we want. Custom statusbar will increase it.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23209 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/buffering.c | 20 | ||||
-rw-r--r-- | apps/buffering.h | 3 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_display.c | 6 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_parser.c | 21 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_tokens.c | 5 | ||||
-rw-r--r-- | apps/gui/skin_engine/wps_internals.h | 1 | ||||
-rw-r--r-- | apps/gui/wps.c | 22 | ||||
-rw-r--r-- | apps/gui/wps.h | 10 | ||||
-rw-r--r-- | apps/playback.c | 156 | ||||
-rw-r--r-- | apps/playback.h | 29 | ||||
-rw-r--r-- | apps/plugin.h | 3 | ||||
-rw-r--r-- | apps/recorder/albumart.c | 23 | ||||
-rw-r--r-- | apps/recorder/albumart.h | 4 |
13 files changed, 199 insertions, 104 deletions
diff --git a/apps/buffering.c b/apps/buffering.c index 08590c9fdf..e66e95d66d 100644 --- a/apps/buffering.c +++ b/apps/buffering.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #ifdef HAVE_ALBUMART | 54 | #ifdef HAVE_ALBUMART |
55 | #include "albumart.h" | 55 | #include "albumart.h" |
56 | #include "jpeg_load.h" | 56 | #include "jpeg_load.h" |
57 | #include "bmp.h" | ||
57 | #endif | 58 | #endif |
58 | 59 | ||
59 | #define GUARD_BUFSIZE (32*1024) | 60 | #define GUARD_BUFSIZE (32*1024) |
@@ -843,10 +844,13 @@ static bool fill_buffer(void) | |||
843 | /* Given a file descriptor to a bitmap file, write the bitmap data to the | 844 | /* Given a file descriptor to a bitmap file, write the bitmap data to the |
844 | buffer, with a struct bitmap and the actual data immediately following. | 845 | buffer, with a struct bitmap and the actual data immediately following. |
845 | Return value is the total size (struct + data). */ | 846 | Return value is the total size (struct + data). */ |
846 | static int load_image(int fd, const char *path) | 847 | static int load_image(int fd, const char *path, struct dim *dim) |
847 | { | 848 | { |
848 | int rc; | 849 | int rc; |
849 | struct bitmap *bmp = (struct bitmap *)&buffer[buf_widx]; | 850 | struct bitmap *bmp = (struct bitmap *)&buffer[buf_widx]; |
851 | |||
852 | /* get the desired image size */ | ||
853 | bmp->width = dim->width, bmp->height = dim->height; | ||
850 | /* FIXME: alignment may be needed for the data buffer. */ | 854 | /* FIXME: alignment may be needed for the data buffer. */ |
851 | bmp->data = &buffer[buf_widx + sizeof(struct bitmap)]; | 855 | bmp->data = &buffer[buf_widx + sizeof(struct bitmap)]; |
852 | #ifndef HAVE_JPEG | 856 | #ifndef HAVE_JPEG |
@@ -859,8 +863,6 @@ static int load_image(int fd, const char *path) | |||
859 | int free = (int)MIN(buffer_len - BUF_USED, buffer_len - buf_widx) | 863 | int free = (int)MIN(buffer_len - BUF_USED, buffer_len - buf_widx) |
860 | - sizeof(struct bitmap); | 864 | - sizeof(struct bitmap); |
861 | 865 | ||
862 | get_albumart_size(bmp); | ||
863 | |||
864 | #ifdef HAVE_JPEG | 866 | #ifdef HAVE_JPEG |
865 | int pathlen = strlen(path); | 867 | int pathlen = strlen(path); |
866 | if (strcmp(path + pathlen - 4, ".bmp")) | 868 | if (strcmp(path + pathlen - 4, ".bmp")) |
@@ -897,11 +899,19 @@ management functions for all the actual handle management work. | |||
897 | filename: name of the file to open | 899 | filename: name of the file to open |
898 | offset: offset at which to start buffering the file, useful when the first | 900 | offset: offset at which to start buffering the file, useful when the first |
899 | (offset-1) bytes of the file aren't needed. | 901 | (offset-1) bytes of the file aren't needed. |
902 | type: one of the data types supported (audio, image, cuesheet, others | ||
903 | user_data: user data passed possibly passed in subcalls specific to a | ||
904 | data_type (only used for image (albumart) buffering so far ) | ||
900 | return value: <0 if the file cannot be opened, or one file already | 905 | return value: <0 if the file cannot be opened, or one file already |
901 | queued to be opened, otherwise the handle for the file in the buffer | 906 | queued to be opened, otherwise the handle for the file in the buffer |
902 | */ | 907 | */ |
903 | int bufopen(const char *file, size_t offset, enum data_type type) | 908 | int bufopen(const char *file, size_t offset, enum data_type type, |
909 | void *user_data) | ||
904 | { | 910 | { |
911 | #ifndef HAVE_ALBUMART | ||
912 | /* currently only used for aa loading */ | ||
913 | (void)user_data; | ||
914 | #endif | ||
905 | if (type == TYPE_ID3) | 915 | if (type == TYPE_ID3) |
906 | { | 916 | { |
907 | /* ID3 case: allocate space, init the handle and return. */ | 917 | /* ID3 case: allocate space, init the handle and return. */ |
@@ -967,7 +977,7 @@ int bufopen(const char *file, size_t offset, enum data_type type) | |||
967 | /* Bitmap file: we load the data instead of the file */ | 977 | /* Bitmap file: we load the data instead of the file */ |
968 | int rc; | 978 | int rc; |
969 | mutex_lock(&llist_mod_mutex); /* Lock because load_bitmap yields */ | 979 | mutex_lock(&llist_mod_mutex); /* Lock because load_bitmap yields */ |
970 | rc = load_image(fd, file); | 980 | rc = load_image(fd, file, (struct dim*)user_data); |
971 | mutex_unlock(&llist_mod_mutex); | 981 | mutex_unlock(&llist_mod_mutex); |
972 | if (rc <= 0) | 982 | if (rc <= 0) |
973 | { | 983 | { |
diff --git a/apps/buffering.h b/apps/buffering.h index d0e2dd797f..6e17b65d8c 100644 --- a/apps/buffering.h +++ b/apps/buffering.h | |||
@@ -74,7 +74,8 @@ bool buffering_reset(char *buf, size_t buflen); | |||
74 | 74 | ||
75 | #define BUF_MAX_HANDLES 256 | 75 | #define BUF_MAX_HANDLES 256 |
76 | 76 | ||
77 | int bufopen(const char *file, size_t offset, enum data_type type); | 77 | int bufopen(const char *file, size_t offset, enum data_type type, |
78 | void *user_data); | ||
78 | int bufalloc(const void *src, size_t size, enum data_type type); | 79 | int bufalloc(const void *src, size_t size, enum data_type type); |
79 | bool bufclose(int handle_id); | 80 | bool bufclose(int handle_id); |
80 | int bufseek(int handle_id, size_t newpos); | 81 | int bufseek(int handle_id, size_t newpos); |
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index 67984cd2bb..a5ea28619a 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c | |||
@@ -259,7 +259,8 @@ static void wps_display_images(struct gui_wps *gwps, struct viewport* vp) | |||
259 | if (data->albumart && data->albumart->vp == vp | 259 | if (data->albumart && data->albumart->vp == vp |
260 | && data->albumart->draw) | 260 | && data->albumart->draw) |
261 | { | 261 | { |
262 | draw_album_art(gwps, audio_current_aa_hid(), false); | 262 | draw_album_art(gwps, playback_current_aa_hid(data->playback_aa_slot), |
263 | false); | ||
263 | data->albumart->draw = false; | 264 | data->albumart->draw = false; |
264 | } | 265 | } |
265 | #endif | 266 | #endif |
@@ -486,7 +487,8 @@ static bool evaluate_conditional(struct gui_wps *gwps, int *token_index) | |||
486 | #ifdef HAVE_ALBUMART | 487 | #ifdef HAVE_ALBUMART |
487 | if (data->albumart && data->tokens[i].type == WPS_TOKEN_ALBUMART_DISPLAY) | 488 | if (data->albumart && data->tokens[i].type == WPS_TOKEN_ALBUMART_DISPLAY) |
488 | { | 489 | { |
489 | draw_album_art(gwps, audio_current_aa_hid(), true); | 490 | draw_album_art(gwps, |
491 | playback_current_aa_hid(data->playback_aa_slot), true); | ||
490 | data->albumart->draw = false; | 492 | data->albumart->draw = false; |
491 | } | 493 | } |
492 | #endif | 494 | #endif |
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 016126bffb..fa35ed994f 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c | |||
@@ -56,6 +56,10 @@ | |||
56 | #include "bmp.h" | 56 | #include "bmp.h" |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | #ifdef HAVE_ALBUMART | ||
60 | #include "playback.h" | ||
61 | #endif | ||
62 | |||
59 | #include "backdrop.h" | 63 | #include "backdrop.h" |
60 | 64 | ||
61 | #define WPS_ERROR_INVALID_PARAM -1 | 65 | #define WPS_ERROR_INVALID_PARAM -1 |
@@ -985,6 +989,8 @@ static int parse_albumart_load(const char *wps_bufptr, | |||
985 | { | 989 | { |
986 | const char *_pos, *newline; | 990 | const char *_pos, *newline; |
987 | bool parsing; | 991 | bool parsing; |
992 | struct dim dimensions; | ||
993 | int albumart_slot; | ||
988 | struct skin_albumart *aa = skin_buffer_alloc(sizeof(struct skin_albumart)); | 994 | struct skin_albumart *aa = skin_buffer_alloc(sizeof(struct skin_albumart)); |
989 | (void)token; /* silence warning */ | 995 | (void)token; /* silence warning */ |
990 | if (!aa) | 996 | if (!aa) |
@@ -1125,6 +1131,16 @@ static int parse_albumart_load(const char *wps_bufptr, | |||
1125 | aa->draw = false; | 1131 | aa->draw = false; |
1126 | wps_data->albumart = aa; | 1132 | wps_data->albumart = aa; |
1127 | 1133 | ||
1134 | dimensions.width = aa->width; | ||
1135 | dimensions.height = aa->height; | ||
1136 | |||
1137 | albumart_slot = playback_claim_aa_slot(&dimensions); | ||
1138 | |||
1139 | if (albumart_slot < 0) /* didn't get a slot ? */ | ||
1140 | return skip_end_of_line(wps_bufptr); | ||
1141 | else | ||
1142 | wps_data->playback_aa_slot = albumart_slot; | ||
1143 | |||
1128 | /* Skip the rest of the line */ | 1144 | /* Skip the rest of the line */ |
1129 | return skip_end_of_line(wps_bufptr); | 1145 | return skip_end_of_line(wps_bufptr); |
1130 | } | 1146 | } |
@@ -1601,6 +1617,11 @@ void skin_data_reset(struct wps_data *wps_data) | |||
1601 | wps_data->strings = NULL; | 1617 | wps_data->strings = NULL; |
1602 | #ifdef HAVE_ALBUMART | 1618 | #ifdef HAVE_ALBUMART |
1603 | wps_data->albumart = NULL; | 1619 | wps_data->albumart = NULL; |
1620 | if (wps_data->playback_aa_slot >= 0) | ||
1621 | { | ||
1622 | playback_release_aa_slot(wps_data->playback_aa_slot); | ||
1623 | wps_data->playback_aa_slot = -1; | ||
1624 | } | ||
1604 | #endif | 1625 | #endif |
1605 | wps_data->tokens = NULL; | 1626 | wps_data->tokens = NULL; |
1606 | wps_data->num_tokens = 0; | 1627 | wps_data->num_tokens = 0; |
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c index d607538f0f..6b29091fe6 100644 --- a/apps/gui/skin_engine/skin_tokens.c +++ b/apps/gui/skin_engine/skin_tokens.c | |||
@@ -368,8 +368,9 @@ const char *get_token_value(struct gui_wps *gwps, | |||
368 | 368 | ||
369 | #ifdef HAVE_ALBUMART | 369 | #ifdef HAVE_ALBUMART |
370 | case WPS_TOKEN_ALBUMART_FOUND: | 370 | case WPS_TOKEN_ALBUMART_FOUND: |
371 | if (data->albumart && audio_current_aa_hid() >= 0) { | 371 | if (data->albumart) { |
372 | return "C"; | 372 | if (playback_current_aa_hid(data->playback_aa_slot) >= 0) |
373 | return "C"; | ||
373 | } | 374 | } |
374 | return NULL; | 375 | return NULL; |
375 | 376 | ||
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index 7a4fdddc7c..638fb0a081 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h | |||
@@ -255,6 +255,7 @@ struct wps_data | |||
255 | struct skin_token_list *strings; | 255 | struct skin_token_list *strings; |
256 | #ifdef HAVE_ALBUMART | 256 | #ifdef HAVE_ALBUMART |
257 | struct skin_albumart *albumart; | 257 | struct skin_albumart *albumart; |
258 | int playback_aa_slot; | ||
258 | #endif | 259 | #endif |
259 | struct wps_token *tokens; | 260 | struct wps_token *tokens; |
260 | /* Total number of tokens in the WPS. During WPS parsing, this is | 261 | /* Total number of tokens in the WPS. During WPS parsing, this is |
diff --git a/apps/gui/wps.c b/apps/gui/wps.c index d4a2893ff2..342ebdea2b 100644 --- a/apps/gui/wps.c +++ b/apps/gui/wps.c | |||
@@ -1278,6 +1278,7 @@ static void statusbar_toggle_handler(void *data) | |||
1278 | } | 1278 | } |
1279 | #endif | 1279 | #endif |
1280 | 1280 | ||
1281 | |||
1281 | void gui_sync_wps_init(void) | 1282 | void gui_sync_wps_init(void) |
1282 | { | 1283 | { |
1283 | int i; | 1284 | int i; |
@@ -1285,6 +1286,7 @@ void gui_sync_wps_init(void) | |||
1285 | { | 1286 | { |
1286 | #ifdef HAVE_ALBUMART | 1287 | #ifdef HAVE_ALBUMART |
1287 | wps_datas[i].albumart = NULL; | 1288 | wps_datas[i].albumart = NULL; |
1289 | wps_datas[i].playback_aa_slot = -1; | ||
1288 | #endif | 1290 | #endif |
1289 | #ifdef HAVE_REMOTE_LCD | 1291 | #ifdef HAVE_REMOTE_LCD |
1290 | wps_datas[i].remote_wps = (i == SCREEN_REMOTE); | 1292 | wps_datas[i].remote_wps = (i == SCREEN_REMOTE); |
@@ -1304,26 +1306,6 @@ void gui_sync_wps_init(void) | |||
1304 | #endif | 1306 | #endif |
1305 | } | 1307 | } |
1306 | 1308 | ||
1307 | #ifdef HAVE_ALBUMART | ||
1308 | bool wps_uses_albumart(int *width, int *height) | ||
1309 | { | ||
1310 | int i; | ||
1311 | FOR_NB_SCREENS(i) { | ||
1312 | struct gui_wps *gwps = &gui_wps[i]; | ||
1313 | struct skin_albumart *aa = gwps->data->albumart; | ||
1314 | if (aa && (aa->state != WPS_ALBUMART_NONE)) | ||
1315 | { | ||
1316 | if (width) | ||
1317 | *width = aa->width; | ||
1318 | if (height) | ||
1319 | *height = aa->height; | ||
1320 | return true; | ||
1321 | } | ||
1322 | } | ||
1323 | return false; | ||
1324 | } | ||
1325 | #endif | ||
1326 | |||
1327 | 1309 | ||
1328 | #ifdef IPOD_ACCESSORY_PROTOCOL | 1310 | #ifdef IPOD_ACCESSORY_PROTOCOL |
1329 | int wps_get_ff_rewind_count(void) | 1311 | int wps_get_ff_rewind_count(void) |
diff --git a/apps/gui/wps.h b/apps/gui/wps.h index 6affcee698..8c6de9e2fc 100644 --- a/apps/gui/wps.h +++ b/apps/gui/wps.h | |||
@@ -38,16 +38,6 @@ void display_keylock_text(bool locked); | |||
38 | 38 | ||
39 | bool is_wps_fading(void); | 39 | bool is_wps_fading(void); |
40 | 40 | ||
41 | |||
42 | #ifdef HAVE_ALBUMART | ||
43 | /* | ||
44 | * Returns true if at least one of the gui_wps screens has an album art | ||
45 | * tag in its wps structure and writes the width and height into the passed | ||
46 | * pointers | ||
47 | */ | ||
48 | bool wps_uses_albumart(int*, int*); | ||
49 | #endif | ||
50 | |||
51 | #ifdef IPOD_ACCESSORY_PROTOCOL | 41 | #ifdef IPOD_ACCESSORY_PROTOCOL |
52 | /* return length of the current ff or rewin action, IAP needs this */ | 42 | /* return length of the current ff or rewin action, IAP needs this */ |
53 | int wps_get_ff_rewind_count(void); | 43 | int wps_get_ff_rewind_count(void); |
diff --git a/apps/playback.c b/apps/playback.c index c69bf39abd..4a5ef5c450 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -64,7 +64,10 @@ | |||
64 | #include "icons.h" | 64 | #include "icons.h" |
65 | #include "peakmeter.h" | 65 | #include "peakmeter.h" |
66 | #include "action.h" | 66 | #include "action.h" |
67 | #ifdef HAVE_ALBUMART | ||
67 | #include "albumart.h" | 68 | #include "albumart.h" |
69 | #include "bmp.h" | ||
70 | #endif | ||
68 | #endif | 71 | #endif |
69 | #include "lang.h" | 72 | #include "lang.h" |
70 | #include "misc.h" | 73 | #include "misc.h" |
@@ -158,6 +161,7 @@ enum filling_state { | |||
158 | }; | 161 | }; |
159 | 162 | ||
160 | #define MAX_TRACK 128 | 163 | #define MAX_TRACK 128 |
164 | #define MAX_MULTIPLE_AA 1 | ||
161 | 165 | ||
162 | #define MAX_TRACK_MASK (MAX_TRACK-1) | 166 | #define MAX_TRACK_MASK (MAX_TRACK-1) |
163 | 167 | ||
@@ -206,7 +210,7 @@ struct track_info { | |||
206 | int id3_hid; /* The ID for the track's metadata handle */ | 210 | int id3_hid; /* The ID for the track's metadata handle */ |
207 | int codec_hid; /* The ID for the track's codec handle */ | 211 | int codec_hid; /* The ID for the track's codec handle */ |
208 | #ifdef HAVE_ALBUMART | 212 | #ifdef HAVE_ALBUMART |
209 | int aa_hid; /* The ID for the track's album art handle */ | 213 | int aa_hid[MAX_MULTIPLE_AA];/* The ID for the track's album art handle */ |
210 | #endif | 214 | #endif |
211 | int cuesheet_hid; /* The ID for the track's parsed cueesheet handle */ | 215 | int cuesheet_hid; /* The ID for the track's parsed cueesheet handle */ |
212 | 216 | ||
@@ -215,6 +219,16 @@ struct track_info { | |||
215 | bool taginfo_ready; /* Is metadata read */ | 219 | bool taginfo_ready; /* Is metadata read */ |
216 | }; | 220 | }; |
217 | 221 | ||
222 | |||
223 | #ifdef HAVE_ALBUMART | ||
224 | struct albumart_slot { | ||
225 | struct dim dim; /* holds width, height of the albumart */ | ||
226 | int used; /* counter, increments if something uses it */ | ||
227 | } albumart_slots[MAX_MULTIPLE_AA]; | ||
228 | |||
229 | #define FOREACH_ALBUMART(i) for(i = 0;i < MAX_MULTIPLE_AA; i++) | ||
230 | #endif | ||
231 | |||
218 | static struct track_info tracks[MAX_TRACK]; | 232 | static struct track_info tracks[MAX_TRACK]; |
219 | static volatile int track_ridx = 0; /* Track being decoded (A/C-) */ | 233 | static volatile int track_ridx = 0; /* Track being decoded (A/C-) */ |
220 | static int track_widx = 0; /* Track being buffered (A) */ | 234 | static int track_widx = 0; /* Track being buffered (A) */ |
@@ -367,11 +381,17 @@ static bool clear_track_info(struct track_info *track) | |||
367 | } | 381 | } |
368 | 382 | ||
369 | #ifdef HAVE_ALBUMART | 383 | #ifdef HAVE_ALBUMART |
370 | if (track->aa_hid >= 0) { | 384 | { |
371 | if (bufclose(track->aa_hid)) | 385 | int i; |
372 | track->aa_hid = -1; | 386 | FOREACH_ALBUMART(i) |
373 | else | 387 | { |
374 | return false; | 388 | if (track->aa_hid[i] >= 0) { |
389 | if (bufclose(track->aa_hid[i])) | ||
390 | track->aa_hid[i] = -1; | ||
391 | else | ||
392 | return false; | ||
393 | } | ||
394 | } | ||
375 | } | 395 | } |
376 | #endif | 396 | #endif |
377 | 397 | ||
@@ -538,18 +558,6 @@ void audio_remove_encoder(void) | |||
538 | 558 | ||
539 | #endif /* HAVE_RECORDING */ | 559 | #endif /* HAVE_RECORDING */ |
540 | 560 | ||
541 | #ifdef HAVE_ALBUMART | ||
542 | int audio_current_aa_hid(void) | ||
543 | { | ||
544 | int cur_idx; | ||
545 | int offset = ci.new_track + wps_offset; | ||
546 | |||
547 | cur_idx = track_ridx + offset; | ||
548 | cur_idx &= MAX_TRACK_MASK; | ||
549 | |||
550 | return tracks[cur_idx].aa_hid; | ||
551 | } | ||
552 | #endif | ||
553 | 561 | ||
554 | struct mp3entry* audio_current_track(void) | 562 | struct mp3entry* audio_current_track(void) |
555 | { | 563 | { |
@@ -673,6 +681,58 @@ struct mp3entry* audio_next_track(void) | |||
673 | return NULL; | 681 | return NULL; |
674 | } | 682 | } |
675 | 683 | ||
684 | #ifdef HAVE_ALBUMART | ||
685 | int playback_current_aa_hid(int slot) | ||
686 | { | ||
687 | if (slot < 0) | ||
688 | return -1; | ||
689 | int cur_idx; | ||
690 | int offset = ci.new_track + wps_offset; | ||
691 | |||
692 | cur_idx = track_ridx + offset; | ||
693 | cur_idx &= MAX_TRACK_MASK; | ||
694 | |||
695 | return tracks[cur_idx].aa_hid[slot]; | ||
696 | } | ||
697 | |||
698 | int playback_claim_aa_slot(struct dim *dim) | ||
699 | { | ||
700 | int i; | ||
701 | /* first try to find a slot already having the size to reuse it | ||
702 | * since we don't want albumart of the same size buffered multiple times */ | ||
703 | FOREACH_ALBUMART(i) | ||
704 | { | ||
705 | struct albumart_slot *slot = &albumart_slots[i]; | ||
706 | if (slot->dim.width == dim->width | ||
707 | && slot->dim.height == dim->height) | ||
708 | { | ||
709 | slot->used++; | ||
710 | return i; | ||
711 | } | ||
712 | } | ||
713 | /* size is new, find a free slot */ | ||
714 | FOREACH_ALBUMART(i) | ||
715 | { | ||
716 | if (!albumart_slots[i].used) | ||
717 | { | ||
718 | albumart_slots[i].used++; | ||
719 | albumart_slots[i].dim = *dim; | ||
720 | return i; | ||
721 | } | ||
722 | } | ||
723 | /* sorry, no free slot */ | ||
724 | return -1; | ||
725 | } | ||
726 | |||
727 | void playback_release_aa_slot(int slot) | ||
728 | { | ||
729 | /* invalidate the albumart_slot */ | ||
730 | struct albumart_slot *aa_slot = &albumart_slots[slot]; | ||
731 | if (aa_slot->used > 0) | ||
732 | aa_slot->used--; | ||
733 | } | ||
734 | |||
735 | #endif | ||
676 | void audio_play(long offset) | 736 | void audio_play(long offset) |
677 | { | 737 | { |
678 | logf("audio_play"); | 738 | logf("audio_play"); |
@@ -1671,7 +1731,7 @@ static bool audio_loadcodec(bool start_play) | |||
1671 | 1731 | ||
1672 | codec_get_full_path(codec_path, codec_fn); | 1732 | codec_get_full_path(codec_path, codec_fn); |
1673 | 1733 | ||
1674 | tracks[track_widx].codec_hid = bufopen(codec_path, 0, TYPE_CODEC); | 1734 | tracks[track_widx].codec_hid = bufopen(codec_path, 0, TYPE_CODEC, NULL); |
1675 | if (tracks[track_widx].codec_hid < 0) | 1735 | if (tracks[track_widx].codec_hid < 0) |
1676 | return false; | 1736 | return false; |
1677 | 1737 | ||
@@ -1757,7 +1817,7 @@ static bool audio_load_track(size_t offset, bool start_play) | |||
1757 | /* Get track metadata if we don't already have it. */ | 1817 | /* Get track metadata if we don't already have it. */ |
1758 | if (tracks[track_widx].id3_hid < 0) | 1818 | if (tracks[track_widx].id3_hid < 0) |
1759 | { | 1819 | { |
1760 | tracks[track_widx].id3_hid = bufopen(trackname, 0, TYPE_ID3); | 1820 | tracks[track_widx].id3_hid = bufopen(trackname, 0, TYPE_ID3, NULL); |
1761 | 1821 | ||
1762 | if (tracks[track_widx].id3_hid < 0) | 1822 | if (tracks[track_widx].id3_hid < 0) |
1763 | { | 1823 | { |
@@ -1859,26 +1919,37 @@ static void audio_finish_load_track(void) | |||
1859 | } | 1919 | } |
1860 | } | 1920 | } |
1861 | #ifdef HAVE_ALBUMART | 1921 | #ifdef HAVE_ALBUMART |
1862 | if (tracks[track_widx].aa_hid < 0) | ||
1863 | { | 1922 | { |
1923 | int i; | ||
1864 | char aa_path[MAX_PATH]; | 1924 | char aa_path[MAX_PATH]; |
1865 | /* find_albumart will error out if the wps doesn't have AA */ | 1925 | FOREACH_ALBUMART(i) |
1866 | if (find_albumart(track_id3, aa_path, sizeof(aa_path))) | ||
1867 | { | 1926 | { |
1868 | tracks[track_widx].aa_hid = bufopen(aa_path, 0, TYPE_BITMAP); | 1927 | /* albumart_slots may change during a yield of bufopen, |
1869 | 1928 | * but that's no problem */ | |
1870 | if(tracks[track_widx].aa_hid == ERR_BUFFER_FULL) | 1929 | if (tracks[track_widx].aa_hid[i] >= 0 || !albumart_slots[i].used) |
1930 | continue; | ||
1931 | /* find_albumart will error out if the wps doesn't have AA */ | ||
1932 | if (find_albumart(track_id3, aa_path, sizeof(aa_path), | ||
1933 | &(albumart_slots[i].dim))) | ||
1871 | { | 1934 | { |
1872 | filling = STATE_FULL; | 1935 | int aa_hid = bufopen(aa_path, 0, TYPE_BITMAP, |
1873 | logf("buffer is full for now"); | 1936 | &(albumart_slots[i].dim)); |
1874 | return; /* No space for track's album art, not an error */ | 1937 | |
1875 | } | 1938 | if(aa_hid == ERR_BUFFER_FULL) |
1876 | else if (tracks[track_widx].aa_hid < 0) | 1939 | { |
1877 | { | 1940 | filling = STATE_FULL; |
1878 | /* another error, ignore AlbumArt */ | 1941 | logf("buffer is full for now"); |
1879 | logf("Album art loading failed"); | 1942 | return; /* No space for track's album art, not an error */ |
1943 | } | ||
1944 | else if (aa_hid < 0) | ||
1945 | { | ||
1946 | /* another error, ignore AlbumArt */ | ||
1947 | logf("Album art loading failed"); | ||
1948 | } | ||
1949 | tracks[track_widx].aa_hid[i] = aa_hid; | ||
1880 | } | 1950 | } |
1881 | } | 1951 | } |
1952 | |||
1882 | } | 1953 | } |
1883 | #endif | 1954 | #endif |
1884 | 1955 | ||
@@ -1954,7 +2025,8 @@ static void audio_finish_load_track(void) | |||
1954 | else | 2025 | else |
1955 | file_offset = 0; | 2026 | file_offset = 0; |
1956 | 2027 | ||
1957 | tracks[track_widx].audio_hid = bufopen(track_id3->path, file_offset, type); | 2028 | tracks[track_widx].audio_hid = bufopen(track_id3->path, file_offset, type, |
2029 | NULL); | ||
1958 | 2030 | ||
1959 | /* No space left, not an error */ | 2031 | /* No space left, not an error */ |
1960 | if (tracks[track_widx].audio_hid == ERR_BUFFER_FULL) | 2032 | if (tracks[track_widx].audio_hid == ERR_BUFFER_FULL) |
@@ -2558,7 +2630,6 @@ static void audio_thread(void) | |||
2558 | LOGFQUEUE("audio < Q_AUDIO_TRACK_CHANGED"); | 2630 | LOGFQUEUE("audio < Q_AUDIO_TRACK_CHANGED"); |
2559 | audio_finalise_track_change(); | 2631 | audio_finalise_track_change(); |
2560 | break; | 2632 | break; |
2561 | |||
2562 | #ifndef SIMULATOR | 2633 | #ifndef SIMULATOR |
2563 | case SYS_USB_CONNECTED: | 2634 | case SYS_USB_CONNECTED: |
2564 | LOGFQUEUE("audio < SYS_USB_CONNECTED"); | 2635 | LOGFQUEUE("audio < SYS_USB_CONNECTED"); |
@@ -2681,11 +2752,18 @@ void audio_init(void) | |||
2681 | tracks[i].audio_hid = -1; | 2752 | tracks[i].audio_hid = -1; |
2682 | tracks[i].id3_hid = -1; | 2753 | tracks[i].id3_hid = -1; |
2683 | tracks[i].codec_hid = -1; | 2754 | tracks[i].codec_hid = -1; |
2684 | #ifdef HAVE_ALBUMART | ||
2685 | tracks[i].aa_hid = -1; | ||
2686 | #endif | ||
2687 | tracks[i].cuesheet_hid = -1; | 2755 | tracks[i].cuesheet_hid = -1; |
2688 | } | 2756 | } |
2757 | #ifdef HAVE_ALBUMART | ||
2758 | FOREACH_ALBUMART(i) | ||
2759 | { | ||
2760 | int j; | ||
2761 | for (j = 0; j < MAX_TRACK; j++) | ||
2762 | { | ||
2763 | tracks[j].aa_hid[i] = -1; | ||
2764 | } | ||
2765 | } | ||
2766 | #endif | ||
2689 | 2767 | ||
2690 | add_event(BUFFER_EVENT_REBUFFER, false, buffering_handle_rebuffer_callback); | 2768 | add_event(BUFFER_EVENT_REBUFFER, false, buffering_handle_rebuffer_callback); |
2691 | add_event(BUFFER_EVENT_FINISHED, false, buffering_handle_finished_callback); | 2769 | add_event(BUFFER_EVENT_FINISHED, false, buffering_handle_finished_callback); |
diff --git a/apps/playback.h b/apps/playback.h index 378d5effec..add11e296b 100644 --- a/apps/playback.h +++ b/apps/playback.h | |||
@@ -25,6 +25,32 @@ | |||
25 | #include <stdbool.h> | 25 | #include <stdbool.h> |
26 | #include "config.h" | 26 | #include "config.h" |
27 | 27 | ||
28 | #ifdef HAVE_ALBUMART | ||
29 | |||
30 | #include "bmp.h" | ||
31 | /* | ||
32 | * Returns the handle id of the buffered albumart for the given slot id | ||
33 | **/ | ||
34 | int playback_current_aa_hid(int slot); | ||
35 | |||
36 | /* | ||
37 | * Hands out an albumart slot for buffering albumart using the size | ||
38 | * int the passed dim struct, it copies the data of dim in order to | ||
39 | * be safe to be reused for other code | ||
40 | * | ||
41 | * The slot may be reused if other code calls this with the same dimensions | ||
42 | * in dim, so if you change dim release and claim a new slot | ||
43 | * | ||
44 | * Save to call from other threads */ | ||
45 | int playback_claim_aa_slot(struct dim *dim); | ||
46 | |||
47 | /* | ||
48 | * Releases the albumart slot with given id | ||
49 | * | ||
50 | * Save to call from other threads */ | ||
51 | void playback_release_aa_slot(int slot); | ||
52 | #endif | ||
53 | |||
28 | /* Functions */ | 54 | /* Functions */ |
29 | const char *get_codec_filename(int cod_spec); | 55 | const char *get_codec_filename(int cod_spec); |
30 | void voice_wait(void); | 56 | void voice_wait(void); |
@@ -45,9 +71,6 @@ bool audio_restore_playback(int type); /* Restores the audio buffer to handle th | |||
45 | void codec_thread_do_callback(void (*fn)(void), | 71 | void codec_thread_do_callback(void (*fn)(void), |
46 | unsigned int *codec_thread_id); | 72 | unsigned int *codec_thread_id); |
47 | 73 | ||
48 | #ifdef HAVE_ALBUMART | ||
49 | int audio_current_aa_hid(void); | ||
50 | #endif | ||
51 | 74 | ||
52 | #if CONFIG_CODEC == SWCODEC /* This #ifdef is better here than gui/wps.c */ | 75 | #if CONFIG_CODEC == SWCODEC /* This #ifdef is better here than gui/wps.c */ |
53 | extern void audio_next_dir(void); | 76 | extern void audio_next_dir(void); |
diff --git a/apps/plugin.h b/apps/plugin.h index b060104373..41375a6adb 100644 --- a/apps/plugin.h +++ b/apps/plugin.h | |||
@@ -789,7 +789,8 @@ struct plugin_api { | |||
789 | 789 | ||
790 | #if (CONFIG_CODEC == SWCODEC) | 790 | #if (CONFIG_CODEC == SWCODEC) |
791 | /* buffering API */ | 791 | /* buffering API */ |
792 | int (*bufopen)(const char *file, size_t offset, enum data_type type); | 792 | int (*bufopen)(const char *file, size_t offset, enum data_type type, |
793 | void *user_data); | ||
793 | int (*bufalloc)(const void *src, size_t size, enum data_type type); | 794 | int (*bufalloc)(const void *src, size_t size, enum data_type type); |
794 | bool (*bufclose)(int handle_id); | 795 | bool (*bufclose)(int handle_id); |
795 | int (*bufseek)(int handle_id, size_t newpos); | 796 | int (*bufseek)(int handle_id, size_t newpos); |
diff --git a/apps/recorder/albumart.c b/apps/recorder/albumart.c index bb2fae4af7..b668bf4eba 100644 --- a/apps/recorder/albumart.c +++ b/apps/recorder/albumart.c | |||
@@ -274,22 +274,18 @@ bool search_albumart_files(const struct mp3entry *id3, const char *size_string, | |||
274 | /* Look for albumart bitmap in the same dir as the track and in its parent dir. | 274 | /* Look for albumart bitmap in the same dir as the track and in its parent dir. |
275 | * Stores the found filename in the buf parameter. | 275 | * Stores the found filename in the buf parameter. |
276 | * Returns true if a bitmap was found, false otherwise */ | 276 | * Returns true if a bitmap was found, false otherwise */ |
277 | bool find_albumart(const struct mp3entry *id3, char *buf, int buflen) | 277 | bool find_albumart(const struct mp3entry *id3, char *buf, int buflen, |
278 | struct dim *dim) | ||
278 | { | 279 | { |
279 | if (!id3 || !buf) | 280 | if (!id3 || !buf) |
280 | return false; | 281 | return false; |
281 | 282 | ||
282 | char size_string[9]; | 283 | char size_string[9]; |
283 | int width = 0, height = 0; | ||
284 | |||
285 | if (!wps_uses_albumart(&width, &height)) | ||
286 | return false; | ||
287 | |||
288 | logf("Looking for album art for %s", id3->path); | 284 | logf("Looking for album art for %s", id3->path); |
289 | 285 | ||
290 | /* Write the size string, e.g. ".100x100". */ | 286 | /* Write the size string, e.g. ".100x100". */ |
291 | snprintf(size_string, sizeof(size_string), ".%dx%d", | 287 | snprintf(size_string, sizeof(size_string), ".%dx%d", |
292 | width, height); | 288 | dim->width, dim->height); |
293 | 289 | ||
294 | /* First we look for a bitmap of the right size */ | 290 | /* First we look for a bitmap of the right size */ |
295 | if (search_albumart_files(id3, size_string, buf, buflen)) | 291 | if (search_albumart_files(id3, size_string, buf, buflen)) |
@@ -376,17 +372,4 @@ void draw_album_art(struct gui_wps *gwps, int handle_id, bool clear) | |||
376 | } | 372 | } |
377 | } | 373 | } |
378 | 374 | ||
379 | void get_albumart_size(struct bitmap *bmp) | ||
380 | { | ||
381 | /* FIXME: What should we do with albumart on remote? */ | ||
382 | int width, height; | ||
383 | |||
384 | if (!wps_uses_albumart(&width, &height)) | ||
385 | { | ||
386 | width = 0; height = 0; | ||
387 | } | ||
388 | |||
389 | bmp->width = width; | ||
390 | bmp->height = height; | ||
391 | } | ||
392 | #endif /* PLUGIN */ | 375 | #endif /* PLUGIN */ |
diff --git a/apps/recorder/albumart.h b/apps/recorder/albumart.h index d1c2dfa7bd..51f456d175 100644 --- a/apps/recorder/albumart.h +++ b/apps/recorder/albumart.h | |||
@@ -29,9 +29,11 @@ | |||
29 | #include "skin_engine/skin_engine.h" | 29 | #include "skin_engine/skin_engine.h" |
30 | 30 | ||
31 | /* Look for albumart bitmap in the same dir as the track and in its parent dir. | 31 | /* Look for albumart bitmap in the same dir as the track and in its parent dir. |
32 | * Calls size_func to get the dimensions to look for | ||
32 | * Stores the found filename in the buf parameter. | 33 | * Stores the found filename in the buf parameter. |
33 | * Returns true if a bitmap was found, false otherwise */ | 34 | * Returns true if a bitmap was found, false otherwise */ |
34 | bool find_albumart(const struct mp3entry *id3, char *buf, int buflen); | 35 | bool find_albumart(const struct mp3entry *id3, char *buf, int buflen, |
36 | struct dim *dim); | ||
35 | 37 | ||
36 | /* Draw the album art bitmap from the given handle ID onto the given WPS. | 38 | /* Draw the album art bitmap from the given handle ID onto the given WPS. |
37 | Call with clear = true to clear the bitmap instead of drawing it. */ | 39 | Call with clear = true to clear the bitmap instead of drawing it. */ |