summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/mpegplayer/mpeg_settings.c585
-rw-r--r--apps/plugins/mpegplayer/mpeg_settings.h34
-rw-r--r--apps/plugins/mpegplayer/mpegplayer.c46
-rw-r--r--apps/plugins/mpegplayer/stream_mgr.c46
4 files changed, 434 insertions, 277 deletions
diff --git a/apps/plugins/mpegplayer/mpeg_settings.c b/apps/plugins/mpegplayer/mpeg_settings.c
index dee374d..2cc8fbc 100644
--- a/apps/plugins/mpegplayer/mpeg_settings.c
+++ b/apps/plugins/mpegplayer/mpeg_settings.c
@@ -7,87 +7,83 @@
struct mpeg_settings settings;
-#define SETTINGS_VERSION 2
-#define SETTINGS_MIN_VERSION 1
-#define SETTINGS_FILENAME "mpegplayer.cfg"
-
#define THUMB_DELAY (75*HZ/100)
/* button definitions */
#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
(CONFIG_KEYPAD == IRIVER_H300_PAD)
-#define MPEG_SELECT BUTTON_ON
-#define MPEG_RIGHT BUTTON_RIGHT
-#define MPEG_LEFT BUTTON_LEFT
-#define MPEG_UP BUTTON_UP
-#define MPEG_DOWN BUTTON_DOWN
-#define MPEG_EXIT BUTTON_OFF
+#define MPEG_START_TIME_SELECT BUTTON_ON
+#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
+#define MPEG_START_TIME_LEFT BUTTON_LEFT
+#define MPEG_START_TIME_UP BUTTON_UP
+#define MPEG_START_TIME_DOWN BUTTON_DOWN
+#define MPEG_START_TIME_EXIT BUTTON_OFF
#elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
-#define MPEG_SELECT BUTTON_PLAY
-#define MPEG_RIGHT BUTTON_RIGHT
-#define MPEG_LEFT BUTTON_LEFT
-#define MPEG_UP BUTTON_UP
-#define MPEG_DOWN BUTTON_DOWN
-#define MPEG_EXIT BUTTON_POWER
+#define MPEG_START_TIME_SELECT BUTTON_PLAY
+#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
+#define MPEG_START_TIME_LEFT BUTTON_LEFT
+#define MPEG_START_TIME_UP BUTTON_UP
+#define MPEG_START_TIME_DOWN BUTTON_DOWN
+#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
(CONFIG_KEYPAD == IPOD_3G_PAD) || \
(CONFIG_KEYPAD == IPOD_1G2G_PAD)
-#define MPEG_SELECT BUTTON_SELECT
-#define MPEG_RIGHT BUTTON_RIGHT
-#define MPEG_LEFT BUTTON_LEFT
-#define MPEG_UP BUTTON_SCROLL_FWD
-#define MPEG_DOWN BUTTON_SCROLL_BACK
-#define MPEG_EXIT BUTTON_MENU
+#define MPEG_START_TIME_SELECT BUTTON_SELECT
+#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
+#define MPEG_START_TIME_LEFT BUTTON_LEFT
+#define MPEG_START_TIME_UP BUTTON_SCROLL_FWD
+#define MPEG_START_TIME_DOWN BUTTON_SCROLL_BACK
+#define MPEG_START_TIME_EXIT BUTTON_MENU
#elif CONFIG_KEYPAD == GIGABEAT_PAD
-#define MPEG_SELECT BUTTON_SELECT
-#define MPEG_LEFT BUTTON_LEFT
-#define MPEG_RIGHT BUTTON_RIGHT
-#define MPEG_UP BUTTON_UP
-#define MPEG_DOWN BUTTON_DOWN
-#define MPEG_SCROLL_DOWN BUTTON_VOL_DOWN
-#define MPEG_SCROLL_UP BUTTON_VOL_UP
-#define MPEG_EXIT BUTTON_POWER
+#define MPEG_START_TIME_SELECT BUTTON_SELECT
+#define MPEG_START_TIME_LEFT BUTTON_LEFT
+#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
+#define MPEG_START_TIME_UP BUTTON_UP
+#define MPEG_START_TIME_DOWN BUTTON_DOWN
+#define MPEG_START_TIME_SCROLL_DOWN BUTTON_VOL_DOWN
+#define MPEG_START_TIME_SCROLL_UP BUTTON_VOL_UP
+#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == IRIVER_H10_PAD
-#define MPEG_SELECT BUTTON_PLAY
-#define MPEG_LEFT BUTTON_LEFT
-#define MPEG_RIGHT BUTTON_RIGHT
-#define MPEG_UP BUTTON_SCROLL_UP
-#define MPEG_DOWN BUTTON_SCROLL_DOWN
-#define MPEG_EXIT BUTTON_POWER
+#define MPEG_START_TIME_SELECT BUTTON_PLAY
+#define MPEG_START_TIME_LEFT BUTTON_LEFT
+#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
+#define MPEG_START_TIME_UP BUTTON_SCROLL_UP
+#define MPEG_START_TIME_DOWN BUTTON_SCROLL_DOWN
+#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif (CONFIG_KEYPAD == SANSA_E200_PAD)
-#define MPEG_SELECT BUTTON_SELECT
-#define MPEG_SCROLL_UP BUTTON_SCROLL_BACK
-#define MPEG_SCROLL_DOWN BUTTON_SCROLL_FWD
-#define MPEG_LEFT BUTTON_LEFT
-#define MPEG_RIGHT BUTTON_RIGHT
-#define MPEG_UP BUTTON_UP
-#define MPEG_DOWN BUTTON_DOWN
-#define MPEG_EXIT BUTTON_POWER
+#define MPEG_START_TIME_SELECT BUTTON_SELECT
+#define MPEG_START_TIME_SCROLL_UP BUTTON_SCROLL_BACK
+#define MPEG_START_TIME_SCROLL_DOWN BUTTON_SCROLL_FWD
+#define MPEG_START_TIME_LEFT BUTTON_LEFT
+#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
+#define MPEG_START_TIME_UP BUTTON_UP
+#define MPEG_START_TIME_DOWN BUTTON_DOWN
+#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif (CONFIG_KEYPAD == SANSA_C200_PAD)
-#define MPEG_SELECT BUTTON_SELECT
-#define MPEG_SCROLL_UP BUTTON_VOL_UP
-#define MPEG_SCROLL_DOWN BUTTON_VOL_DOWN
-#define MPEG_LEFT BUTTON_LEFT
-#define MPEG_RIGHT BUTTON_RIGHT
-#define MPEG_UP BUTTON_UP
-#define MPEG_DOWN BUTTON_DOWN
-#define MPEG_EXIT BUTTON_POWER
+#define MPEG_START_TIME_SELECT BUTTON_SELECT
+#define MPEG_START_TIME_SCROLL_UP BUTTON_VOL_UP
+#define MPEG_START_TIME_SCROLL_DOWN BUTTON_VOL_DOWN
+#define MPEG_START_TIME_LEFT BUTTON_LEFT
+#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
+#define MPEG_START_TIME_UP BUTTON_UP
+#define MPEG_START_TIME_DOWN BUTTON_DOWN
+#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == MROBE500_PAD
-#define MPEG_SELECT BUTTON_RC_HEART
-#define MPEG_SCROLL_UP BUTTON_RC_VOL_UP
-#define MPEG_SCROLL_DOWN BUTTON_RC_VOL_DOWN
-#define MPEG_LEFT BUTTON_LEFT
-#define MPEG_RIGHT BUTTON_RIGHT
-#define MPEG_UP BUTTON_RC_PLAY
-#define MPEG_DOWN BUTTON_RC_DOWN
-#define MPEG_EXIT BUTTON_POWER
+#define MPEG_START_TIME_SELECT BUTTON_RC_HEART
+#define MPEG_START_TIME_SCROLL_UP BUTTON_RC_VOL_UP
+#define MPEG_START_TIME_SCROLL_DOWN BUTTON_RC_VOL_DOWN
+#define MPEG_START_TIME_LEFT BUTTON_LEFT
+#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
+#define MPEG_START_TIME_UP BUTTON_RC_PLAY
+#define MPEG_START_TIME_DOWN BUTTON_RC_DOWN
+#define MPEG_START_TIME_EXIT BUTTON_POWER
#else
#error MPEGPLAYER: Unsupported keypad
@@ -100,8 +96,8 @@ static struct configdata config[] =
{TYPE_INT, 0, 2, &settings.skipframes, "Skip frames", NULL, NULL},
{TYPE_INT, 0, INT_MAX, &settings.resume_count, "Resume count",
NULL, NULL},
- {TYPE_INT, 0, 2, &settings.enable_start_menu, "Enable start menu",
- NULL, NULL},
+ {TYPE_INT, 0, MPEG_RESUME_NUM_OPTIONS, &settings.resume_options,
+ "Resume options", NULL, NULL},
#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) || defined(SANSA_C200)
{TYPE_INT, 0, INT_MAX, &settings.displayoptions, "Display options",
NULL, NULL},
@@ -118,66 +114,70 @@ static const struct opt_items enabledisable[2] = {
{ "Enable", -1 },
};
-static void display_options(void)
+static long mpeg_menu_sysevent_id;
+
+void mpeg_menu_sysevent_clear(void)
{
- int result;
- int menu_id;
- int options_quit = 0;
+ mpeg_menu_sysevent_id = 0;
+}
- static const struct menu_item items[] = {
-#if MPEG_OPTION_DITHERING_ENABLED
- [MPEG_OPTION_DITHERING] =
- { "Dithering", NULL },
-#endif
- [MPEG_OPTION_DISPLAY_FPS] =
- { "Display FPS", NULL },
- [MPEG_OPTION_LIMIT_FPS] =
- { "Limit FPS", NULL },
- [MPEG_OPTION_SKIP_FRAMES] =
- { "Skip frames", NULL },
- };
+int mpeg_menu_sysevent_callback(int btn, int menu)
+{
+ switch (btn)
+ {
+ case SYS_USB_CONNECTED:
+ case SYS_POWEROFF:
+ mpeg_menu_sysevent_id = btn;
+ return ACTION_STD_CANCEL;
+ }
- menu_id = menu_init(rb, items, ARRAYLEN(items),
- NULL, NULL, NULL, NULL);
+ return btn;
+ (void)menu;
+}
- rb->button_clear_queue();
+long mpeg_menu_sysevent(void)
+{
+ return mpeg_menu_sysevent_id;
+}
- while(options_quit == 0)
- {
- result = menu_show(menu_id);
+void mpeg_menu_sysevent_handle(void)
+{
+ long id = mpeg_menu_sysevent();
+ if (id != 0)
+ rb->default_event_handler(id);
+}
- switch (result)
- {
-#if MPEG_OPTION_DITHERING_ENABLED
- case MPEG_OPTION_DITHERING:
- result = (settings.displayoptions & LCD_YUV_DITHER) ? 1 : 0;
- rb->set_option("Dithering", &result, INT, noyes, 2, NULL);
- settings.displayoptions = (settings.displayoptions & ~LCD_YUV_DITHER)
- | ((result != 0) ? LCD_YUV_DITHER : 0);
- rb->lcd_yuv_set_options(settings.displayoptions);
- break;
-#endif /* MPEG_OPTION_DITHERING_ENABLED */
- case MPEG_OPTION_DISPLAY_FPS:
- rb->set_option("Display FPS",&settings.showfps,INT,
- noyes, 2, NULL);
- break;
- case MPEG_OPTION_LIMIT_FPS:
- rb->set_option("Limit FPS",&settings.limitfps,INT,
- noyes, 2, NULL);
- break;
- case MPEG_OPTION_SKIP_FRAMES:
- rb->set_option("Skip frames",&settings.skipframes,INT,
- noyes, 2, NULL);
- break;
- default:
- options_quit=1;
- break;
- }
- }
+static void format_menu_item(struct menu_item *item, int bufsize,
+ const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
- menu_exit(menu_id);
+ rb->vsnprintf(item->desc, bufsize, fmt, ap);
+
+ va_end(ap);
+}
+
+static bool mpeg_set_option(const char* string,
+ void* variable,
+ enum optiontype type,
+ const struct opt_items* options,
+ int numoptions,
+ void (*function)(int))
+{
+ mpeg_menu_sysevent_clear();
+
+ /* This eats SYS_POWEROFF - :\ */
+ bool usb = rb->set_option(string, variable, type, options, numoptions,
+ function);
+
+ if (usb)
+ mpeg_menu_sysevent_id = ACTION_STD_CANCEL;
+
+ return usb;
}
+
#ifndef HAVE_LCD_COLOR
/* Cheapo splash implementation for the grey surface */
static void grey_splash(int ticks, const unsigned char *fmt, ...)
@@ -230,7 +230,7 @@ static void show_loading(struct vo_rect *rc)
lcd_(splash)(0, "Loading...");
}
-void draw_slider(uint32_t range, uint32_t pos, struct vo_rect *rc)
+static void draw_slider(uint32_t range, uint32_t pos, struct vo_rect *rc)
{
#define SLIDER_WIDTH (LCD_WIDTH-SLIDER_LMARGIN-SLIDER_RMARGIN)
#define SLIDER_X SLIDER_LMARGIN
@@ -291,7 +291,7 @@ void draw_slider(uint32_t range, uint32_t pos, struct vo_rect *rc)
}
}
-bool display_thumb_image(const struct vo_rect *rc)
+static bool display_thumb_image(const struct vo_rect *rc)
{
if (!stream_display_thumb(rc))
{
@@ -322,7 +322,7 @@ bool display_thumb_image(const struct vo_rect *rc)
}
/* Add an amount to the specified time - with saturation */
-uint32_t increment_time(uint32_t val, int32_t amount, uint32_t range)
+static uint32_t increment_time(uint32_t val, int32_t amount, uint32_t range)
{
if (amount < 0)
{
@@ -344,7 +344,7 @@ uint32_t increment_time(uint32_t val, int32_t amount, uint32_t range)
return val;
}
-int get_start_time(uint32_t duration)
+static int get_start_time(uint32_t duration)
{
int button = 0;
int tmo = TIMEOUT_NOBLOCK;
@@ -420,73 +420,79 @@ int get_start_time(uint32_t duration)
rc_vid.r, rc_vid.b);
#ifndef HAVE_LCD_COLOR
- /* Restore gray overlay dimensions */
stream_gray_show(true);
#endif
- while(slider_state < state9)
+ while (slider_state < state9)
{
+ mpeg_menu_sysevent_clear();
button = tmo == TIMEOUT_BLOCK ?
rb->button_get(true) : rb->button_get_w_tmo(tmo);
+ button = mpeg_menu_sysevent_callback(button, -1);
+
switch (button)
{
case BUTTON_NONE:
break;
/* Coarse (1 minute) control */
- case MPEG_DOWN:
- case MPEG_DOWN | BUTTON_REPEAT:
+ case MPEG_START_TIME_DOWN:
+ case MPEG_START_TIME_DOWN | BUTTON_REPEAT:
resume_time = increment_time(resume_time, -60*TS_SECOND, duration);
slider_state = state0;
break;
- case MPEG_UP:
- case MPEG_UP | BUTTON_REPEAT:
+ case MPEG_START_TIME_UP:
+ case MPEG_START_TIME_UP | BUTTON_REPEAT:
resume_time = increment_time(resume_time, 60*TS_SECOND, duration);
slider_state = state0;
break;
/* Fine (1 second) control */
- case MPEG_LEFT:
- case MPEG_LEFT | BUTTON_REPEAT:
-#ifdef MPEG_SCROLL_UP
- case MPEG_SCROLL_UP:
- case MPEG_SCROLL_UP | BUTTON_REPEAT:
+ case MPEG_START_TIME_LEFT:
+ case MPEG_START_TIME_LEFT | BUTTON_REPEAT:
+#ifdef MPEG_START_TIME_SCROLL_UP
+ case MPEG_START_TIME_SCROLL_UP:
+ case MPEG_START_TIME_SCROLL_UP | BUTTON_REPEAT:
#endif
resume_time = increment_time(resume_time, -TS_SECOND, duration);
slider_state = state0;
break;
- case MPEG_RIGHT:
- case MPEG_RIGHT | BUTTON_REPEAT:
-#ifdef MPEG_SCROLL_DOWN
- case MPEG_SCROLL_DOWN:
- case MPEG_SCROLL_DOWN | BUTTON_REPEAT:
+ case MPEG_START_TIME_RIGHT:
+ case MPEG_START_TIME_RIGHT | BUTTON_REPEAT:
+#ifdef MPEG_START_TIME_SCROLL_DOWN
+ case MPEG_START_TIME_SCROLL_DOWN:
+ case MPEG_START_TIME_SCROLL_DOWN | BUTTON_REPEAT:
#endif
resume_time = increment_time(resume_time, TS_SECOND, duration);
slider_state = state0;
break;
- case MPEG_SELECT:
+ case MPEG_START_TIME_SELECT:
settings.resume_time = resume_time;
- case MPEG_EXIT:
+ button = MPEG_START_SEEK;
slider_state = state9;
break;
- case SYS_USB_CONNECTED:
+ case MPEG_START_TIME_EXIT:
+ button = MPEG_START_EXIT;
slider_state = state9;
-#ifndef HAVE_LCD_COLOR
- stream_gray_show(false);
-#endif
- cancel_cpu_boost();
+ break;
+
+ case ACTION_STD_CANCEL:
+ button = MPEG_START_QUIT;
+ slider_state = state9;
+ break;
+
default:
rb->default_event_handler(button);
rb->yield();
continue;
}
- switch(slider_state)
+ switch (slider_state)
{
case state0:
trigger_cpu_boost();
@@ -500,12 +506,13 @@ int get_start_time(uint32_t duration)
display_thumb_image(&rc_vid);
slider_state = state2;
case state2:
- case state9:
cancel_cpu_boost();
tmo = TIMEOUT_BLOCK;
default:
break;
}
+
+ rb->yield();
}
#ifndef HAVE_LCD_COLOR
@@ -519,46 +526,17 @@ int get_start_time(uint32_t duration)
return button;
}
-enum mpeg_start_id mpeg_start_menu(uint32_t duration)
+static int show_start_menu(uint32_t duration)
{
int menu_id;
int result = 0;
- int menu_quit = 0;
+ bool menu_quit = false;
/* add the resume time to the menu display */
char resume_str[32];
char hms_str[32];
struct hms hms;
- ts_to_hms(settings.resume_time, &hms);
- hms_format(hms_str, sizeof(hms_str), &hms);
-
- if (settings.enable_start_menu == 0)
- {
- rb->snprintf(resume_str, sizeof(resume_str), "Yes: %s", hms_str);
-
- struct opt_items resume_no_yes[2] =
- {
- { "No", -1 },
- { resume_str, -1 },
- };
- if (settings.resume_time == 0)
- return MPEG_START_RESTART;
-
- rb->set_option("Resume", &result, INT,
- resume_no_yes, 2, NULL);
-
- if (result == 0)
- {
- settings.resume_time = 0;
- return MPEG_START_RESTART;
- }
- else
- return MPEG_START_RESUME;
- }
-
- rb->snprintf(resume_str, sizeof(resume_str), "Resume at: %s", hms_str);
-
struct menu_item items[] =
{
[MPEG_START_RESTART] =
@@ -567,50 +545,65 @@ enum mpeg_start_id mpeg_start_menu(uint32_t duration)
{ resume_str, NULL },
[MPEG_START_SEEK] =
{ "Set start time", NULL },
+ [MPEG_START_SETTINGS] =
+ { "Settings", NULL },
[MPEG_START_QUIT] =
{ "Quit mpegplayer", NULL },
};
+ ts_to_hms(settings.resume_time, &hms);
+ hms_format(hms_str, sizeof(hms_str), &hms);
+ format_menu_item(&items[MPEG_START_RESUME], sizeof (resume_str),
+ "Resume at: %s", hms_str);
- menu_id = menu_init(rb, items, sizeof(items) / sizeof(*items),
- NULL, NULL, NULL, NULL);
+ menu_id = menu_init(rb, items, ARRAYLEN(items),
+ mpeg_menu_sysevent_callback, NULL, NULL, NULL);
rb->button_clear_queue();
- while(menu_quit == 0)
+ while (!menu_quit)
{
+ mpeg_menu_sysevent_clear();
result = menu_show(menu_id);
switch (result)
{
- case MPEG_START_RESTART:
- settings.resume_time = 0;
- menu_quit = 1;
- break;
- case MPEG_START_RESUME:
- menu_quit = 1;
- break;
- case MPEG_START_SEEK:
+ case MPEG_START_RESTART:
+ settings.resume_time = 0;
+ menu_quit = true;
+ break;
+
+ case MPEG_START_RESUME:
+ menu_quit = true;
+ break;
+
+ case MPEG_START_SEEK:
+ if (!stream_can_seek())
{
- if (!stream_can_seek())
- {
- rb->splash(HZ, "Unavailable");
- break;
- }
-
- bool vis = stream_show_vo(false);
- if (get_start_time(duration) == MPEG_SELECT)
- menu_quit = 1;
- stream_show_vo(vis);
- break;
- }
- case MPEG_START_QUIT:
- menu_quit = 1;
+ rb->splash(HZ, "Unavailable");
break;
- default:
- result = MPEG_START_QUIT;
- menu_quit = 1;
+ }
+
+ result = get_start_time(duration);
+
+ if (result != MPEG_START_EXIT)
+ menu_quit = true;
+ break;
+
+ case MPEG_START_SETTINGS:
+ if (mpeg_menu(MPEG_MENU_HIDE_QUIT_ITEM) != MPEG_MENU_QUIT)
break;
+ /* Fall-through */
+ default:
+ result = MPEG_START_QUIT;
+ menu_quit = true;
+ break;
+ }
+
+ if (mpeg_menu_sysevent() != 0)
+ {
+ result = MPEG_START_QUIT;
+ menu_quit = true;
}
}
@@ -622,7 +615,116 @@ enum mpeg_start_id mpeg_start_menu(uint32_t duration)
return result;
}
-void clear_resume_count(void)
+/* Return the desired resume action */
+int mpeg_start_menu(uint32_t duration)
+{
+ mpeg_menu_sysevent_clear();
+
+ switch (settings.resume_options)
+ {
+ case MPEG_RESUME_MENU_IF_INCOMPLETE:
+ if (!stream_can_seek() || settings.resume_time == 0)
+ {
+ case MPEG_RESUME_RESTART:
+ settings.resume_time = 0;
+ return MPEG_START_RESTART;
+ }
+ default:
+ case MPEG_RESUME_MENU_ALWAYS:
+ return show_start_menu(duration);
+ case MPEG_RESUME_ALWAYS:
+ return MPEG_START_SEEK;
+ }
+}
+
+/** MPEG Menu **/
+static void display_options(void)
+{
+ int result;
+ int menu_id;
+ bool menu_quit = false;
+
+ static const struct menu_item items[] = {
+#if MPEG_OPTION_DITHERING_ENABLED
+ [MPEG_OPTION_DITHERING] =
+ { "Dithering", NULL },
+#endif
+ [MPEG_OPTION_DISPLAY_FPS] =
+ { "Display FPS", NULL },
+ [MPEG_OPTION_LIMIT_FPS] =
+ { "Limit FPS", NULL },
+ [MPEG_OPTION_SKIP_FRAMES] =
+ { "Skip frames", NULL },
+ };
+
+ menu_id = menu_init(rb, items, ARRAYLEN(items),
+ mpeg_menu_sysevent_callback, NULL, NULL, NULL);
+
+ rb->button_clear_queue();
+
+ while (!menu_quit)
+ {
+ mpeg_menu_sysevent_clear();
+ result = menu_show(menu_id);
+
+ switch (result)
+ {
+#if MPEG_OPTION_DITHERING_ENABLED
+ case MPEG_OPTION_DITHERING:
+ result = (settings.displayoptions & LCD_YUV_DITHER) ? 1 : 0;
+ mpeg_set_option("Dithering", &result, INT, noyes, 2, NULL);
+ settings.displayoptions =
+ (settings.displayoptions & ~LCD_YUV_DITHER)
+ | ((result != 0) ? LCD_YUV_DITHER : 0);
+ rb->lcd_yuv_set_options(settings.displayoptions);
+ break;
+#endif /* MPEG_OPTION_DITHERING_ENABLED */
+
+ case MPEG_OPTION_DISPLAY_FPS:
+ mpeg_set_option("Display FPS", &settings.showfps, INT,
+ noyes, 2, NULL);
+ break;
+
+ case MPEG_OPTION_LIMIT_FPS:
+ mpeg_set_option("Limit FPS", &settings.limitfps, INT,
+ noyes, 2, NULL);
+ break;
+
+ case MPEG_OPTION_SKIP_FRAMES:
+ mpeg_set_option("Skip frames", &settings.skipframes, INT,
+ noyes, 2, NULL);
+ break;
+
+ default:
+ menu_quit = true;
+ break;
+ }
+
+ if (mpeg_menu_sysevent() != 0)
+ menu_quit = true;
+ }
+
+ menu_exit(menu_id);
+}
+
+static void resume_options(void)
+{
+ static const struct opt_items items[MPEG_RESUME_NUM_OPTIONS] = {
+ [MPEG_RESUME_MENU_ALWAYS] =
+ { "Start menu", -1 },
+ [MPEG_RESUME_MENU_IF_INCOMPLETE] =
+ { "Start menu if not completed", -1 },
+ [MPEG_RESUME_ALWAYS] =
+ { "Resume automatically", -1 },
+ [MPEG_RESUME_RESTART] =
+ { "Play from beginning", -1 },
+ };
+
+ mpeg_set_option("Resume Options", &settings.resume_options,
+ INT, items, MPEG_RESUME_NUM_OPTIONS, NULL);
+}
+
+static void clear_resume_count(void)
{
configfile_save(SETTINGS_FILENAME, config, ARRAYLEN(config),
SETTINGS_VERSION);
@@ -633,58 +735,69 @@ void clear_resume_count(void)
configfile_update_entry(SETTINGS_FILENAME, "Resume count", 0);
}
-enum mpeg_menu_id mpeg_menu(void)
+int mpeg_menu(unsigned flags)
{
int menu_id;
int result;
- int menu_quit=0;
-
- /* add the clear resume option to the menu display */
+ bool menu_quit = false;
+ int item_count;
char clear_str[32];
- rb->snprintf(clear_str, sizeof(clear_str),
- "Clear all resumes: %u", settings.resume_count);
struct menu_item items[] = {
[MPEG_MENU_DISPLAY_SETTINGS] =
{ "Display Options", NULL },
[MPEG_MENU_ENABLE_START_MENU] =
- { "Start menu", NULL },
+ { "Resume Options", NULL },
[MPEG_MENU_CLEAR_RESUMES] =
{ clear_str, NULL },
[MPEG_MENU_QUIT] =
{ "Quit mpegplayer", NULL },
};
- menu_id = menu_init(rb, items, ARRAYLEN(items),
- NULL, NULL, NULL, NULL);
+ item_count = ARRAYLEN(items);
+
+ if (flags & MPEG_MENU_HIDE_QUIT_ITEM)
+ item_count--;
+
+ menu_id = menu_init(rb, items, item_count,
+ mpeg_menu_sysevent_callback, NULL, NULL, NULL);
rb->button_clear_queue();
- while (menu_quit == 0)
+ while (!menu_quit)
{
- result=menu_show(menu_id);
+ mpeg_menu_sysevent_clear();
+
+ /* Format and add resume option to the menu display */
+ format_menu_item(&items[MPEG_MENU_CLEAR_RESUMES], sizeof(clear_str),
+ "Clear all resumes: %u", settings.resume_count);
+
+ result = menu_show(menu_id);
- switch(result)
+ switch (result)
{
- case MPEG_MENU_DISPLAY_SETTINGS:
- display_options();
- break;
- case MPEG_MENU_ENABLE_START_MENU:
- rb->set_option("Start menu",
- &settings.enable_start_menu,
- INT, enabledisable, 2, NULL);
- break;
- case MPEG_MENU_CLEAR_RESUMES:
- clear_resume_count();
- rb->snprintf(clear_str, sizeof(clear_str),
- "Clear all resumes: %u", 0);
- break;
- case MPEG_MENU_QUIT:
- default:
- menu_quit=1;
- if (result == MENU_ATTACHED_USB)
- result = MPEG_MENU_QUIT;
- break;
+ case MPEG_MENU_DISPLAY_SETTINGS:
+ display_options();
+ break;
+
+ case MPEG_MENU_ENABLE_START_MENU:
+ resume_options();
+ break;
+
+ case MPEG_MENU_CLEAR_RESUMES:
+ clear_resume_count();
+ break;
+
+ case MPEG_MENU_QUIT:
+ default:
+ menu_quit = true;
+ break;
+ }
+
+ if (mpeg_menu_sysevent() != 0)
+ {
+ result = MPEG_MENU_QUIT;
+ menu_quit = true;
}
}
@@ -702,7 +815,7 @@ void init_settings(const char* filename)
settings.showfps = 0; /* Do not show FPS */
settings.limitfps = 1; /* Limit FPS */
settings.skipframes = 1; /* Skip frames */
- settings.enable_start_menu = 1; /* Enable start menu */
+ settings.resume_options = MPEG_RESUME_MENU_ALWAYS; /* Enable start menu */
settings.resume_count = -1;
#if MPEG_OPTION_DITHERING_ENABLED
settings.displayoptions = 0; /* No visual effects */
@@ -754,8 +867,8 @@ void save_settings(void)
settings.limitfps);
configfile_update_entry(SETTINGS_FILENAME, "Skip frames",
settings.skipframes);
- configfile_update_entry(SETTINGS_FILENAME, "Enable start menu",
- settings.enable_start_menu);
+ configfile_update_entry(SETTINGS_FILENAME, "Resume options",
+ settings.resume_options);
/* If this was a new resume entry then update the total resume count */
if (configfile_update_entry(SETTINGS_FILENAME, settings.resume_filename,
diff --git a/apps/plugins/mpegplayer/mpeg_settings.h b/apps/plugins/mpegplayer/mpeg_settings.h
index 3186c73..a55b2c3 100644
--- a/apps/plugins/mpegplayer/mpeg_settings.h
+++ b/apps/plugins/mpegplayer/mpeg_settings.h
@@ -1,6 +1,10 @@
#include "plugin.h"
+#define SETTINGS_VERSION 3
+#define SETTINGS_MIN_VERSION 1
+#define SETTINGS_FILENAME "mpegplayer.cfg"
+
#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) || defined(SANSA_C200)
#define MPEG_OPTION_DITHERING_ENABLED 1
#endif
@@ -19,12 +23,23 @@ enum mpeg_option_id
MPEG_OPTION_SKIP_FRAMES,
};
+enum mpeg_resume_id
+{
+ MPEG_RESUME_MENU_ALWAYS = 0,
+ MPEG_RESUME_MENU_IF_INCOMPLETE,
+ MPEG_RESUME_RESTART,
+ MPEG_RESUME_ALWAYS,
+ MPEG_RESUME_NUM_OPTIONS,
+};
+
enum mpeg_start_id
{
MPEG_START_RESTART,
MPEG_START_RESUME,
MPEG_START_SEEK,
+ MPEG_START_SETTINGS,
MPEG_START_QUIT,
+ MPEG_START_EXIT,
};
enum mpeg_menu_id
@@ -39,7 +54,7 @@ struct mpeg_settings {
int showfps; /* flag to display fps */
int limitfps; /* flag to limit fps */
int skipframes; /* flag to skip frames */
- int enable_start_menu; /* flag to enable/disable start menu */
+ int resume_options; /* type of resume action at start */
int resume_count; /* total # of resumes in config file */
int resume_time; /* resume time for current mpeg (in half minutes) */
char resume_filename[MAX_PATH]; /* filename of current mpeg */
@@ -50,9 +65,18 @@ struct mpeg_settings {
extern struct mpeg_settings settings;
-int get_start_time(uint32_t duration);
-enum mpeg_start_id mpeg_start_menu(uint32_t duration);
-enum mpeg_menu_id mpeg_menu(void);
+int mpeg_start_menu(uint32_t duration);
+
+enum
+{
+ MPEG_MENU_HIDE_QUIT_ITEM = 0x1, /* Don't show the quit item */
+};
+
+int mpeg_menu(unsigned flags);
+void mpeg_menu_sysevent_clear(void);
+long mpeg_menu_sysevent(void);
+int mpeg_menu_sysevent_callback(int btn, int menu);
+void mpeg_menu_sysevent_handle(void);
+
void init_settings(const char* filename);
void save_settings(void);
-void clear_resume_count(void);
diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c
index 935634c..7c82ac5 100644
--- a/apps/plugins/mpegplayer/mpegplayer.c
+++ b/apps/plugins/mpegplayer/mpegplayer.c
@@ -822,6 +822,11 @@ static void wvs_refresh(int hint)
if (hint == WVS_REFRESH_DEFAULT) {
/* The default which forces no updates */
+ /* Make sure Rockbox doesn't turn off the player because of
+ too little activity */
+ if (wvs.status == WVS_STATUS_PLAYING)
+ rb->reset_poweroff_timer();
+
/* Redraw the current or possibly extract a new video frame */
if ((wvs.auto_refresh & WVS_REFRESH_VIDEO) &&
TIME_AFTER(tick, wvs.print_tick)) {
@@ -942,8 +947,6 @@ static void wvs_show(unsigned show)
/* Uncover clipped video area and redraw it */
wvs.flags &= ~WVS_SHOW;
- stream_vo_set_clip(NULL);
-
draw_clear_area(0, 0, wvs.width, wvs.height);
if (!(show & WVS_NODRAW)) {
@@ -951,7 +954,10 @@ static void wvs_show(unsigned show)
draw_update_rect(0, 0, wvs.width, wvs.height);
vo_unlock();
+ stream_vo_set_clip(NULL);
stream_draw_frame(false);
+ } else {
+ stream_vo_set_clip(NULL);
}
}
}
@@ -1180,14 +1186,20 @@ static void wvs_resume(void)
stream_resume();
}
-/* Stop playback - remember the resume point if not already stopped */
+/* Stop playback - remember the resume point if not closed */
static void wvs_stop(void)
{
+ uint32_t resume_time;
+
wvs_cancel_refresh(WVS_REFRESH_VIDEO | WVS_REFRESH_RESUME);
wvs_show(WVS_HIDE | WVS_NODRAW);
- if (stream_stop() != STREAM_STOPPED)
- settings.resume_time = stream_get_resume_time();
+ stream_stop();
+
+ resume_time = stream_get_resume_time();
+
+ if (resume_time != INVALID_TIMESTAMP)
+ settings.resume_time = resume_time;
}
/* Perform a seek if seeking is possible for this stream - if playing, a delay
@@ -1242,11 +1254,12 @@ static void button_loop(void)
/* Gently poll the video player for EOS and handle UI */
while (stream_status() != STREAM_STOPPED)
{
- int button = rb->button_get_w_tmo(WVS_MIN_UPDATE_INTERVAL);
+ int button;
- /* Make sure Rockbox doesn't turn off the player because of
- too little activity */
- rb->reset_poweroff_timer();
+ mpeg_menu_sysevent_clear();
+ button = rb->button_get_w_tmo(WVS_MIN_UPDATE_INTERVAL);
+
+ button = mpeg_menu_sysevent_callback(button, -1);
switch (button)
{
@@ -1288,7 +1301,7 @@ static void button_loop(void)
stream_show_vo(false);
backlight_use_settings(rb);
- result = mpeg_menu();
+ result = mpeg_menu(0);
/* The menu can change the font, so restore */
rb->lcd_setfont(FONT_SYSFIXED);
@@ -1298,6 +1311,7 @@ static void button_loop(void)
case MPEG_MENU_QUIT:
wvs_stop();
break;
+
default:
/* If not stopped, show video again */
if (state != STREAM_STOPPED) {
@@ -1316,6 +1330,7 @@ static void button_loop(void)
} /* MPEG_MENU: */
case MPEG_STOP:
+ case ACTION_STD_CANCEL:
{
wvs_stop();
break;
@@ -1349,16 +1364,11 @@ static void button_loop(void)
break;
} /* MPEG_RW: MPEG_FF: */
- case SYS_POWEROFF:
- case SYS_USB_CONNECTED:
- /* Stop and get the resume time before closing the file early */
- wvs_stop();
- stream_close();
- save_settings(); /* Save settings (if they have changed) */
- /* Fall-through */
default:
+ {
rb->default_event_handler(button);
break;
+ } /* default: */
}
rb->yield();
@@ -1428,6 +1438,8 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
save_settings(); /* Save settings (if they have changed) */
status = PLUGIN_OK;
+
+ mpeg_menu_sysevent_handle();
} else {
DEBUGF("Could not open %s\n", (char*)parameter);
switch (err)
diff --git a/apps/plugins/mpegplayer/stream_mgr.c b/apps/plugins/mpegplayer/stream_mgr.c
index 14457a7..b164254 100644
--- a/apps/plugins/mpegplayer/stream_mgr.c
+++ b/apps/plugins/mpegplayer/stream_mgr.c
@@ -133,7 +133,7 @@ void str_data_notify_received(struct stream *str)
static void stream_mgr_init_state(void)
{
stream_mgr.filename = NULL;
- stream_mgr.resume_time = 0;
+ stream_mgr.resume_time = INVALID_TIMESTAMP;
stream_mgr.seeked = false;
}
@@ -341,6 +341,26 @@ static uint32_t stream_seek_intl(uint32_t time, int whence,
return parser_seek_time(time);
}
+/* Store the resume time at the last seek/current clock point */
+static void stream_remember_resume_time(void)
+{
+ /* Assume invalidity */
+ stream_mgr.resume_time = 0;
+
+ if (stream_can_seek())
+ {
+ /* Read the current stream time or the last seeked position */
+ uint32_t start;
+ uint32_t time = stream_get_seek_time(&start);
+
+ if (time >= str_parser.start_pts && time < str_parser.end_pts)
+ {
+ /* Save the current stream time */
+ stream_mgr.resume_time = time - start;
+ }
+ }
+}
+
/* Handle STREAM_OPEN */
void stream_on_open(const char *filename)
{
@@ -396,11 +416,11 @@ static void stream_on_play(void)
/* Seek to initial position and set clock to that time */
/* Save the resume time */
- start = str_parser.last_seek_time - str_parser.start_pts;
- stream_mgr.resume_time = start;
+ stream_remember_resume_time();
/* Prepare seek to start point */
- start = stream_seek_intl(start, SEEK_SET, STREAM_STOPPED, NULL);
+ start = stream_seek_intl(stream_mgr.resume_time, SEEK_SET,
+ STREAM_STOPPED, NULL);
/* Sync and start - force buffer fill */
stream_start_playback(start, true);
@@ -485,21 +505,8 @@ static void stream_on_stop(bool reply)
/* Pause the clock */
pcm_output_play_pause(false);
- /* Assume invalidity */
- stream_mgr.resume_time = 0;
-
- if (stream_can_seek())
- {
- /* Read the current stream time or the last seeked position */
- uint32_t start;
- uint32_t time = stream_get_seek_time(&start);
-
- if (time >= str_parser.start_pts && time < str_parser.end_pts)
- {
- /* Save the current stream time */
- stream_mgr.resume_time = time - start;
- }
- }
+ /* Update the resume time info */
+ stream_remember_resume_time();
/* Not stopped = paused or playing */
stream_mgr.seeked = false;
@@ -555,6 +562,7 @@ static void stream_on_seek(struct stream_seek_data *skd)
}
time = stream_seek_intl(time, whence, stream_mgr.status, &buffer);
+ stream_remember_resume_time();
if (stream_mgr.status == STREAM_PLAYING)
{