summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-12-01 02:07:32 +0100
committerwm4 <wm4@nowhere>2013-12-01 02:07:32 +0100
commit48e10da5019d8103fdde96bca68d72ddb1d7f2ca (patch)
tree4c52fefdd88307015a34167afcf7b2d460025bf3
parentb18f02d1ad5e5ce4031438f1cd0f1f3aaaf83003 (diff)
downloadmpv-48e10da5019d8103fdde96bca68d72ddb1d7f2ca.tar.bz2
mpv-48e10da5019d8103fdde96bca68d72ddb1d7f2ca.tar.xz
command: add a revert_seek command
As discussed on IRC.
-rw-r--r--DOCS/man/en/input.rst6
-rw-r--r--mpvcore/input/input.c1
-rw-r--r--mpvcore/input/input.h1
-rw-r--r--mpvcore/player/command.c39
4 files changed, 46 insertions, 1 deletions
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;
}
}
}