summaryrefslogtreecommitdiffstats
path: root/core/command.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/command.c')
-rw-r--r--core/command.c105
1 files changed, 75 insertions, 30 deletions
diff --git a/core/command.c b/core/command.c
index 115ea9236f..d8a8882c26 100644
--- a/core/command.c
+++ b/core/command.c
@@ -328,6 +328,19 @@ static int mp_property_time_pos(m_option_t *prop, int action,
return M_PROPERTY_NOT_IMPLEMENTED;
}
+static int mp_property_remaining(m_option_t *prop, int action,
+ void *arg, MPContext *mpctx)
+{
+ double len = get_time_length(mpctx);
+ double pos = get_current_time(mpctx);
+ double start = get_start_time(mpctx);
+
+ if (!(int)len)
+ return M_PROPERTY_UNAVAILABLE;
+
+ return m_property_double_ro(prop, action, arg, len - (pos - start));
+}
+
/// Current chapter (RW)
static int mp_property_chapter(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
@@ -350,14 +363,11 @@ static int mp_property_chapter(m_option_t *prop, int action, void *arg,
case M_PROPERTY_SET: ;
int step_all = *(int *)arg - chapter;
chapter += step_all;
- double next_pts = 0;
- queue_seek(mpctx, MPSEEK_NONE, 0, 0);
- chapter = seek_chapter(mpctx, chapter, &next_pts);
- if (chapter >= 0) {
- if (next_pts > -1.0)
- queue_seek(mpctx, MPSEEK_ABSOLUTE, next_pts, 0);
- } else if (step_all > 0)
+ if (chapter >= get_chapter_count(mpctx) && step_all > 0) {
mpctx->stop_play = PT_NEXT_ENTRY;
+ } else {
+ mp_seek_chapter(mpctx, chapter);
+ }
return M_PROPERTY_OK;
}
return M_PROPERTY_NOT_IMPLEMENTED;
@@ -471,6 +481,17 @@ static int mp_property_angle(m_option_t *prop, int action, void *arg,
resync_audio_stream(sh_audio);
}
return M_PROPERTY_OK;
+ case M_PROPERTY_GET_TYPE: {
+ struct m_option opt = {
+ .name = prop->name,
+ .type = CONF_TYPE_INT,
+ .flags = CONF_RANGE,
+ .min = 1,
+ .max = angles,
+ };
+ *(struct m_option *)arg = opt;
+ return M_PROPERTY_OK;
+ }
}
return M_PROPERTY_NOT_IMPLEMENTED;
}
@@ -518,19 +539,15 @@ static int mp_property_pause(m_option_t *prop, int action, void *arg,
{
MPContext *mpctx = ctx;
- switch (action) {
- case M_PROPERTY_SET:
+ if (action == M_PROPERTY_SET) {
if (*(int *)arg) {
pause_player(mpctx);
} else {
unpause_player(mpctx);
}
return M_PROPERTY_OK;
- case M_PROPERTY_GET:
- *(int *)arg = mpctx->paused;
- return M_PROPERTY_OK;
}
- return M_PROPERTY_NOT_IMPLEMENTED;
+ return mp_property_generic_option(prop, action, arg, ctx);
}
static int mp_property_cache(m_option_t *prop, int action, void *arg,
@@ -741,7 +758,7 @@ static int property_switch_track(m_option_t *prop, int action, void *arg,
switch (action) {
case M_PROPERTY_GET:
- *(int *) arg = track ? track->user_tid : -1;
+ *(int *) arg = track ? track->user_tid : -2;
return M_PROPERTY_OK;
case M_PROPERTY_PRINT:
if (!track)
@@ -769,9 +786,8 @@ static int property_switch_track(m_option_t *prop, int action, void *arg,
case M_PROPERTY_SET:
mp_switch_track(mpctx, type, mp_track_by_tid(mpctx, type, *(int *)arg));
return M_PROPERTY_OK;
- default:
- return M_PROPERTY_NOT_IMPLEMENTED;
}
+ return mp_property_generic_option(prop, action, arg, mpctx);
}
/// Selected audio id (RW)
@@ -825,10 +841,12 @@ static int mp_property_program(m_option_t *prop, int action, void *arg,
"Selected program contains no audio or video streams!\n");
return M_PROPERTY_ERROR;
}
- mp_switch_track(mpctx, STREAM_AUDIO,
- find_track_by_demuxer_id(mpctx, STREAM_AUDIO, prog.aid));
mp_switch_track(mpctx, STREAM_VIDEO,
find_track_by_demuxer_id(mpctx, STREAM_VIDEO, prog.vid));
+ mp_switch_track(mpctx, STREAM_AUDIO,
+ find_track_by_demuxer_id(mpctx, STREAM_AUDIO, prog.aid));
+ mp_switch_track(mpctx, STREAM_SUB,
+ find_track_by_demuxer_id(mpctx, STREAM_VIDEO, prog.sid));
return M_PROPERTY_OK;
}
return M_PROPERTY_NOT_IMPLEMENTED;
@@ -1295,6 +1313,19 @@ static int mp_property_tv_color(m_option_t *prop, int action, void *arg,
#endif
+static int mp_property_alias(m_option_t *prop, int action, void *arg,
+ MPContext *mpctx)
+{
+ const char *real_property = prop->priv;
+ int r = mp_property_do(real_property, action, arg, mpctx);
+ if (action == M_PROPERTY_GET_TYPE && r >= 0) {
+ // Fix the property name
+ struct m_option *type = arg;
+ type->name = prop->name;
+ }
+ return r;
+}
+
// Use option-to-property-bridge. (The property and option have the same names.)
#define M_OPTION_PROPERTY(name) \
{(name), mp_property_generic_option, &m_option_type_dummy, 0, 0, 0, (name)}
@@ -1306,6 +1337,10 @@ static int mp_property_tv_color(m_option_t *prop, int action, void *arg,
#define M_OPTION_PROPERTY_CUSTOM_(name, handler, ...) \
{(name), (handler), &m_option_type_dummy, 0, 0, 0, (name), __VA_ARGS__}
+// Redirect a property name to another
+#define M_PROPERTY_ALIAS(name, real_property) \
+ {(name), mp_property_alias, &m_option_type_dummy, 0, 0, 0, (real_property)}
+
/// All properties available in MPlayer.
/** \ingroup Properties
*/
@@ -1341,6 +1376,7 @@ static const m_option_t mp_properties[] = {
M_OPT_RANGE, 0, 100, NULL },
{ "time-pos", mp_property_time_pos, CONF_TYPE_TIME,
M_OPT_MIN, 0, 0, NULL },
+ { "time-remaining", mp_property_remaining, CONF_TYPE_TIME },
{ "chapter", mp_property_chapter, CONF_TYPE_INT,
M_OPT_MIN, 0, 0, NULL },
M_OPTION_PROPERTY_CUSTOM("edition", mp_property_edition),
@@ -1349,12 +1385,10 @@ static const m_option_t mp_properties[] = {
{ "chapters", mp_property_chapters, CONF_TYPE_INT,
0, 0, 0, NULL },
{ "editions", mp_property_editions, CONF_TYPE_INT },
- { "angle", mp_property_angle, CONF_TYPE_INT,
- CONF_RANGE, -2, 10, NULL },
+ { "angle", mp_property_angle, &m_option_type_dummy },
{ "metadata", mp_property_metadata, CONF_TYPE_STRING_LIST,
0, 0, 0, NULL },
- { "pause", mp_property_pause, CONF_TYPE_FLAG,
- M_OPT_RANGE, 0, 1, NULL },
+ M_OPTION_PROPERTY_CUSTOM("pause", mp_property_pause),
{ "cache", mp_property_cache, CONF_TYPE_INT },
M_OPTION_PROPERTY("pts-association-mode"),
M_OPTION_PROPERTY("hr-seek"),
@@ -1375,8 +1409,7 @@ static const m_option_t mp_properties[] = {
0, 0, 0, NULL },
{ "channels", mp_property_channels, CONF_TYPE_INT,
0, 0, 0, NULL },
- { "audio", mp_property_audio, CONF_TYPE_INT,
- CONF_RANGE, -2, 65535, NULL },
+ M_OPTION_PROPERTY_CUSTOM("aid", mp_property_audio),
{ "balance", mp_property_balance, CONF_TYPE_FLOAT,
M_OPT_RANGE, -1, 1, NULL },
@@ -1419,14 +1452,12 @@ static const m_option_t mp_properties[] = {
0, 0, 0, NULL },
{ "aspect", mp_property_aspect, CONF_TYPE_FLOAT,
CONF_RANGE, 0, 10, NULL },
- { "video", mp_property_video, CONF_TYPE_INT,
- CONF_RANGE, -2, 65535, NULL },
+ M_OPTION_PROPERTY_CUSTOM("vid", mp_property_video),
{ "program", mp_property_program, CONF_TYPE_INT,
CONF_RANGE, -1, 65535, NULL },
// Subs
- { "sub", mp_property_sub, CONF_TYPE_INT,
- M_OPT_MIN, -1, 0, NULL },
+ M_OPTION_PROPERTY_CUSTOM("sid", mp_property_sub),
M_OPTION_PROPERTY_CUSTOM("sub-delay", mp_property_sub_delay),
M_OPTION_PROPERTY_CUSTOM("sub-pos", mp_property_sub_pos),
{ "sub-visibility", mp_property_sub_visibility, CONF_TYPE_FLAG,
@@ -1450,6 +1481,10 @@ static const m_option_t mp_properties[] = {
M_OPT_RANGE, -100, 100, .offset = TV_COLOR_HUE },
#endif
+ M_PROPERTY_ALIAS("video", "vid"),
+ M_PROPERTY_ALIAS("audio", "aid"),
+ M_PROPERTY_ALIAS("sub", "sid"),
+
{0},
};
@@ -1820,7 +1855,11 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
}
case MP_CMD_FRAME_STEP:
- add_step_frame(mpctx);
+ add_step_frame(mpctx, 1);
+ break;
+
+ case MP_CMD_FRAME_BACK_STEP:
+ add_step_frame(mpctx, -1);
break;
case MP_CMD_QUIT:
@@ -1828,6 +1867,12 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
mpctx->quit_player_rc = cmd->args[0].v.i;
break;
+ case MP_CMD_QUIT_WATCH_LATER:
+ mp_write_watch_later_conf(mpctx);
+ mpctx->stop_play = PT_QUIT;
+ mpctx->quit_player_rc = 0;
+ break;
+
case MP_CMD_PLAYLIST_NEXT:
case MP_CMD_PLAYLIST_PREV:
{
@@ -2287,7 +2332,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
pause_player(mpctx);
break;
case 3: // "pausing_toggle"
- if (mpctx->paused)
+ if (opts->pause)
unpause_player(mpctx);
else
pause_player(mpctx);