summaryrefslogtreecommitdiff
path: root/apps/plugins/mpegplayer/mpegplayer.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/mpegplayer/mpegplayer.c')
-rw-r--r--apps/plugins/mpegplayer/mpegplayer.c190
1 files changed, 159 insertions, 31 deletions
diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c
index 513c2f0863..2314d96889 100644
--- a/apps/plugins/mpegplayer/mpegplayer.c
+++ b/apps/plugins/mpegplayer/mpegplayer.c
@@ -372,6 +372,13 @@ CONFIG_KEYPAD == SANSA_M200_PAD
372#define MIN_FF_REWIND_STEP (TS_SECOND/2) 372#define MIN_FF_REWIND_STEP (TS_SECOND/2)
373#define OSD_MIN_UPDATE_INTERVAL (HZ/2) 373#define OSD_MIN_UPDATE_INTERVAL (HZ/2)
374 374
375enum video_action
376{
377 VIDEO_STOP = 0,
378 VIDEO_PREV,
379 VIDEO_NEXT,
380};
381
375/* OSD status - same order as icon array */ 382/* OSD status - same order as icon array */
376enum osd_status_enum 383enum osd_status_enum
377{ 384{
@@ -1452,7 +1459,7 @@ static void osd_stop(void)
1452 1459
1453 osd_cancel_refresh(OSD_REFRESH_VIDEO | OSD_REFRESH_RESUME); 1460 osd_cancel_refresh(OSD_REFRESH_VIDEO | OSD_REFRESH_RESUME);
1454 osd_set_status(OSD_STATUS_STOPPED | OSD_NODRAW); 1461 osd_set_status(OSD_STATUS_STOPPED | OSD_NODRAW);
1455 osd_show(OSD_HIDE | OSD_NODRAW); 1462 osd_show(OSD_HIDE);
1456 1463
1457 stream_stop(); 1464 stream_stop();
1458 1465
@@ -1496,6 +1503,53 @@ static void osd_seek(int btn)
1496 stream_seek(time, SEEK_SET); 1503 stream_seek(time, SEEK_SET);
1497} 1504}
1498 1505
1506/* has this file the extension .mpg ? */
1507static bool is_videofile(const char* file)
1508{
1509 const char* ext = rb->strrchr(file, '.');
1510 if (ext && !rb->strcasecmp(ext, ".mpg"))
1511 return true;
1512
1513 return false;
1514}
1515
1516/* deliver the next/previous video file in the current directory.
1517 returns 0 if there is none. */
1518static bool get_videofile(int direction, char* videofile, size_t bufsize)
1519{
1520 struct tree_context *tree = rb->tree_get_context();
1521 struct entry *dircache = tree->dircache;
1522 int i, step, end, found = 0;
1523 char *videoname = rb->strrchr(videofile, '/') + 1;
1524 size_t rest = bufsize - (videoname - videofile) - 1;
1525
1526 if (direction == VIDEO_NEXT) {
1527 i = 0;
1528 step = 1;
1529 end = tree->filesindir;
1530 } else {
1531 i = tree->filesindir-1;
1532 step = -1;
1533 end = -1;
1534 }
1535 for (; i != end; i += step)
1536 {
1537 const char* name = dircache[i].name;
1538 if (!rb->strcmp(name, videoname)) {
1539 found = 1;
1540 continue;
1541 }
1542 if (found && rb->strlen(name) <= rest &&
1543 !(dircache[i].attr & ATTR_DIRECTORY) && is_videofile(name))
1544 {
1545 rb->strcpy(videoname, name);
1546 return true;
1547 }
1548 }
1549
1550 return false;
1551}
1552
1499#ifdef HAVE_HEADPHONE_DETECTION 1553#ifdef HAVE_HEADPHONE_DETECTION
1500/* Handle SYS_PHONE_PLUGGED/UNPLUGGED */ 1554/* Handle SYS_PHONE_PLUGGED/UNPLUGGED */
1501static void osd_handle_phone_plug(bool inserted) 1555static void osd_handle_phone_plug(bool inserted)
@@ -1531,8 +1585,10 @@ static void osd_handle_phone_plug(bool inserted)
1531} 1585}
1532#endif 1586#endif
1533 1587
1534static void button_loop(void) 1588static int button_loop(void)
1535{ 1589{
1590 int next_action = (settings.play_mode == 0) ? VIDEO_STOP : VIDEO_NEXT;
1591
1536 rb->lcd_setfont(FONT_SYSFIXED); 1592 rb->lcd_setfont(FONT_SYSFIXED);
1537#ifdef HAVE_LCD_COLOR 1593#ifdef HAVE_LCD_COLOR
1538 rb->lcd_set_foreground(LCD_WHITE); 1594 rb->lcd_set_foreground(LCD_WHITE);
@@ -1550,7 +1606,7 @@ static void button_loop(void)
1550 /* Start playback at the specified starting time */ 1606 /* Start playback at the specified starting time */
1551 if (osd_play(settings.resume_time) < STREAM_OK) { 1607 if (osd_play(settings.resume_time) < STREAM_OK) {
1552 rb->splash(HZ*2, "Playback failed"); 1608 rb->splash(HZ*2, "Playback failed");
1553 return; 1609 return VIDEO_STOP;
1554 } 1610 }
1555 1611
1556 /* Gently poll the video player for EOS and handle UI */ 1612 /* Gently poll the video player for EOS and handle UI */
@@ -1629,6 +1685,8 @@ static void button_loop(void)
1629 1685
1630 result = mpeg_menu(); 1686 result = mpeg_menu();
1631 1687
1688 next_action = (settings.play_mode == 0) ? VIDEO_STOP : VIDEO_NEXT;
1689
1632 /* The menu can change the font, so restore */ 1690 /* The menu can change the font, so restore */
1633 rb->lcd_setfont(FONT_SYSFIXED); 1691 rb->lcd_setfont(FONT_SYSFIXED);
1634#ifdef HAVE_LCD_COLOR 1692#ifdef HAVE_LCD_COLOR
@@ -1641,6 +1699,7 @@ static void button_loop(void)
1641 switch (result) 1699 switch (result)
1642 { 1700 {
1643 case MPEG_MENU_QUIT: 1701 case MPEG_MENU_QUIT:
1702 next_action = VIDEO_STOP;
1644 osd_stop(); 1703 osd_stop();
1645 break; 1704 break;
1646 1705
@@ -1679,6 +1738,7 @@ static void button_loop(void)
1679#endif 1738#endif
1680 case ACTION_STD_CANCEL: 1739 case ACTION_STD_CANCEL:
1681 { 1740 {
1741 next_action = VIDEO_STOP;
1682 osd_stop(); 1742 osd_stop();
1683 break; 1743 break;
1684 } /* MPEG_STOP: */ 1744 } /* MPEG_STOP: */
@@ -1718,7 +1778,40 @@ static void button_loop(void)
1718 case MPEG_RC_FF: 1778 case MPEG_RC_FF:
1719#endif 1779#endif
1720 { 1780 {
1721 osd_seek(button); 1781 int old_button = button;
1782 if (settings.play_mode != 0)
1783 {
1784 /* if button has been released: skip to next/previous file */
1785 button = rb->button_get_w_tmo(OSD_MIN_UPDATE_INTERVAL);
1786 }
1787 switch (button)
1788 {
1789 case MPEG_RW | BUTTON_REL:
1790 {
1791 /* release within 3 seconds: skip to previous file, else
1792 start the current video from the beginning */
1793 osd_stop();
1794 if ( stream_get_resume_time() > 3*TS_SECOND ) {
1795 osd_play(0);
1796 osd_show(OSD_SHOW);
1797 } else {
1798 next_action = VIDEO_PREV;
1799 }
1800 break;
1801 }
1802 case MPEG_FF | BUTTON_REL:
1803 {
1804 osd_stop();
1805 next_action = VIDEO_NEXT;
1806 break;
1807 }
1808 default:
1809 {
1810 button = old_button;
1811 osd_seek(button);
1812 break;
1813 }
1814 }
1722 break; 1815 break;
1723 } /* MPEG_RW: MPEG_FF: */ 1816 } /* MPEG_RW: MPEG_FF: */
1724 1817
@@ -1750,13 +1843,18 @@ static void button_loop(void)
1750#endif 1843#endif
1751 1844
1752 rb->lcd_setfont(FONT_UI); 1845 rb->lcd_setfont(FONT_UI);
1846
1847 return next_action;
1753} 1848}
1754 1849
1755enum plugin_status plugin_start(const void* parameter) 1850enum plugin_status plugin_start(const void* parameter)
1756{ 1851{
1852 static char videofile[MAX_PATH];
1853
1757 int status = PLUGIN_ERROR; /* assume failure */ 1854 int status = PLUGIN_ERROR; /* assume failure */
1758 int result; 1855 int result;
1759 int err; 1856 int err;
1857 bool quit = false;
1760 const char *errstring; 1858 const char *errstring;
1761 1859
1762 if (parameter == NULL) { 1860 if (parameter == NULL) {
@@ -1777,46 +1875,76 @@ enum plugin_status plugin_start(const void* parameter)
1777 rb->lcd_clear_display(); 1875 rb->lcd_clear_display();
1778 rb->lcd_update(); 1876 rb->lcd_update();
1779 1877
1878 rb->strcpy(videofile, (const char*) parameter);
1879
1780 if (stream_init() < STREAM_OK) { 1880 if (stream_init() < STREAM_OK) {
1781 DEBUGF("Could not initialize streams\n"); 1881 DEBUGF("Could not initialize streams\n");
1782 } else { 1882 } else {
1783 rb->splash(0, "Loading..."); 1883 while (!quit)
1784 init_settings((char*)parameter); 1884 {
1885 int next_action = VIDEO_STOP;
1785 1886
1786 err = stream_open((char *)parameter); 1887 init_settings(videofile);
1888 err = stream_open(videofile);
1787 1889
1788 if (err >= STREAM_OK) { 1890 if (err >= STREAM_OK) {
1789 /* start menu */ 1891 /* start menu */
1790 rb->lcd_clear_display(); 1892 rb->lcd_clear_display();
1791 rb->lcd_update(); 1893 rb->lcd_update();
1792 result = mpeg_start_menu(stream_get_duration()); 1894 result = mpeg_start_menu(stream_get_duration());
1793 1895
1794 if (result != MPEG_START_QUIT) { 1896 if (result != MPEG_START_QUIT) {
1795 /* Enter button loop and process UI */ 1897 /* Enter button loop and process UI */
1796 button_loop(); 1898 next_action = button_loop();
1797 } 1899 }
1798 1900
1799 stream_close(); 1901 stream_close();
1800 1902
1801 rb->lcd_clear_display(); 1903 rb->lcd_clear_display();
1802 rb->lcd_update(); 1904 rb->lcd_update();
1803 1905
1804 save_settings(); 1906 save_settings();
1805 status = PLUGIN_OK; 1907 status = PLUGIN_OK;
1806 1908
1807 mpeg_menu_sysevent_handle(); 1909 mpeg_menu_sysevent_handle();
1808 } else { 1910 } else {
1809 DEBUGF("Could not open %s\n", (char*)parameter); 1911 DEBUGF("Could not open %s\n", videofile);
1810 switch (err) 1912 switch (err)
1913 {
1914 case STREAM_UNSUPPORTED:
1915 errstring = "Unsupported format";
1916 break;
1917 default:
1918 errstring = "Error opening file: %d";
1919 }
1920
1921 rb->splashf(HZ*2, errstring, err);
1922 status = PLUGIN_ERROR;
1923 }
1924
1925 /* return value of button_loop says, what's next */
1926 switch (next_action)
1927 {
1928 case VIDEO_NEXT:
1811 { 1929 {
1812 case STREAM_UNSUPPORTED: 1930 if (!get_videofile(VIDEO_NEXT, videofile, sizeof(videofile))) {
1813 errstring = "Unsupported format"; 1931 /* quit after finished the last videofile */
1932 quit = true;
1933 }
1814 break; 1934 break;
1815 default: 1935 }
1816 errstring = "Error opening file: %d"; 1936 case VIDEO_PREV:
1937 {
1938 get_videofile(VIDEO_PREV, videofile, sizeof(videofile));
1939 /* if there is no previous file, play the same videofile */
1940 break;
1941 }
1942 case VIDEO_STOP:
1943 {
1944 quit = true;
1945 break;
1946 }
1817 } 1947 }
1818
1819 rb->splashf(HZ*2, errstring, err);
1820 } 1948 }
1821 } 1949 }
1822 1950