From 48e10da5019d8103fdde96bca68d72ddb1d7f2ca Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 1 Dec 2013 02:07:32 +0100 Subject: command: add a revert_seek command As discussed on IRC. --- DOCS/man/en/input.rst | 6 ++++++ mpvcore/input/input.c | 1 + mpvcore/input/input.h | 1 + mpvcore/player/command.c | 39 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/DOCS/man/en/input.rst b/DOCS/man/en/input.rst index 0763b1d1e1..7d62784b97 100644 --- a/DOCS/man/en/input.rst +++ b/DOCS/man/en/input.rst @@ -86,6 +86,12 @@ List of Input Commands keyframes Always restart playback at keyframe boundaries (fast). +``revert_seek`` + Undoes the ``seek`` command, and some other commands that seek (but not + necessarily all of them). Calling this command once will jump to the + playback position before the seek. Calling it a second time undoes the + ``revert_seek`` command itself. + ``frame_step`` Play one frame, then pause. diff --git a/mpvcore/input/input.c b/mpvcore/input/input.c index 744d474919..b454d3f574 100644 --- a/mpvcore/input/input.c +++ b/mpvcore/input/input.c @@ -151,6 +151,7 @@ static const struct mp_cmd_def mp_cmds[] = { }, .allow_auto_repeat = true, }, + { MP_CMD_REVERT_SEEK, "revert_seek", }, { MP_CMD_QUIT, "quit", { OARG_INT(0) } }, { MP_CMD_QUIT_WATCH_LATER, "quit_watch_later", }, { MP_CMD_STOP, "stop", }, diff --git a/mpvcore/input/input.h b/mpvcore/input/input.h index 27db11705e..9e897abbbb 100644 --- a/mpvcore/input/input.h +++ b/mpvcore/input/input.h @@ -27,6 +27,7 @@ enum mp_command_type { MP_CMD_IGNORE, MP_CMD_SEEK, + MP_CMD_REVERT_SEEK, MP_CMD_QUIT, MP_CMD_QUIT_WATCH_LATER, MP_CMD_PLAYLIST_NEXT, diff --git a/mpvcore/player/command.c b/mpvcore/player/command.c index ae1ba3ca31..f6eb0b3c7a 100644 --- a/mpvcore/player/command.c +++ b/mpvcore/player/command.c @@ -32,6 +32,7 @@ #include "config.h" #include "talloc.h" #include "command.h" +#include "osdep/timer.h" #include "mpvcore/mp_common.h" #include "mpvcore/input/input.h" #include "stream/stream.h" @@ -75,6 +76,9 @@ struct command_ctx { int events; + double last_seek_time; + double last_seek_pts; + struct cycle_counter *cycle_counters; int num_cycle_counters; @@ -87,6 +91,16 @@ static int edit_filters(struct MPContext *mpctx, enum stream_type mediatype, static int set_filters(struct MPContext *mpctx, enum stream_type mediatype, struct m_obj_settings *new_chain); +// Call before a seek, in order to allow revert_seek to undo the seek. +static void mark_seek(struct MPContext *mpctx) +{ + struct command_ctx *cmd = mpctx->command_ctx; + double now = mp_time_sec(); + if (now > cmd->last_seek_time + 2.0 || cmd->last_seek_pts == MP_NOPTS_VALUE) + cmd->last_seek_pts = get_current_time(mpctx); + cmd->last_seek_time = now; +} + static char *format_bitrate(int rate) { return talloc_asprintf(NULL, "%d kbps", rate * 8 / 1000); @@ -397,6 +411,7 @@ static int mp_property_chapter(m_option_t *prop, int action, void *arg, } case M_PROPERTY_SWITCH: case M_PROPERTY_SET: ; + mark_seek(mpctx); int step_all; if (action == M_PROPERTY_SWITCH) { struct m_property_switch_arg *sarg = arg; @@ -2475,6 +2490,7 @@ static bool check_property_autorepeat(char *property, struct MPContext *mpctx) void run_command(MPContext *mpctx, mp_cmd_t *cmd) { + struct command_ctx *cmdctx = mpctx->command_ctx; struct MPOpts *opts = mpctx->opts; int osd_duration = opts->osd_duration; bool auto_osd = cmd->on_osd == MP_ON_OSD_AUTO; @@ -2500,6 +2516,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd) double v = cmd->args[0].v.d * cmd->scale; int abs = cmd->args[1].v.i; int exact = cmd->args[2].v.i; + mark_seek(mpctx); if (abs == 2) { // Absolute seek to a timestamp in seconds queue_seek(mpctx, MPSEEK_ABSOLUTE, v, exact); set_osd_function(mpctx, @@ -2518,6 +2535,20 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd) break; } + case MP_CMD_REVERT_SEEK: { + double oldpts = cmdctx->last_seek_pts; + if (oldpts != MP_NOPTS_VALUE) { + cmdctx->last_seek_pts = get_current_time(mpctx); + queue_seek(mpctx, MPSEEK_ABSOLUTE, oldpts, 1); + set_osd_function(mpctx, OSD_REW); + if (bar_osd) + mpctx->add_osd_seek_info |= OSD_SEEK_INFO_BAR; + if (msg_or_nobar_osd) + mpctx->add_osd_seek_info |= OSD_SEEK_INFO_TEXT; + } + break; + } + case MP_CMD_SET: { int r = mp_property_do(cmd->args[0].v.s, M_PROPERTY_SET_STRING, cmd->args[1].v.s, mpctx); @@ -2687,6 +2718,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd) // frame PTS and sub PTS rarely match exactly). Add some // rounding for the mess of it. a[0] += 0.01 * (a[1] > 0 ? 1 : -1); + mark_seek(mpctx); queue_seek(mpctx, MPSEEK_RELATIVE, a[0], 1); set_osd_function(mpctx, (a[0] > 0) ? OSD_FFW : OSD_REW); if (bar_osd) @@ -3137,7 +3169,10 @@ void command_uninit(struct MPContext *mpctx) void command_init(struct MPContext *mpctx) { - mpctx->command_ctx = talloc_zero(NULL, struct command_ctx); + mpctx->command_ctx = talloc(NULL, struct command_ctx); + *mpctx->command_ctx = (struct command_ctx){ + .last_seek_pts = MP_NOPTS_VALUE, + }; } // Notify that a property might have changed. @@ -3183,6 +3218,8 @@ void mp_flush_events(struct MPContext *mpctx) } if (name) handle_script_event(mpctx, name, ""); + if (event == MP_EVENT_START_FILE) + ctx->last_seek_pts = MP_NOPTS_VALUE; } } } -- cgit v1.2.3