diff options
Diffstat (limited to 'core/command.c')
-rw-r--r-- | core/command.c | 105 |
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); |