diff options
author | Linus Nielsen Feltzing <linus@haxx.se> | 2002-10-14 14:13:13 +0000 |
---|---|---|
committer | Linus Nielsen Feltzing <linus@haxx.se> | 2002-10-14 14:13:13 +0000 |
commit | 402502fc6f11c3cb6e224e90ecfb30d5a5147a63 (patch) | |
tree | bd9a8dd5514201cff57ab87c2ed6006fcea029aa /firmware/mpeg.c | |
parent | 2f8f1c7dcf246c229b0271de78daef4d21764d10 (diff) | |
download | rockbox-402502fc6f11c3cb6e224e90ecfb30d5a5147a63.tar.gz rockbox-402502fc6f11c3cb6e224e90ecfb30d5a5147a63.zip |
Swapping is now done without the MPEG_SWAP message. Added some debugging functionality
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2623 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/mpeg.c')
-rw-r--r-- | firmware/mpeg.c | 185 |
1 files changed, 107 insertions, 78 deletions
diff --git a/firmware/mpeg.c b/firmware/mpeg.c index f149814dac..d7e7acbf92 100644 --- a/firmware/mpeg.c +++ b/firmware/mpeg.c | |||
@@ -37,11 +37,15 @@ | |||
37 | 37 | ||
38 | extern void bitswap(unsigned char *data, int length); | 38 | extern void bitswap(unsigned char *data, int length); |
39 | 39 | ||
40 | #define MPEG_CHUNKSIZE 0x180000 | 40 | static int get_unplayed_space(void); |
41 | #define MPEG_SWAP_CHUNKSIZE 0x8000 | 41 | static int get_unswapped_space(void); |
42 | #define MPEG_HIGH_WATER 2 | 42 | |
43 | #define MPEG_SWAP_CHUNKSIZE 0x2000 | ||
44 | #define MPEG_HIGH_WATER 2 /* We leave 2 bytes empty because otherwise we | ||
45 | wouldn't be able to see the difference between | ||
46 | an empty buffer and a full one. */ | ||
43 | #define MPEG_LOW_WATER 0x40000 | 47 | #define MPEG_LOW_WATER 0x40000 |
44 | #define MPEG_LOW_WATER_CHUNKSIZE 0x10000 | 48 | #define MPEG_LOW_WATER_CHUNKSIZE 0x40000 |
45 | 49 | ||
46 | #define MPEG_PLAY 1 | 50 | #define MPEG_PLAY 1 |
47 | #define MPEG_STOP 2 | 51 | #define MPEG_STOP 2 |
@@ -52,8 +56,7 @@ extern void bitswap(unsigned char *data, int length); | |||
52 | #define MPEG_FF_REWIND 7 | 56 | #define MPEG_FF_REWIND 7 |
53 | #define MPEG_FLUSH_RELOAD 8 | 57 | #define MPEG_FLUSH_RELOAD 8 |
54 | #define MPEG_NEED_DATA 100 | 58 | #define MPEG_NEED_DATA 100 |
55 | #define MPEG_SWAP_DATA 101 | 59 | #define MPEG_TRACK_CHANGE 101 |
56 | #define MPEG_TRACK_CHANGE 102 | ||
57 | 60 | ||
58 | extern char* playlist_peek(int steps); | 61 | extern char* playlist_peek(int steps); |
59 | extern int playlist_next(int steps); | 62 | extern int playlist_next(int steps); |
@@ -439,6 +442,26 @@ static bool dma_underrun; /* True when the DMA has stopped because of | |||
439 | 442 | ||
440 | static int mpeg_file; | 443 | static int mpeg_file; |
441 | 444 | ||
445 | void mpeg_get_debugdata(struct mpeg_debug *dbgdata) | ||
446 | { | ||
447 | dbgdata->mp3buflen = mp3buflen; | ||
448 | dbgdata->mp3buf_write = mp3buf_write; | ||
449 | dbgdata->mp3buf_swapwrite = mp3buf_swapwrite; | ||
450 | dbgdata->mp3buf_read = mp3buf_read; | ||
451 | |||
452 | dbgdata->last_dma_chunk_size = last_dma_chunk_size; | ||
453 | |||
454 | dbgdata->dma_on = dma_on; | ||
455 | dbgdata->playing = playing; | ||
456 | dbgdata->play_pending = play_pending; | ||
457 | dbgdata->is_playing = is_playing; | ||
458 | dbgdata->filling = filling; | ||
459 | dbgdata->dma_underrun = dma_underrun; | ||
460 | |||
461 | dbgdata->unplayed_space = get_unplayed_space(); | ||
462 | dbgdata->unswapped_space = get_unswapped_space(); | ||
463 | } | ||
464 | |||
442 | static void mas_poll_start(int interval_in_ms) | 465 | static void mas_poll_start(int interval_in_ms) |
443 | { | 466 | { |
444 | unsigned int count; | 467 | unsigned int count; |
@@ -480,8 +503,8 @@ static void dbg_timer_start(void) | |||
480 | TSNC &= ~0x04; /* No synchronization */ | 503 | TSNC &= ~0x04; /* No synchronization */ |
481 | TMDR &= ~0x44; /* Operate normally */ | 504 | TMDR &= ~0x44; /* Operate normally */ |
482 | 505 | ||
483 | TCNT1 = 0; /* Start counting at 0 */ | 506 | TCNT2 = 0; /* Start counting at 0 */ |
484 | TCR1 = 0x03; /* Sysclock/8 */ | 507 | TCR2 = 0x03; /* Sysclock/8 */ |
485 | 508 | ||
486 | TSTR |= 0x04; /* Start timer 2 */ | 509 | TSTR |= 0x04; /* Start timer 2 */ |
487 | } | 510 | } |
@@ -492,7 +515,7 @@ static int dbg_cnt2us(unsigned int cnt) | |||
492 | } | 515 | } |
493 | #endif | 516 | #endif |
494 | 517 | ||
495 | int get_unplayed_space(void) | 518 | static int get_unplayed_space(void) |
496 | { | 519 | { |
497 | int space = mp3buf_write - mp3buf_read; | 520 | int space = mp3buf_write - mp3buf_read; |
498 | if (space < 0) | 521 | if (space < 0) |
@@ -815,6 +838,65 @@ void hexdump(unsigned char *buf, int len) | |||
815 | } | 838 | } |
816 | #endif | 839 | #endif |
817 | 840 | ||
841 | static void swap_one_chunk(void) | ||
842 | { | ||
843 | int free_space_left; | ||
844 | int amount_to_swap; | ||
845 | int t1, t2; | ||
846 | |||
847 | free_space_left = get_unswapped_space(); | ||
848 | |||
849 | if(free_space_left == 0 && !play_pending) | ||
850 | return; | ||
851 | |||
852 | amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left); | ||
853 | if(mp3buf_write < mp3buf_swapwrite) | ||
854 | amount_to_swap = MIN(mp3buflen - mp3buf_swapwrite, | ||
855 | amount_to_swap); | ||
856 | else | ||
857 | amount_to_swap = MIN(mp3buf_write - mp3buf_swapwrite, | ||
858 | amount_to_swap); | ||
859 | |||
860 | DEBUGF("B %x\n", amount_to_swap); | ||
861 | t1 = current_tick; | ||
862 | bitswap(mp3buf + mp3buf_swapwrite, amount_to_swap); | ||
863 | t2 = current_tick; | ||
864 | DEBUGF("time: %d\n", t2 - t1); | ||
865 | |||
866 | mp3buf_swapwrite += amount_to_swap; | ||
867 | if(mp3buf_swapwrite >= mp3buflen) | ||
868 | { | ||
869 | mp3buf_swapwrite = 0; | ||
870 | DEBUGF("BW\n"); | ||
871 | } | ||
872 | |||
873 | /* And while we're at it, see if we have started | ||
874 | playing yet. If not, do it. */ | ||
875 | if(play_pending || dma_underrun) | ||
876 | { | ||
877 | /* If the filling has stopped, and we still haven't reached | ||
878 | the watermark, the file must be smaller than the | ||
879 | watermark. We must still play it. */ | ||
880 | if(((mp3buf_swapwrite - mp3buf_read) >= MPEG_LOW_WATER) || | ||
881 | !filling) | ||
882 | { | ||
883 | DEBUGF("P\n"); | ||
884 | play_pending = false; | ||
885 | playing = true; | ||
886 | |||
887 | init_dma(); | ||
888 | if (!paused) | ||
889 | { | ||
890 | last_dma_tick = current_tick; | ||
891 | start_dma(); | ||
892 | } | ||
893 | |||
894 | /* Tell ourselves that we need more data */ | ||
895 | queue_post(&mpeg_queue, MPEG_NEED_DATA, 0); | ||
896 | } | ||
897 | } | ||
898 | } | ||
899 | |||
818 | static void mpeg_thread(void) | 900 | static void mpeg_thread(void) |
819 | { | 901 | { |
820 | static int pause_tick = 0; | 902 | static int pause_tick = 0; |
@@ -824,7 +906,6 @@ static void mpeg_thread(void) | |||
824 | int free_space_left; | 906 | int free_space_left; |
825 | int unplayed_space_left; | 907 | int unplayed_space_left; |
826 | int amount_to_read; | 908 | int amount_to_read; |
827 | int amount_to_swap; | ||
828 | int t1, t2; | 909 | int t1, t2; |
829 | int start_offset; | 910 | int start_offset; |
830 | 911 | ||
@@ -838,7 +919,18 @@ static void mpeg_thread(void) | |||
838 | DEBUGF("S R:%x W:%x SW:%x\n", | 919 | DEBUGF("S R:%x W:%x SW:%x\n", |
839 | mp3buf_read, mp3buf_write, mp3buf_swapwrite); | 920 | mp3buf_read, mp3buf_write, mp3buf_swapwrite); |
840 | yield(); | 921 | yield(); |
841 | queue_wait(&mpeg_queue, &ev); | 922 | |
923 | /* Swap if necessary, and don't block on the queue_wait() */ | ||
924 | if(get_unswapped_space()) | ||
925 | { | ||
926 | swap_one_chunk(); | ||
927 | queue_wait_w_tmo(&mpeg_queue, &ev, 0); | ||
928 | } | ||
929 | else | ||
930 | { | ||
931 | queue_wait(&mpeg_queue, &ev); | ||
932 | } | ||
933 | |||
842 | switch(ev.id) | 934 | switch(ev.id) |
843 | { | 935 | { |
844 | case MPEG_PLAY: | 936 | case MPEG_PLAY: |
@@ -1221,64 +1313,6 @@ static void mpeg_thread(void) | |||
1221 | break; | 1313 | break; |
1222 | } | 1314 | } |
1223 | 1315 | ||
1224 | case MPEG_SWAP_DATA: | ||
1225 | free_space_left = get_unswapped_space(); | ||
1226 | |||
1227 | if(free_space_left == 0 && !play_pending) | ||
1228 | break; | ||
1229 | |||
1230 | amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left); | ||
1231 | if(mp3buf_write < mp3buf_swapwrite) | ||
1232 | amount_to_swap = MIN(mp3buflen - mp3buf_swapwrite, | ||
1233 | amount_to_swap); | ||
1234 | else | ||
1235 | amount_to_swap = MIN(mp3buf_write - mp3buf_swapwrite, | ||
1236 | amount_to_swap); | ||
1237 | |||
1238 | DEBUGF("B %x\n", amount_to_swap); | ||
1239 | t1 = current_tick; | ||
1240 | bitswap(mp3buf + mp3buf_swapwrite, amount_to_swap); | ||
1241 | t2 = current_tick; | ||
1242 | DEBUGF("time: %d\n", t2 - t1); | ||
1243 | |||
1244 | mp3buf_swapwrite += amount_to_swap; | ||
1245 | if(mp3buf_swapwrite >= mp3buflen) | ||
1246 | { | ||
1247 | mp3buf_swapwrite = 0; | ||
1248 | DEBUGF("BW\n"); | ||
1249 | } | ||
1250 | |||
1251 | /* Tell ourselves that we must swap more data */ | ||
1252 | queue_post(&mpeg_queue, MPEG_SWAP_DATA, 0); | ||
1253 | |||
1254 | /* And while we're at it, see if we have started | ||
1255 | playing yet. If not, do it. */ | ||
1256 | if(play_pending || dma_underrun) | ||
1257 | { | ||
1258 | /* If the filling has stopped, and we still haven't reached | ||
1259 | the watermark, the file must be smaller than the | ||
1260 | watermark. We must still play it. */ | ||
1261 | if(((mp3buf_swapwrite - mp3buf_read) >= MPEG_LOW_WATER) || | ||
1262 | !filling) | ||
1263 | { | ||
1264 | DEBUGF("P\n"); | ||
1265 | play_pending = false; | ||
1266 | playing = true; | ||
1267 | |||
1268 | init_dma(); | ||
1269 | if (!paused) | ||
1270 | { | ||
1271 | last_dma_tick = current_tick; | ||
1272 | start_dma(); | ||
1273 | } | ||
1274 | |||
1275 | /* Tell ourselves that we need more data */ | ||
1276 | queue_post(&mpeg_queue, MPEG_NEED_DATA, 0); | ||
1277 | |||
1278 | } | ||
1279 | } | ||
1280 | break; | ||
1281 | |||
1282 | case MPEG_NEED_DATA: | 1316 | case MPEG_NEED_DATA: |
1283 | free_space_left = mp3buf_read - mp3buf_write; | 1317 | free_space_left = mp3buf_read - mp3buf_write; |
1284 | 1318 | ||
@@ -1289,7 +1323,7 @@ static void mpeg_thread(void) | |||
1289 | unplayed_space_left = mp3buflen - free_space_left; | 1323 | unplayed_space_left = mp3buflen - free_space_left; |
1290 | 1324 | ||
1291 | /* Make sure that we don't fill the entire buffer */ | 1325 | /* Make sure that we don't fill the entire buffer */ |
1292 | free_space_left -= 2; | 1326 | free_space_left -= MPEG_HIGH_WATER; |
1293 | 1327 | ||
1294 | /* do we have any more buffer space to fill? */ | 1328 | /* do we have any more buffer space to fill? */ |
1295 | if(free_space_left <= MPEG_HIGH_WATER) | 1329 | if(free_space_left <= MPEG_HIGH_WATER) |
@@ -1305,15 +1339,12 @@ static void mpeg_thread(void) | |||
1305 | amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE, | 1339 | amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE, |
1306 | free_space_left); | 1340 | free_space_left); |
1307 | else | 1341 | else |
1308 | amount_to_read = MIN(MPEG_CHUNKSIZE, free_space_left); | 1342 | amount_to_read = free_space_left; |
1309 | 1343 | ||
1310 | /* Don't read more than until the end of the buffer */ | 1344 | /* Don't read more than until the end of the buffer */ |
1311 | amount_to_read = MIN(mp3buflen - mp3buf_write, amount_to_read); | 1345 | amount_to_read = MIN(mp3buflen - mp3buf_write, amount_to_read); |
1312 | 1346 | ||
1313 | /* Read in a few seconds worth of MP3 data. We don't want to | 1347 | /* Read as much mpeg data as we can fit in the buffer */ |
1314 | read too large chunks because the bitswapping will take | ||
1315 | too much time. We must keep the DMA happy and also give | ||
1316 | the other threads a chance to run. */ | ||
1317 | if(mpeg_file >= 0) | 1348 | if(mpeg_file >= 0) |
1318 | { | 1349 | { |
1319 | DEBUGF("R\n"); | 1350 | DEBUGF("R\n"); |
@@ -1325,8 +1356,6 @@ static void mpeg_thread(void) | |||
1325 | t2 = current_tick; | 1356 | t2 = current_tick; |
1326 | DEBUGF("time: %d\n", t2 - t1); | 1357 | DEBUGF("time: %d\n", t2 - t1); |
1327 | DEBUGF("R: %x\n", len); | 1358 | DEBUGF("R: %x\n", len); |
1328 | /* Tell ourselves that we need to swap some data */ | ||
1329 | queue_post(&mpeg_queue, MPEG_SWAP_DATA, 0); | ||
1330 | 1359 | ||
1331 | /* Make sure that the write pointer is at a word | 1360 | /* Make sure that the write pointer is at a word |
1332 | boundary when we reach the end of the file */ | 1361 | boundary when we reach the end of the file */ |