summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-04-14 02:46:15 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-04-14 02:46:15 +0000
commit9bfa237869ec3a75776926de7ffd4e7a1c4e03b9 (patch)
tree31c8b5f5540cd8b9eee3d75ab71cf70590dc6ae4 /apps
parent3d6436e530cac4c8fe200c31e35e47fed572345e (diff)
downloadrockbox-9bfa237869ec3a75776926de7ffd4e7a1c4e03b9.tar.gz
rockbox-9bfa237869ec3a75776926de7ffd4e7a1c4e03b9.zip
mpegplayer: Get it in better shape for dual core targets. Utilize the newly added cache stuff. Add a mutex to core shared buffer variables. I'd prefer to have a true spinlock there but this will do for the moment and protect the data. Nonetheless I can't seem to crash it on an e200 any longer and the display garbage is gone.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13153 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/plugin.c6
-rw-r--r--apps/plugin.h8
-rw-r--r--apps/plugins/mpegplayer/mpegplayer.c65
3 files changed, 61 insertions, 18 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index 1db0253c4e..a059a8d035 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -486,6 +486,12 @@ static const struct plugin_api rockbox_api = {
486 detect_flashed_ramimage, 486 detect_flashed_ramimage,
487 detect_flashed_romimage, 487 detect_flashed_romimage,
488#endif 488#endif
489
490#if NUM_CORES > 1
491 spinlock_init,
492 spinlock_lock,
493 spinlock_unlock,
494#endif
489}; 495};
490 496
491int plugin_load(const char* plugin, void* parameter) 497int plugin_load(const char* plugin, void* parameter)
diff --git a/apps/plugin.h b/apps/plugin.h
index 51421fffb4..0c2d050a73 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -110,7 +110,7 @@
110#define PLUGIN_MAGIC 0x526F634B /* RocK */ 110#define PLUGIN_MAGIC 0x526F634B /* RocK */
111 111
112/* increase this every time the api struct changes */ 112/* increase this every time the api struct changes */
113#define PLUGIN_API_VERSION 52 113#define PLUGIN_API_VERSION 53
114 114
115/* update this to latest version if a change to the api struct breaks 115/* update this to latest version if a change to the api struct breaks
116 backwards compatibility (and please take the opportunity to sort in any 116 backwards compatibility (and please take the opportunity to sort in any
@@ -600,6 +600,12 @@ struct plugin_api {
600 bool (*detect_flashed_ramimage)(void); 600 bool (*detect_flashed_ramimage)(void);
601 bool (*detect_flashed_romimage)(void); 601 bool (*detect_flashed_romimage)(void);
602#endif 602#endif
603
604#if NUM_CORES > 1
605 void (*spinlock_init)(struct mutex *m);
606 void (*spinlock_lock)(struct mutex *m);
607 void (*spinlock_unlock)(struct mutex *m);
608#endif
603}; 609};
604 610
605/* plugin header */ 611/* plugin header */
diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c
index b61e76ce8a..7d97766c35 100644
--- a/apps/plugins/mpegplayer/mpegplayer.c
+++ b/apps/plugins/mpegplayer/mpegplayer.c
@@ -224,9 +224,28 @@ static Stream video_str IBSS_ATTR;
224/* NOTE: Putting the following variables in IRAM cause audio corruption 224/* NOTE: Putting the following variables in IRAM cause audio corruption
225 on the ipod (reason unknown) 225 on the ipod (reason unknown)
226*/ 226*/
227static uint8_t *disk_buf, *disk_buf_end; 227static uint8_t *disk_buf IBSS_ATTR;
228static uint8_t *disk_buf_end IBSS_ATTR;
228static uint8_t *disk_buf_tail IBSS_ATTR; 229static uint8_t *disk_buf_tail IBSS_ATTR;
229static size_t buffer_size IBSS_ATTR; 230static size_t buffer_size IBSS_ATTR;
231#if NUM_CORES > 1
232/* Some stream variables are shared between cores */
233struct mutex stream_lock IBSS_ATTR;
234static inline void init_stream_lock(void)
235 { rb->spinlock_init(&stream_lock); }
236static inline void lock_stream(void)
237 { rb->spinlock_lock(&stream_lock); }
238static inline void unlock_stream(void)
239 { rb->spinlock_unlock(&stream_lock); }
240#else
241/* No RMW issue here */
242static inline void init_stream_lock(void)
243 { }
244static inline void lock_stream(void)
245 { }
246static inline void unlock_stream(void)
247 { }
248#endif
230 249
231/* Events */ 250/* Events */
232static struct event_queue msg_queue IBSS_ATTR; 251static struct event_queue msg_queue IBSS_ATTR;
@@ -558,7 +577,7 @@ static void get_next_data( Stream* str )
558 /* Problem */ 577 /* Problem */
559 //rb->splash( HZ*3, "missing packet start code prefix : %X%X at %X", *p, *(p+2), p-disk_buf ); 578 //rb->splash( HZ*3, "missing packet start code prefix : %X%X at %X", *p, *(p+2), p-disk_buf );
560 str->curr_packet_end = str->curr_packet = NULL; 579 str->curr_packet_end = str->curr_packet = NULL;
561 return; 580 break;
562 //++p; 581 //++p;
563 //break; 582 //break;
564 } 583 }
@@ -574,7 +593,7 @@ static void get_next_data( Stream* str )
574 if (stream == 0xB9) 593 if (stream == 0xB9)
575 { 594 {
576 str->curr_packet_end = str->curr_packet = NULL; 595 str->curr_packet_end = str->curr_packet = NULL;
577 return; 596 break;
578 } 597 }
579 598
580 /* It's not the packet we're looking for, skip it */ 599 /* It's not the packet we're looking for, skip it */
@@ -667,6 +686,8 @@ static void get_next_data( Stream* str )
667 686
668 if (str->curr_packet != NULL) 687 if (str->curr_packet != NULL)
669 { 688 {
689 lock_stream();
690
670 if (str->curr_packet < str->prev_packet) 691 if (str->curr_packet < str->prev_packet)
671 { 692 {
672 str->buffer_remaining -= (disk_buf_end - str->prev_packet) + 693 str->buffer_remaining -= (disk_buf_end - str->prev_packet) +
@@ -679,6 +700,8 @@ static void get_next_data( Stream* str )
679 str->buffer_remaining -= (str->curr_packet - str->prev_packet); 700 str->buffer_remaining -= (str->curr_packet - str->prev_packet);
680 } 701 }
681 702
703 unlock_stream();
704
682 str->prev_packet = str->curr_packet; 705 str->prev_packet = str->curr_packet;
683 } 706 }
684 707
@@ -689,8 +712,6 @@ static void get_next_data( Stream* str )
689 str->guard_bytes = str->curr_packet_end - disk_buf_end; 712 str->guard_bytes = str->curr_packet_end - disk_buf_end;
690 rb->memcpy(disk_buf_end, disk_buf, str->guard_bytes); 713 rb->memcpy(disk_buf_end, disk_buf, str->guard_bytes);
691 } 714 }
692
693 return;
694 } 715 }
695 716
696 break; 717 break;
@@ -1250,9 +1271,9 @@ static void video_thread(void)
1250 mpeg2dec = mpeg2_init(); 1271 mpeg2dec = mpeg2_init();
1251 if (mpeg2dec == NULL) 1272 if (mpeg2dec == NULL)
1252 { 1273 {
1253 videostatus = STREAM_ERROR;
1254 rb->splash(0, "mpeg2_init failed"); 1274 rb->splash(0, "mpeg2_init failed");
1255 /* Commit suicide */ 1275 /* Commit suicide */
1276 videostatus = THREAD_TERMINATED;
1256 rb->remove_thread(NULL); 1277 rb->remove_thread(NULL);
1257 } 1278 }
1258 1279
@@ -1282,6 +1303,8 @@ static void video_thread(void)
1282 else if (videostatus == PLEASE_PAUSE) 1303 else if (videostatus == PLEASE_PAUSE)
1283 { 1304 {
1284 videostatus = STREAM_PAUSING; 1305 videostatus = STREAM_PAUSING;
1306 flush_icache();
1307
1285 while (videostatus == STREAM_PAUSING) 1308 while (videostatus == STREAM_PAUSING)
1286 rb->sleep(HZ/10); 1309 rb->sleep(HZ/10);
1287 } 1310 }
@@ -1533,6 +1556,8 @@ static void video_thread(void)
1533 } 1556 }
1534 1557
1535done: 1558done:
1559 flush_icache();
1560
1536 videostatus = STREAM_DONE; 1561 videostatus = STREAM_DONE;
1537 1562
1538 while (videostatus != PLEASE_STOP) 1563 while (videostatus != PLEASE_STOP)
@@ -1550,10 +1575,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
1550 int audiosize; 1575 int audiosize;
1551 int in_file; 1576 int in_file;
1552 uint8_t* buffer; 1577 uint8_t* buffer;
1553 size_t audio_remaining, video_remaining;
1554 size_t bytes_to_read;
1555 size_t file_remaining; 1578 size_t file_remaining;
1556 size_t n;
1557 size_t disk_buf_len; 1579 size_t disk_buf_len;
1558#ifndef HAVE_LCD_COLOR 1580#ifndef HAVE_LCD_COLOR
1559 long graysize; 1581 long graysize;
@@ -1692,6 +1714,8 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
1692 gray_show(true); 1714 gray_show(true);
1693#endif 1715#endif
1694 1716
1717 init_stream_lock();
1718
1695 /* We put the video thread on the second processor for multi-core targets. */ 1719 /* We put the video thread on the second processor for multi-core targets. */
1696 if ((videothread_id = rb->create_thread(video_thread, 1720 if ((videothread_id = rb->create_thread(video_thread,
1697 (uint8_t*)video_stack,VIDEO_STACKSIZE,"mpgvideo" IF_PRIO(,PRIORITY_PLAYBACK) 1721 (uint8_t*)video_stack,VIDEO_STACKSIZE,"mpgvideo" IF_PRIO(,PRIORITY_PLAYBACK)
@@ -1711,32 +1735,39 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
1711 rb->lcd_setfont(FONT_SYSFIXED); 1735 rb->lcd_setfont(FONT_SYSFIXED);
1712 1736
1713 /* Wait until both threads have finished their work */ 1737 /* Wait until both threads have finished their work */
1714 while ((audiostatus != STREAM_DONE) || (videostatus != STREAM_DONE)) { 1738 while ((audiostatus != STREAM_DONE) || (videostatus != STREAM_DONE))
1715 audio_remaining = audio_str.buffer_remaining; 1739 {
1716 video_remaining = video_str.buffer_remaining; 1740 size_t audio_remaining = audio_str.buffer_remaining;
1741 size_t video_remaining = video_str.buffer_remaining;
1742
1717 if (MIN(audio_remaining,video_remaining) < MPEG_LOW_WATERMARK) { 1743 if (MIN(audio_remaining,video_remaining) < MPEG_LOW_WATERMARK) {
1718 1744
1719 // TODO: Add mutex when updating the A/V buffer_remaining variables. 1745 size_t bytes_to_read = buffer_size - MPEG_GUARDBUF_SIZE -
1720 bytes_to_read = buffer_size - MPEG_GUARDBUF_SIZE - MAX(audio_remaining,video_remaining); 1746 MAX(audio_remaining,video_remaining);
1721 1747
1722 bytes_to_read = MIN(bytes_to_read,(size_t)(disk_buf_end-disk_buf_tail)); 1748 bytes_to_read = MIN(bytes_to_read,(size_t)(disk_buf_end-disk_buf_tail));
1723 1749
1724 while (( bytes_to_read > 0) && (file_remaining > 0) && 1750 while (( bytes_to_read > 0) && (file_remaining > 0) &&
1725 ((audiostatus != STREAM_DONE) || (videostatus != STREAM_DONE))) { 1751 ((audiostatus != STREAM_DONE) || (videostatus != STREAM_DONE))) {
1726 n = rb->read(in_file, disk_buf_tail, MIN(32*1024,bytes_to_read)); 1752 size_t n = rb->read(in_file, disk_buf_tail, MIN(32*1024,bytes_to_read));
1727 1753
1728 bytes_to_read -= n; 1754 bytes_to_read -= n;
1729 file_remaining -= n; 1755 file_remaining -= n;
1756
1757 lock_stream();
1730 audio_str.buffer_remaining += n; 1758 audio_str.buffer_remaining += n;
1731 video_str.buffer_remaining += n; 1759 video_str.buffer_remaining += n;
1760 unlock_stream();
1761
1732 disk_buf_tail += n; 1762 disk_buf_tail += n;
1763
1733 rb->yield(); 1764 rb->yield();
1734 } 1765 }
1735 1766
1736 if (disk_buf_tail == disk_buf_end) 1767 if (disk_buf_tail == disk_buf_end)
1737 disk_buf_tail = buffer; 1768 disk_buf_tail = buffer;
1738
1739 } 1769 }
1770
1740 rb->sleep(HZ/10); 1771 rb->sleep(HZ/10);
1741 } 1772 }
1742 1773