diff options
author | Nicolas Pennequin <nicolas.pennequin@free.fr> | 2008-04-03 17:51:53 +0000 |
---|---|---|
committer | Nicolas Pennequin <nicolas.pennequin@free.fr> | 2008-04-03 17:51:53 +0000 |
commit | 33f522de8b36985401c1a17831b5ef8501039953 (patch) | |
tree | fe87d8b5e095f73fff04bbca133afe31d8787734 /apps | |
parent | 81efd6c36d7f424b1c8e6e36f799fe1a047d8f38 (diff) | |
download | rockbox-33f522de8b36985401c1a17831b5ef8501039953.tar.gz rockbox-33f522de8b36985401c1a17831b5ef8501039953.zip |
Migrate the buffering code to the new events system.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16950 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/buffering.c | 65 | ||||
-rw-r--r-- | apps/buffering.h | 21 | ||||
-rw-r--r-- | apps/playback.c | 69 |
3 files changed, 44 insertions, 111 deletions
diff --git a/apps/buffering.c b/apps/buffering.c index 6d4192443c..99a4a3b058 100644 --- a/apps/buffering.c +++ b/apps/buffering.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include "pcmbuf.h" | 49 | #include "pcmbuf.h" |
50 | #include "buffer.h" | 50 | #include "buffer.h" |
51 | #include "bmp.h" | 51 | #include "bmp.h" |
52 | #include "events.h" | ||
52 | 53 | ||
53 | #ifdef SIMULATOR | 54 | #ifdef SIMULATOR |
54 | #define ata_disk_is_active() 1 | 55 | #define ata_disk_is_active() 1 |
@@ -153,9 +154,6 @@ static struct mutex llist_mutex; | |||
153 | This is global so that move_handle and rm_handle can invalidate it. */ | 154 | This is global so that move_handle and rm_handle can invalidate it. */ |
154 | static struct memory_handle *cached_handle = NULL; | 155 | static struct memory_handle *cached_handle = NULL; |
155 | 156 | ||
156 | static buffering_callback buffering_callback_funcs[MAX_BUF_CALLBACKS]; | ||
157 | static int buffer_callback_count = 0; | ||
158 | |||
159 | static struct { | 157 | static struct { |
160 | size_t remaining; /* Amount of data needing to be buffered */ | 158 | size_t remaining; /* Amount of data needing to be buffered */ |
161 | size_t wasted; /* Amount of space available for freeing */ | 159 | size_t wasted; /* Amount of space available for freeing */ |
@@ -190,8 +188,6 @@ static struct event_queue buffering_queue; | |||
190 | static struct queue_sender_list buffering_queue_sender_list; | 188 | static struct queue_sender_list buffering_queue_sender_list; |
191 | 189 | ||
192 | 190 | ||
193 | static void call_buffering_callbacks(enum callback_event ev, int value); | ||
194 | |||
195 | 191 | ||
196 | /* | 192 | /* |
197 | LINKED LIST MANAGEMENT | 193 | LINKED LIST MANAGEMENT |
@@ -659,7 +655,7 @@ static bool buffer_handle(int handle_id) | |||
659 | /* finished buffering the file */ | 655 | /* finished buffering the file */ |
660 | close(h->fd); | 656 | close(h->fd); |
661 | h->fd = -1; | 657 | h->fd = -1; |
662 | call_buffering_callbacks(EVENT_HANDLE_FINISHED, h->id); | 658 | send_event(EVENT_HANDLE_FINISHED, &h->id); |
663 | } | 659 | } |
664 | 660 | ||
665 | return true; | 661 | return true; |
@@ -715,7 +711,7 @@ static void rebuffer_handle(int handle_id, size_t newpos) | |||
715 | /* There isn't enough space to rebuffer all of the track from its new | 711 | /* There isn't enough space to rebuffer all of the track from its new |
716 | offset, so we ask the user to free some */ | 712 | offset, so we ask the user to free some */ |
717 | DEBUGF("rebuffer_handle: space is needed\n"); | 713 | DEBUGF("rebuffer_handle: space is needed\n"); |
718 | call_buffering_callbacks(EVENT_HANDLE_REBUFFER, handle_id); | 714 | send_event(EVENT_HANDLE_REBUFFER, &handle_id); |
719 | } | 715 | } |
720 | 716 | ||
721 | /* Now we ask for a rebuffer */ | 717 | /* Now we ask for a rebuffer */ |
@@ -1269,52 +1265,6 @@ void buf_set_watermark(size_t bytes) | |||
1269 | queue_post(&buffering_queue, Q_SET_WATERMARK, bytes); | 1265 | queue_post(&buffering_queue, Q_SET_WATERMARK, bytes); |
1270 | } | 1266 | } |
1271 | 1267 | ||
1272 | bool register_buffering_callback(buffering_callback func) | ||
1273 | { | ||
1274 | int i; | ||
1275 | if (buffer_callback_count >= MAX_BUF_CALLBACKS) | ||
1276 | return false; | ||
1277 | for (i = 0; i < MAX_BUF_CALLBACKS; i++) | ||
1278 | { | ||
1279 | if (buffering_callback_funcs[i] == NULL) | ||
1280 | { | ||
1281 | buffering_callback_funcs[i] = func; | ||
1282 | buffer_callback_count++; | ||
1283 | return true; | ||
1284 | } | ||
1285 | else if (buffering_callback_funcs[i] == func) | ||
1286 | return true; | ||
1287 | } | ||
1288 | return false; | ||
1289 | } | ||
1290 | |||
1291 | void unregister_buffering_callback(buffering_callback func) | ||
1292 | { | ||
1293 | int i; | ||
1294 | for (i = 0; i < MAX_BUF_CALLBACKS; i++) | ||
1295 | { | ||
1296 | if (buffering_callback_funcs[i] == func) | ||
1297 | { | ||
1298 | buffering_callback_funcs[i] = NULL; | ||
1299 | buffer_callback_count--; | ||
1300 | } | ||
1301 | } | ||
1302 | return; | ||
1303 | } | ||
1304 | |||
1305 | static void call_buffering_callbacks(enum callback_event ev, int value) | ||
1306 | { | ||
1307 | logf("call_buffering_callbacks()"); | ||
1308 | int i; | ||
1309 | for (i = 0; i < MAX_BUF_CALLBACKS; i++) | ||
1310 | { | ||
1311 | if (buffering_callback_funcs[i]) | ||
1312 | { | ||
1313 | buffering_callback_funcs[i](ev, value); | ||
1314 | } | ||
1315 | } | ||
1316 | } | ||
1317 | |||
1318 | static void shrink_buffer_inner(struct memory_handle *h) | 1268 | static void shrink_buffer_inner(struct memory_handle *h) |
1319 | { | 1269 | { |
1320 | if (h == NULL) | 1270 | if (h == NULL) |
@@ -1350,7 +1300,7 @@ void buffering_thread(void) | |||
1350 | LOGFQUEUE("buffering < Q_START_FILL"); | 1300 | LOGFQUEUE("buffering < Q_START_FILL"); |
1351 | /* Call buffer callbacks here because this is one of two ways | 1301 | /* Call buffer callbacks here because this is one of two ways |
1352 | * to begin a full buffer fill */ | 1302 | * to begin a full buffer fill */ |
1353 | call_buffering_callbacks(EVENT_BUFFER_LOW, 0); | 1303 | send_event(EVENT_BUFFER_LOW, 0); |
1354 | shrink_buffer(); | 1304 | shrink_buffer(); |
1355 | queue_reply(&buffering_queue, 1); | 1305 | queue_reply(&buffering_queue, 1); |
1356 | filling |= buffer_handle((int)ev.data); | 1306 | filling |= buffer_handle((int)ev.data); |
@@ -1412,7 +1362,7 @@ void buffering_thread(void) | |||
1412 | 1362 | ||
1413 | /* If the buffer is low, call the callbacks to get new data */ | 1363 | /* If the buffer is low, call the callbacks to get new data */ |
1414 | if (num_handles > 0 && data_counters.useful <= conf_watermark) | 1364 | if (num_handles > 0 && data_counters.useful <= conf_watermark) |
1415 | call_buffering_callbacks(EVENT_BUFFER_LOW, 0); | 1365 | send_event(EVENT_BUFFER_LOW, 0); |
1416 | 1366 | ||
1417 | #if 0 | 1367 | #if 0 |
1418 | /* TODO: This needs to be fixed to use the idle callback, disable it | 1368 | /* TODO: This needs to be fixed to use the idle callback, disable it |
@@ -1422,7 +1372,7 @@ void buffering_thread(void) | |||
1422 | else if (ata_disk_is_active() && queue_empty(&buffering_queue)) | 1372 | else if (ata_disk_is_active() && queue_empty(&buffering_queue)) |
1423 | { | 1373 | { |
1424 | if (num_handles > 0 && data_counters.useful <= high_watermark) | 1374 | if (num_handles > 0 && data_counters.useful <= high_watermark) |
1425 | call_buffering_callbacks(EVENT_BUFFER_LOW, 0); | 1375 | send_event(EVENT_BUFFER_LOW, 0); |
1426 | 1376 | ||
1427 | if (data_counters.remaining > 0 && BUF_USED <= high_watermark) | 1377 | if (data_counters.remaining > 0 && BUF_USED <= high_watermark) |
1428 | { | 1378 | { |
@@ -1492,9 +1442,6 @@ bool buffering_reset(char *buf, size_t buflen) | |||
1492 | num_handles = 0; | 1442 | num_handles = 0; |
1493 | base_handle_id = -1; | 1443 | base_handle_id = -1; |
1494 | 1444 | ||
1495 | buffer_callback_count = 0; | ||
1496 | memset(buffering_callback_funcs, 0, sizeof(buffering_callback_funcs)); | ||
1497 | |||
1498 | /* Set the high watermark as 75% full...or 25% empty :) */ | 1445 | /* Set the high watermark as 75% full...or 25% empty :) */ |
1499 | #if MEM > 8 | 1446 | #if MEM > 8 |
1500 | high_watermark = 3*buflen / 4; | 1447 | high_watermark = 3*buflen / 4; |
diff --git a/apps/buffering.h b/apps/buffering.h index bc61ec5e6d..cd705cec25 100644 --- a/apps/buffering.h +++ b/apps/buffering.h | |||
@@ -22,6 +22,7 @@ | |||
22 | 22 | ||
23 | #include <sys/types.h> | 23 | #include <sys/types.h> |
24 | #include <stdbool.h> | 24 | #include <stdbool.h> |
25 | #include "events.h" | ||
25 | 26 | ||
26 | 27 | ||
27 | enum data_type { | 28 | enum data_type { |
@@ -36,8 +37,7 @@ enum data_type { | |||
36 | }; | 37 | }; |
37 | 38 | ||
38 | enum callback_event { | 39 | enum callback_event { |
39 | EVENT_DEFAULT, | 40 | EVENT_BUFFER_LOW = (EVENT_CLASS_BUFFERING|1), |
40 | EVENT_BUFFER_LOW, | ||
41 | EVENT_HANDLE_REBUFFER, | 41 | EVENT_HANDLE_REBUFFER, |
42 | EVENT_HANDLE_CLOSED, | 42 | EVENT_HANDLE_CLOSED, |
43 | EVENT_HANDLE_MOVED, | 43 | EVENT_HANDLE_MOVED, |
@@ -109,23 +109,6 @@ void buf_set_base_handle(int handle_id); | |||
109 | size_t buf_used(void); | 109 | size_t buf_used(void); |
110 | 110 | ||
111 | 111 | ||
112 | /*************************************************************************** | ||
113 | * CALLBACK UTILITIES | ||
114 | * ================== | ||
115 | * | ||
116 | * register_buffering_callback, unregister_buffering_callback: | ||
117 | * | ||
118 | * Register/Unregister callback functions that will get executed when the buffer | ||
119 | * goes below the low watermark. They are executed once, then forgotten. | ||
120 | * | ||
121 | * NOTE: The callbacks are called from the buffering thread, so don't make them | ||
122 | * do too much. Ideally they should just post an event to a queue and return. | ||
123 | ****************************************************************************/ | ||
124 | |||
125 | #define MAX_BUF_CALLBACKS 4 | ||
126 | typedef void (*buffering_callback)(enum callback_event ev, int value); | ||
127 | bool register_buffering_callback(buffering_callback func); | ||
128 | void unregister_buffering_callback(buffering_callback func); | ||
129 | 112 | ||
130 | /* Settings */ | 113 | /* Settings */ |
131 | enum { | 114 | enum { |
diff --git a/apps/playback.c b/apps/playback.c index 119e37a073..1101517aef 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include "codecs.h" | 41 | #include "codecs.h" |
42 | #include "audio.h" | 42 | #include "audio.h" |
43 | #include "buffering.h" | 43 | #include "buffering.h" |
44 | #include "events.h" | ||
44 | #include "voice_thread.h" | 45 | #include "voice_thread.h" |
45 | #include "mp3_playback.h" | 46 | #include "mp3_playback.h" |
46 | #include "usb.h" | 47 | #include "usb.h" |
@@ -1386,6 +1387,34 @@ static void codec_thread(void) | |||
1386 | } | 1387 | } |
1387 | 1388 | ||
1388 | 1389 | ||
1390 | /* --- Buffering callbacks --- */ | ||
1391 | |||
1392 | static void buffering_low_buffer_callback(void *data) | ||
1393 | { | ||
1394 | (void)data; | ||
1395 | logf("low buffer callback"); | ||
1396 | |||
1397 | if (filling == STATE_FULL) { | ||
1398 | /* force a refill */ | ||
1399 | LOGFQUEUE("buffering > audio Q_AUDIO_FILL_BUFFER"); | ||
1400 | queue_post(&audio_queue, Q_AUDIO_FILL_BUFFER, 0); | ||
1401 | } | ||
1402 | } | ||
1403 | |||
1404 | static void buffering_handle_rebuffer_callback(void *data) | ||
1405 | { | ||
1406 | (void)data; | ||
1407 | LOGFQUEUE("audio >| audio Q_AUDIO_FLUSH"); | ||
1408 | queue_post(&audio_queue, Q_AUDIO_FLUSH, 0); | ||
1409 | } | ||
1410 | |||
1411 | static void buffering_handle_finished_callback(int *data) | ||
1412 | { | ||
1413 | logf("handle %d finished buffering", *data); | ||
1414 | strip_tags(*data); | ||
1415 | } | ||
1416 | |||
1417 | |||
1389 | /* --- Audio thread --- */ | 1418 | /* --- Audio thread --- */ |
1390 | 1419 | ||
1391 | static bool audio_have_tracks(void) | 1420 | static bool audio_have_tracks(void) |
@@ -1433,36 +1462,6 @@ static void audio_update_trackinfo(void) | |||
1433 | ci.taginfo_ready = &CUR_TI->taginfo_ready; | 1462 | ci.taginfo_ready = &CUR_TI->taginfo_ready; |
1434 | } | 1463 | } |
1435 | 1464 | ||
1436 | static void buffering_audio_callback(enum callback_event ev, int value) | ||
1437 | { | ||
1438 | (void)value; | ||
1439 | logf("buffering_audio_callback"); | ||
1440 | |||
1441 | switch (ev) | ||
1442 | { | ||
1443 | case EVENT_BUFFER_LOW: | ||
1444 | if (filling == STATE_FULL) { | ||
1445 | /* force a refill */ | ||
1446 | LOGFQUEUE("buffering > audio Q_AUDIO_FILL_BUFFER"); | ||
1447 | queue_post(&audio_queue, Q_AUDIO_FILL_BUFFER, 0); | ||
1448 | } | ||
1449 | break; | ||
1450 | |||
1451 | case EVENT_HANDLE_REBUFFER: | ||
1452 | LOGFQUEUE("audio >| audio Q_AUDIO_FLUSH"); | ||
1453 | queue_post(&audio_queue, Q_AUDIO_FLUSH, 0); | ||
1454 | break; | ||
1455 | |||
1456 | case EVENT_HANDLE_FINISHED: | ||
1457 | logf("handle %d finished buffering", value); | ||
1458 | strip_tags(value); | ||
1459 | break; | ||
1460 | |||
1461 | default: | ||
1462 | break; | ||
1463 | } | ||
1464 | } | ||
1465 | |||
1466 | /* Clear tracks between write and read, non inclusive */ | 1465 | /* Clear tracks between write and read, non inclusive */ |
1467 | static void audio_clear_track_entries(void) | 1466 | static void audio_clear_track_entries(void) |
1468 | { | 1467 | { |
@@ -2062,6 +2061,8 @@ static void audio_stop_playback(void) | |||
2062 | /* TODO: Create auto bookmark too? */ | 2061 | /* TODO: Create auto bookmark too? */ |
2063 | 2062 | ||
2064 | prev_track_elapsed = curtrack_id3.elapsed; | 2063 | prev_track_elapsed = curtrack_id3.elapsed; |
2064 | |||
2065 | remove_event(EVENT_BUFFER_LOW, buffering_low_buffer_callback); | ||
2065 | } | 2066 | } |
2066 | 2067 | ||
2067 | paused = false; | 2068 | paused = false; |
@@ -2076,8 +2077,6 @@ static void audio_stop_playback(void) | |||
2076 | /* Close all tracks */ | 2077 | /* Close all tracks */ |
2077 | audio_release_tracks(); | 2078 | audio_release_tracks(); |
2078 | 2079 | ||
2079 | unregister_buffering_callback(buffering_audio_callback); | ||
2080 | |||
2081 | memset(&curtrack_id3, 0, sizeof(struct mp3entry)); | 2080 | memset(&curtrack_id3, 0, sizeof(struct mp3entry)); |
2082 | } | 2081 | } |
2083 | 2082 | ||
@@ -2121,7 +2120,8 @@ static void audio_play_start(size_t offset) | |||
2121 | #endif | 2120 | #endif |
2122 | 2121 | ||
2123 | audio_fill_file_buffer(true, offset); | 2122 | audio_fill_file_buffer(true, offset); |
2124 | register_buffering_callback(buffering_audio_callback); | 2123 | |
2124 | add_event(EVENT_BUFFER_LOW, false, buffering_low_buffer_callback); | ||
2125 | 2125 | ||
2126 | LOGFQUEUE("audio > audio Q_AUDIO_TRACK_CHANGED"); | 2126 | LOGFQUEUE("audio > audio Q_AUDIO_TRACK_CHANGED"); |
2127 | queue_post(&audio_queue, Q_AUDIO_TRACK_CHANGED, 0); | 2127 | queue_post(&audio_queue, Q_AUDIO_TRACK_CHANGED, 0); |
@@ -2512,6 +2512,9 @@ void audio_init(void) | |||
2512 | #endif | 2512 | #endif |
2513 | } | 2513 | } |
2514 | 2514 | ||
2515 | add_event(EVENT_HANDLE_REBUFFER, false, buffering_handle_rebuffer_callback); | ||
2516 | add_event(EVENT_HANDLE_FINISHED, false, buffering_handle_finished_callback); | ||
2517 | |||
2515 | /* Probably safe to say */ | 2518 | /* Probably safe to say */ |
2516 | audio_is_initialized = true; | 2519 | audio_is_initialized = true; |
2517 | 2520 | ||