summaryrefslogtreecommitdiffstats
path: root/player/command.c
diff options
context:
space:
mode:
Diffstat (limited to 'player/command.c')
-rw-r--r--player/command.c100
1 files changed, 45 insertions, 55 deletions
diff --git a/player/command.c b/player/command.c
index ac97e1022d..f4c10d48b9 100644
--- a/player/command.c
+++ b/player/command.c
@@ -75,8 +75,6 @@ struct command_ctx {
double last_seek_pts;
double marked_pts;
- double prev_pts;
-
char **warned_deprecated;
int num_warned_deprecated;
@@ -220,7 +218,7 @@ static void mp_hook_add(struct MPContext *mpctx, char *client, char *name,
}
// Call before a seek, in order to allow revert-seek to undo the seek.
-static void mark_seek(struct MPContext *mpctx)
+void mark_seek(struct MPContext *mpctx)
{
struct command_ctx *cmd = mpctx->command_ctx;
double now = mp_time_sec();
@@ -431,11 +429,9 @@ static int mp_property_stream_path(void *ctx, struct m_property *prop,
int action, void *arg)
{
MPContext *mpctx = ctx;
- // demuxer->stream as well as stream->url are immutable -> ok to access
- struct stream *stream = mpctx->demuxer ? mpctx->demuxer->stream : NULL;
- if (!stream || !stream->url)
+ if (!mpctx->demuxer || !mpctx->demuxer->filename)
return M_PROPERTY_UNAVAILABLE;
- return m_property_strdup_ro(action, arg, stream->url);
+ return m_property_strdup_ro(action, arg, mpctx->demuxer->filename);
}
struct change_stream_capture_args {
@@ -649,7 +645,7 @@ static int mp_property_percent_pos(void *ctx, struct m_property *prop,
switch (action) {
case M_PROPERTY_SET: {
double pos = *(double *)arg;
- queue_seek(mpctx, MPSEEK_FACTOR, pos / 100.0, MPSEEK_DEFAULT, true);
+ queue_seek(mpctx, MPSEEK_FACTOR, pos / 100.0, MPSEEK_DEFAULT, 0);
return M_PROPERTY_OK;
}
case M_PROPERTY_GET: {
@@ -694,7 +690,7 @@ static int mp_property_time_pos(void *ctx, struct m_property *prop,
return M_PROPERTY_UNAVAILABLE;
if (action == M_PROPERTY_SET) {
- queue_seek(mpctx, MPSEEK_ABSOLUTE, *(double *)arg, MPSEEK_DEFAULT, true);
+ queue_seek(mpctx, MPSEEK_ABSOLUTE, *(double *)arg, MPSEEK_DEFAULT, 0);
return M_PROPERTY_OK;
}
return property_time(action, arg, get_current_time(mpctx));
@@ -743,7 +739,7 @@ static int mp_property_playback_time(void *ctx, struct m_property *prop,
return M_PROPERTY_UNAVAILABLE;
if (action == M_PROPERTY_SET) {
- queue_seek(mpctx, MPSEEK_ABSOLUTE, *(double *)arg, MPSEEK_DEFAULT, true);
+ queue_seek(mpctx, MPSEEK_ABSOLUTE, *(double *)arg, MPSEEK_DEFAULT, 0);
return M_PROPERTY_OK;
}
return property_time(action, arg, get_playback_time(mpctx));
@@ -844,7 +840,7 @@ static int mp_property_chapter(void *ctx, struct m_property *prop,
} else {
double pts = chapter_start_time(mpctx, chapter);
if (pts != MP_NOPTS_VALUE) {
- queue_seek(mpctx, MPSEEK_ABSOLUTE, pts, MPSEEK_DEFAULT, true);
+ queue_seek(mpctx, MPSEEK_ABSOLUTE, pts, MPSEEK_DEFAULT, 0);
mpctx->last_chapter_seek = chapter;
mpctx->last_chapter_pts = pts;
}
@@ -2210,7 +2206,7 @@ static int mp_property_hwdec(void *ctx, struct m_property *prop,
video_vd_control(vd, VDCTRL_REINIT, NULL);
double last_pts = mpctx->last_vo_pts;
if (last_pts != MP_NOPTS_VALUE)
- queue_seek(mpctx, MPSEEK_ABSOLUTE, last_pts, MPSEEK_EXACT, true);
+ queue_seek(mpctx, MPSEEK_ABSOLUTE, last_pts, MPSEEK_EXACT, 0);
}
return M_PROPERTY_OK;
}
@@ -3194,10 +3190,30 @@ static int mp_property_playlist_pos_1(void *ctx, struct m_property *prop,
return mp_property_playlist_pos_x(ctx, prop, action, arg, 1);
}
+struct get_playlist_ctx {
+ struct MPContext *mpctx;
+ int last_index;
+ struct playlist_entry *last_entry;
+};
+
static int get_playlist_entry(int item, int action, void *arg, void *ctx)
{
- struct MPContext *mpctx = ctx;
- struct playlist_entry *e = playlist_entry_from_index(mpctx->playlist, item);
+ struct get_playlist_ctx *p = ctx;
+ struct MPContext *mpctx = p->mpctx;
+
+ struct playlist_entry *e;
+ // This is an optimization that prevents O(n^2) behaviour when the entire
+ // playlist is requested. If a request is made for the last requested entry
+ // or the entry immediately following it, it can be found without a full
+ // traversal of the linked list.
+ if (p->last_entry && item == p->last_index)
+ e = p->last_entry;
+ else if (p->last_entry && item == p->last_index + 1)
+ e = p->last_entry->next;
+ else
+ e = playlist_entry_from_index(mpctx->playlist, item);
+ p->last_index = item;
+ p->last_entry = e;
if (!e)
return M_PROPERTY_ERROR;
@@ -3237,8 +3253,10 @@ static int mp_property_playlist(void *ctx, struct m_property *prop,
*(char **)arg = res;
return M_PROPERTY_OK;
}
+
+ struct get_playlist_ctx p = { .mpctx = mpctx };
return m_property_read_list(action, arg, playlist_entry_count(mpctx->playlist),
- get_playlist_entry, mpctx);
+ get_playlist_entry, &p);
}
static char *print_obj_osd_list(struct m_obj_settings *list)
@@ -3301,9 +3319,11 @@ static int mp_property_ab_loop(void *ctx, struct m_property *prop,
}
int r = mp_property_generic_option(mpctx, prop, action, arg);
if (r > 0 && action == M_PROPERTY_SET) {
+ mpctx->ab_loop_clip = mpctx->playback_pts < opts->ab_loop[1];
if (strcmp(prop->name, "ab-loop-b") == 0) {
- struct command_ctx *cctx = mpctx->command_ctx;
- cctx->prev_pts = opts->ab_loop[0];
+ if (opts->ab_loop[1] != MP_NOPTS_VALUE &&
+ mpctx->playback_pts <= opts->ab_loop[1])
+ mpctx->ab_loop_clip = true;
}
// Update if visible
set_osd_bar_chapters(mpctx, OSD_BAR_SEEK);
@@ -4622,19 +4642,19 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re
mark_seek(mpctx);
switch (abs) {
case 0: { // Relative seek
- queue_seek(mpctx, MPSEEK_RELATIVE, v, precision, false);
+ queue_seek(mpctx, MPSEEK_RELATIVE, v, precision, MPSEEK_FLAG_DELAY);
set_osd_function(mpctx, (v > 0) ? OSD_FFW : OSD_REW);
break;
}
case 1: { // Absolute seek by percentage
double ratio = v / 100.0;
double cur_pos = get_current_pos_ratio(mpctx, false);
- queue_seek(mpctx, MPSEEK_FACTOR, ratio, precision, false);
+ queue_seek(mpctx, MPSEEK_FACTOR, ratio, precision, MPSEEK_FLAG_DELAY);
set_osd_function(mpctx, cur_pos < ratio ? OSD_FFW : OSD_REW);
break;
}
case 2: { // Absolute seek to a timestamp in seconds
- queue_seek(mpctx, MPSEEK_ABSOLUTE, v, precision, false);
+ queue_seek(mpctx, MPSEEK_ABSOLUTE, v, precision, MPSEEK_FLAG_DELAY);
set_osd_function(mpctx,
v > get_current_time(mpctx) ? OSD_FFW : OSD_REW);
break;
@@ -4642,7 +4662,7 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re
case 3: { // Relative seek by percentage
queue_seek(mpctx, MPSEEK_FACTOR,
get_current_pos_ratio(mpctx, false) + v / 100.0,
- precision, false);
+ precision, MPSEEK_FLAG_DELAY);
set_osd_function(mpctx, v > 0 ? OSD_FFW : OSD_REW);
break;
}}
@@ -4664,7 +4684,8 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re
} else if (oldpts != MP_NOPTS_VALUE) {
cmdctx->last_seek_pts = get_current_time(mpctx);
cmdctx->marked_pts = MP_NOPTS_VALUE;
- queue_seek(mpctx, MPSEEK_ABSOLUTE, oldpts, MPSEEK_EXACT, false);
+ queue_seek(mpctx, MPSEEK_ABSOLUTE, oldpts, MPSEEK_EXACT,
+ MPSEEK_FLAG_DELAY);
set_osd_function(mpctx, OSD_REW);
if (bar_osd)
mpctx->add_osd_seek_info |= OSD_SEEK_INFO_BAR;
@@ -4850,7 +4871,8 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re
// 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], MPSEEK_EXACT, false);
+ queue_seek(mpctx, MPSEEK_RELATIVE, a[0], MPSEEK_EXACT,
+ MPSEEK_FLAG_DELAY);
set_osd_function(mpctx, (a[0] > 0) ? OSD_FFW : OSD_REW);
if (bar_osd)
mpctx->add_osd_seek_info |= OSD_SEEK_INFO_BAR;
@@ -5373,7 +5395,6 @@ void command_init(struct MPContext *mpctx)
mpctx->command_ctx = talloc(NULL, struct command_ctx);
*mpctx->command_ctx = (struct command_ctx){
.last_seek_pts = MP_NOPTS_VALUE,
- .prev_pts = MP_NOPTS_VALUE,
};
}
@@ -5386,8 +5407,6 @@ static void command_event(struct MPContext *mpctx, int event, void *arg)
ctx->marked_pts = MP_NOPTS_VALUE;
}
- if (event == MPV_EVENT_SEEK)
- ctx->prev_pts = MP_NOPTS_VALUE;
if (event == MPV_EVENT_IDLE)
ctx->is_idle = true;
if (event == MPV_EVENT_START_FILE)
@@ -5398,35 +5417,6 @@ static void command_event(struct MPContext *mpctx, int event, void *arg)
}
}
-void handle_ab_loop(struct MPContext *mpctx)
-{
- struct command_ctx *ctx = mpctx->command_ctx;
- struct MPOpts *opts = mpctx->opts;
-
- if (opts->pause)
- return;
-
- double now = mpctx->restart_complete ? mpctx->playback_pts : MP_NOPTS_VALUE;
- if (now != MP_NOPTS_VALUE && (opts->ab_loop[0] != MP_NOPTS_VALUE ||
- opts->ab_loop[1] != MP_NOPTS_VALUE))
- {
- double start = opts->ab_loop[0];
- if (start == MP_NOPTS_VALUE)
- start = 0;
- double end = opts->ab_loop[1];
- if (end == MP_NOPTS_VALUE)
- end = INFINITY;
- if (ctx->prev_pts >= start && ctx->prev_pts < end &&
- (now >= end || mpctx->stop_play == AT_END_OF_FILE))
- {
- mark_seek(mpctx);
- queue_seek(mpctx, MPSEEK_ABSOLUTE, start,
- MPSEEK_EXACT, false);
- }
- }
- ctx->prev_pts = now;
-}
-
void handle_command_updates(struct MPContext *mpctx)
{
struct command_ctx *ctx = mpctx->command_ctx;