summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2009-10-16 19:14:41 +0000
committerThomas Martitz <kugel@rockbox.org>2009-10-16 19:14:41 +0000
commite9c10189e93fe53cff74ae8fa15d19b1c522d5e4 (patch)
treee3c39a41ff160194dfd9ce617893e0367a6fdcc8
parenta72ffe7bb533302dbf4e6c7c4f1e4bd4078d3ed6 (diff)
downloadrockbox-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.c20
-rw-r--r--apps/buffering.h3
-rw-r--r--apps/gui/skin_engine/skin_display.c6
-rw-r--r--apps/gui/skin_engine/skin_parser.c21
-rw-r--r--apps/gui/skin_engine/skin_tokens.c5
-rw-r--r--apps/gui/skin_engine/wps_internals.h1
-rw-r--r--apps/gui/wps.c22
-rw-r--r--apps/gui/wps.h10
-rw-r--r--apps/playback.c156
-rw-r--r--apps/playback.h29
-rw-r--r--apps/plugin.h3
-rw-r--r--apps/recorder/albumart.c23
-rw-r--r--apps/recorder/albumart.h4
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). */
846static int load_image(int fd, const char *path) 847static 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*/
903int bufopen(const char *file, size_t offset, enum data_type type) 908int 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
77int bufopen(const char *file, size_t offset, enum data_type type); 77int bufopen(const char *file, size_t offset, enum data_type type,
78 void *user_data);
78int bufalloc(const void *src, size_t size, enum data_type type); 79int bufalloc(const void *src, size_t size, enum data_type type);
79bool bufclose(int handle_id); 80bool bufclose(int handle_id);
80int bufseek(int handle_id, size_t newpos); 81int 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
1281void gui_sync_wps_init(void) 1282void 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
1308bool 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
1329int wps_get_ff_rewind_count(void) 1311int 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
39bool is_wps_fading(void); 39bool 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 */
48bool 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 */
53int wps_get_ff_rewind_count(void); 43int 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
224struct 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
218static struct track_info tracks[MAX_TRACK]; 232static struct track_info tracks[MAX_TRACK];
219static volatile int track_ridx = 0; /* Track being decoded (A/C-) */ 233static volatile int track_ridx = 0; /* Track being decoded (A/C-) */
220static int track_widx = 0; /* Track being buffered (A) */ 234static 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
542int 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
554struct mp3entry* audio_current_track(void) 562struct 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
685int 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
698int 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
727void 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
676void audio_play(long offset) 736void 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 **/
34int 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 */
45int 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 */
51void playback_release_aa_slot(int slot);
52#endif
53
28/* Functions */ 54/* Functions */
29const char *get_codec_filename(int cod_spec); 55const char *get_codec_filename(int cod_spec);
30void voice_wait(void); 56void voice_wait(void);
@@ -45,9 +71,6 @@ bool audio_restore_playback(int type); /* Restores the audio buffer to handle th
45void codec_thread_do_callback(void (*fn)(void), 71void 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
49int 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 */
53extern void audio_next_dir(void); 76extern 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 */
277bool find_albumart(const struct mp3entry *id3, char *buf, int buflen) 277bool 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
379void 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 */
34bool find_albumart(const struct mp3entry *id3, char *buf, int buflen); 35bool 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. */