diff options
Diffstat (limited to 'apps/playback.c')
-rw-r--r-- | apps/playback.c | 156 |
1 files changed, 117 insertions, 39 deletions
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); |