summaryrefslogtreecommitdiff
path: root/apps/playback.c
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2008-03-07 22:56:51 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2008-03-07 22:56:51 +0000
commit2ccdc48ee943f1506809e94df990873cb937bd1a (patch)
tree1b365168ad24fc74c935a4eeaefcdf30f793c854 /apps/playback.c
parentaafa321d31c0dab631a5e0a70a0d8798368169f4 (diff)
downloadrockbox-2ccdc48ee943f1506809e94df990873cb937bd1a.tar.gz
rockbox-2ccdc48ee943f1506809e94df990873cb937bd1a.zip
Rewritten playback event handling. Should fix runtime statistics gathering.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16546 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/playback.c')
-rw-r--r--apps/playback.c117
1 files changed, 57 insertions, 60 deletions
diff --git a/apps/playback.c b/apps/playback.c
index f757f4ae08..f66fd2954a 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -210,8 +210,6 @@ struct track_info {
210 size_t filesize; /* File total length */ 210 size_t filesize; /* File total length */
211 211
212 bool taginfo_ready; /* Is metadata read */ 212 bool taginfo_ready; /* Is metadata read */
213
214 bool event_sent; /* Was this track's buffered event sent */
215}; 213};
216 214
217static struct track_info tracks[MAX_TRACK]; 215static struct track_info tracks[MAX_TRACK];
@@ -247,13 +245,12 @@ static bool skipped_during_pause = false; /* Do we need to clear the PCM buffer
247 */ 245 */
248static bool codec_requested_stop = false; 246static bool codec_requested_stop = false;
249 247
250/* Callbacks which applications or plugins may set */ 248struct playback_event {
251/* When the playing track has changed from the user's perspective */ 249 enum PLAYBACK_EVENT_TYPE type;
252void (*track_changed_callback)(struct mp3entry *id3) = NULL; 250 void (*callback)(void *data);
253/* When a track has been buffered */ 251};
254void (*track_buffer_callback)(struct mp3entry *id3) = NULL; 252
255/* When a track's buffer has been overwritten or cleared */ 253struct playback_event events[PLAYBACK_MAX_EVENTS];
256void (*track_unbuffer_callback)(struct mp3entry *id3) = NULL;
257 254
258static size_t buffer_margin = 0; /* Buffer margin aka anti-skip buffer (A/C-) */ 255static size_t buffer_margin = 0; /* Buffer margin aka anti-skip buffer (A/C-) */
259 256
@@ -352,11 +349,6 @@ static bool clear_track_info(struct track_info *track)
352 } 349 }
353 350
354 if (track->id3_hid >= 0) { 351 if (track->id3_hid >= 0) {
355 if (track->event_sent && track_unbuffer_callback) {
356 /* If there is an unbuffer callback, call it */
357 track_unbuffer_callback(bufgetid3(track->id3_hid));
358 }
359
360 if (bufclose(track->id3_hid)) 352 if (bufclose(track->id3_hid))
361 track->id3_hid = -1; 353 track->id3_hid = -1;
362 else 354 else
@@ -381,7 +373,6 @@ static bool clear_track_info(struct track_info *track)
381 373
382 track->filesize = 0; 374 track->filesize = 0;
383 track->taginfo_ready = false; 375 track->taginfo_ready = false;
384 track->event_sent = false;
385 376
386 return true; 377 return true;
387} 378}
@@ -1456,6 +1447,51 @@ static void codec_thread(void)
1456 1447
1457/* --- Audio thread --- */ 1448/* --- Audio thread --- */
1458 1449
1450void playback_add_event(enum PLAYBACK_EVENT_TYPE type, void (*handler))
1451{
1452 int i;
1453
1454 /* Try to find a free slot. */
1455 for (i = 0; i < PLAYBACK_MAX_EVENTS; i++)
1456 {
1457 if (events[i].callback == NULL)
1458 {
1459 events[i].type = type;
1460 events[i].callback = handler;
1461 return;
1462 }
1463 }
1464
1465 panicf("playback event line full");
1466}
1467
1468void playback_remove_event(enum PLAYBACK_EVENT_TYPE type, void (*handler))
1469{
1470 int i;
1471
1472 for (i = 0; i < PLAYBACK_MAX_EVENTS; i++)
1473 {
1474 if (events[i].type == type && events[i].callback == handler)
1475 {
1476 events[i].callback = NULL;
1477 return;
1478 }
1479 }
1480
1481 panicf("playback event not found");
1482}
1483
1484static void send_event(enum PLAYBACK_EVENT_TYPE type, void *data)
1485{
1486 int i;
1487
1488 for (i = 0; i < PLAYBACK_MAX_EVENTS; i++)
1489 {
1490 if (events[i].type == type && events[i].callback != NULL)
1491 events[i].callback(data);
1492 }
1493}
1494
1459static bool audio_have_tracks(void) 1495static bool audio_have_tracks(void)
1460{ 1496{
1461 return (audio_track_count() != 0); 1497 return (audio_track_count() != 0);
@@ -1546,7 +1582,7 @@ static void audio_clear_track_entries(bool clear_unbuffered)
1546 1582
1547 /* If the track is buffered, conditionally clear/notify, 1583 /* If the track is buffered, conditionally clear/notify,
1548 * otherwise clear the track if that option is selected */ 1584 * otherwise clear the track if that option is selected */
1549 if (tracks[cur_idx].event_sent || clear_unbuffered) 1585 if (clear_unbuffered)
1550 clear_track_info(&tracks[cur_idx]); 1586 clear_track_info(&tracks[cur_idx]);
1551 } 1587 }
1552} 1588}
@@ -1750,8 +1786,7 @@ static bool audio_load_track(int offset, bool start_play)
1750 { 1786 {
1751 if (get_metadata(&id3, fd, trackname)) 1787 if (get_metadata(&id3, fd, trackname))
1752 { 1788 {
1753 if (track_buffer_callback) 1789 send_event(PLAYBACK_EVENT_TRACK_BUFFER, &id3);
1754 track_buffer_callback(&id3);
1755 1790
1756 tracks[track_widx].id3_hid = 1791 tracks[track_widx].id3_hid =
1757 bufalloc(&id3, sizeof(struct mp3entry), TYPE_ID3); 1792 bufalloc(&id3, sizeof(struct mp3entry), TYPE_ID3);
@@ -1910,30 +1945,6 @@ static bool audio_load_track(int offset, bool start_play)
1910 return true; 1945 return true;
1911} 1946}
1912 1947
1913/* Send callback events to notify about new tracks. */
1914static void audio_generate_postbuffer_events(void)
1915{
1916 int cur_idx;
1917
1918 logf("Postbuffer:%d/%d",track_ridx,track_widx);
1919
1920 if (audio_have_tracks())
1921 {
1922 cur_idx = track_ridx;
1923
1924 while (1) {
1925 if (!tracks[cur_idx].event_sent)
1926 {
1927 /* Mark the event 'sent' even if we don't really send one */
1928 tracks[cur_idx].event_sent = true;
1929 }
1930 if (cur_idx == track_widx)
1931 break;
1932 cur_idx = (cur_idx + 1) & MAX_TRACK_MASK;
1933 }
1934 }
1935}
1936
1937static void audio_fill_file_buffer(bool start_play, size_t offset) 1948static void audio_fill_file_buffer(bool start_play, size_t offset)
1938{ 1949{
1939 struct queue_event ev; 1950 struct queue_event ev;
@@ -1978,7 +1989,6 @@ static void audio_fill_file_buffer(bool start_play, size_t offset)
1978 if (!had_next_track && audio_next_track()) 1989 if (!had_next_track && audio_next_track())
1979 track_changed = true; 1990 track_changed = true;
1980 1991
1981 audio_generate_postbuffer_events();
1982} 1992}
1983 1993
1984static void audio_rebuffer(void) 1994static void audio_rebuffer(void)
@@ -2012,6 +2022,9 @@ static int audio_check_new_track(void)
2012 bool forward; 2022 bool forward;
2013 bool end_of_playlist; /* Temporary flag, not the same as playlist_end */ 2023 bool end_of_playlist; /* Temporary flag, not the same as playlist_end */
2014 2024
2025 /* Now it's good time to send track unbuffer events. */
2026 send_event(PLAYBACK_EVENT_TRACK_FINISH, &curtrack_id3);
2027
2015 if (dir_skip) 2028 if (dir_skip)
2016 { 2029 {
2017 dir_skip = false; 2030 dir_skip = false;
@@ -2173,21 +2186,6 @@ skip_done:
2173 return Q_CODEC_REQUEST_COMPLETE; 2186 return Q_CODEC_REQUEST_COMPLETE;
2174} 2187}
2175 2188
2176void audio_set_track_buffer_event(void (*handler)(struct mp3entry *id3))
2177{
2178 track_buffer_callback = handler;
2179}
2180
2181void audio_set_track_unbuffer_event(void (*handler)(struct mp3entry *id3))
2182{
2183 track_unbuffer_callback = handler;
2184}
2185
2186void audio_set_track_changed_event(void (*handler)(struct mp3entry *id3))
2187{
2188 track_changed_callback = handler;
2189}
2190
2191unsigned long audio_prev_elapsed(void) 2189unsigned long audio_prev_elapsed(void)
2192{ 2190{
2193 return prev_track_elapsed; 2191 return prev_track_elapsed;
@@ -2404,8 +2402,7 @@ static void audio_finalise_track_change(void)
2404 bufgetid3(prev_ti->id3_hid)->elapsed = 0; 2402 bufgetid3(prev_ti->id3_hid)->elapsed = 0;
2405 } 2403 }
2406 2404
2407 if (track_changed_callback) 2405 send_event(PLAYBACK_EVENT_TRACK_CHANGE, &curtrack_id3);
2408 track_changed_callback(&curtrack_id3);
2409 2406
2410 track_changed = true; 2407 track_changed = true;
2411 playlist_update_resume_info(audio_current_track()); 2408 playlist_update_resume_info(audio_current_track());