summaryrefslogtreecommitdiffstats
path: root/player/command.c
diff options
context:
space:
mode:
Diffstat (limited to 'player/command.c')
-rw-r--r--player/command.c138
1 files changed, 105 insertions, 33 deletions
diff --git a/player/command.c b/player/command.c
index 0673ecb032..278f669fb2 100644
--- a/player/command.c
+++ b/player/command.c
@@ -18,7 +18,6 @@
#include <float.h>
#include <stdlib.h>
#include <inttypes.h>
-#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>
@@ -68,6 +67,7 @@
#include "options/path.h"
#include "screenshot.h"
#include "misc/dispatch.h"
+#include "misc/language.h"
#include "misc/node.h"
#include "misc/thread_pool.h"
#include "misc/thread_tools.h"
@@ -388,7 +388,7 @@ static char *cut_osd_list(struct MPContext *mpctx, char *text, int pos)
static char *format_delay(double time)
{
- return talloc_asprintf(NULL, "%d ms", (int)lrint(time * 1000));
+ return talloc_asprintf(NULL, "%.f ms", time * 1000);
}
// Property-option bridge. (Maps the property to the option with the same name.)
@@ -791,10 +791,10 @@ static int mp_property_percent_pos(void *ctx, struct m_property *prop,
};
return M_PROPERTY_OK;
case M_PROPERTY_PRINT: {
- int pos = get_percent_pos(mpctx);
+ double pos = get_current_pos_ratio(mpctx, false);
if (pos < 0)
return M_PROPERTY_UNAVAILABLE;
- *(char **)arg = talloc_asprintf(NULL, "%d", pos);
+ *(char **)arg = talloc_asprintf(NULL, "%.f", pos * 100);
return M_PROPERTY_OK;
}
}
@@ -820,7 +820,7 @@ static int mp_property_time_pos(void *ctx, struct m_property *prop,
queue_seek(mpctx, MPSEEK_ABSOLUTE, *(double *)arg, MPSEEK_DEFAULT, 0);
return M_PROPERTY_OK;
}
- return property_time(action, arg, get_current_time(mpctx));
+ return property_time(action, arg, get_playback_time(mpctx));
}
/// Current audio pts in seconds (R)
@@ -1463,10 +1463,10 @@ static int mp_property_demuxer_cache_duration(void *ctx, struct m_property *prop
struct demux_reader_state s;
demux_get_reader_state(mpctx->demuxer, &s);
- if (s.ts_duration < 0)
+ if (s.ts_info.duration < 0)
return M_PROPERTY_UNAVAILABLE;
- return m_property_double_ro(action, arg, s.ts_duration);
+ return m_property_double_ro(action, arg, s.ts_info.duration);
}
static int mp_property_demuxer_cache_time(void *ctx, struct m_property *prop,
@@ -1479,10 +1479,10 @@ static int mp_property_demuxer_cache_time(void *ctx, struct m_property *prop,
struct demux_reader_state s;
demux_get_reader_state(mpctx->demuxer, &s);
- if (s.ts_end == MP_NOPTS_VALUE)
+ if (s.ts_info.end == MP_NOPTS_VALUE)
return M_PROPERTY_UNAVAILABLE;
- return m_property_double_ro(action, arg, s.ts_end);
+ return m_property_double_ro(action, arg, s.ts_info.end);
}
static int mp_property_demuxer_cache_idle(void *ctx, struct m_property *prop,
@@ -1518,14 +1518,14 @@ static int mp_property_demuxer_cache_state(void *ctx, struct m_property *prop,
struct mpv_node *r = (struct mpv_node *)arg;
node_init(r, MPV_FORMAT_NODE_MAP, NULL);
- if (s.ts_end != MP_NOPTS_VALUE)
- node_map_add_double(r, "cache-end", s.ts_end);
+ if (s.ts_info.end != MP_NOPTS_VALUE)
+ node_map_add_double(r, "cache-end", s.ts_info.end);
- if (s.ts_reader != MP_NOPTS_VALUE)
- node_map_add_double(r, "reader-pts", s.ts_reader);
+ if (s.ts_info.reader != MP_NOPTS_VALUE)
+ node_map_add_double(r, "reader-pts", s.ts_info.reader);
- if (s.ts_duration >= 0)
- node_map_add_double(r, "cache-duration", s.ts_duration);
+ if (s.ts_info.duration >= 0)
+ node_map_add_double(r, "cache-duration", s.ts_info.duration);
node_map_add_flag(r, "eof", s.eof);
node_map_add_flag(r, "underrun", s.underrun);
@@ -1543,6 +1543,25 @@ static int mp_property_demuxer_cache_state(void *ctx, struct m_property *prop,
if (s.ts_last != MP_NOPTS_VALUE)
node_map_add_double(r, "debug-ts-last", s.ts_last);
+ struct mpv_node *stream_types =
+ node_map_add(r, "ts-per-stream", MPV_FORMAT_NODE_ARRAY);
+ for (int n = 0; n < STREAM_TYPE_COUNT; n++) {
+ struct demux_ctrl_ts_info ts = s.ts_per_stream[n];
+ if (ts.duration == -1)
+ continue;
+
+ struct mpv_node *st = node_array_add(stream_types, MPV_FORMAT_NODE_MAP);
+ node_map_add_string(st, "type",
+ n == STREAM_VIDEO ? "video" :
+ n == STREAM_AUDIO ? "audio" :
+ n == STREAM_SUB ? "subtitle" : "unknown");
+ node_map_add_double(st, "cache-duration", ts.duration);
+ if (ts.reader != MP_NOPTS_VALUE)
+ node_map_add_double(st, "reader-pts", ts.reader);
+ if (ts.end != MP_NOPTS_VALUE)
+ node_map_add_double(st, "cache-end", ts.end);
+ }
+
node_map_add_flag(r, "bof-cached", s.bof_cached);
node_map_add_flag(r, "eof-cached", s.eof_cached);
@@ -1651,7 +1670,7 @@ static int mp_property_volume(void *ctx, struct m_property *prop,
};
return M_PROPERTY_OK;
case M_PROPERTY_PRINT:
- *(char **)arg = talloc_asprintf(NULL, "%i", (int)opts->softvol_volume);
+ *(char **)arg = talloc_asprintf(NULL, "%.f", opts->softvol_volume);
return M_PROPERTY_OK;
}
@@ -2060,6 +2079,10 @@ static int get_track_entry(int item, int action, void *arg, void *ctx)
.unavailable = !has_rg},
{"replaygain-album-gain", SUB_PROP_FLOAT(rg.album_gain),
.unavailable = !has_rg},
+ {"dolby-vision-profile", SUB_PROP_INT(p.dv_profile),
+ .unavailable = !p.dovi},
+ {"dolby-vision-level", SUB_PROP_INT(p.dv_level),
+ .unavailable = !p.dovi},
{0}
};
@@ -2897,6 +2920,32 @@ static int mp_property_mouse_pos(void *ctx, struct m_property *prop,
return M_PROPERTY_NOT_IMPLEMENTED;
}
+static int get_touch_pos(int item, int action, void *arg, void *ctx)
+{
+ const int **pos = (const int **)ctx;
+ struct m_sub_property props[] = {
+ {"x", SUB_PROP_INT(pos[0][item])},
+ {"y", SUB_PROP_INT(pos[1][item])},
+ {"id", SUB_PROP_INT(pos[2][item])},
+ {0}
+ };
+
+ int r = m_property_read_sub(props, action, arg);
+ return r;
+}
+
+#define MAX_TOUCH_POINTS 10
+static int mp_property_touch_pos(void *ctx, struct m_property *prop,
+ int action, void *arg)
+{
+ MPContext *mpctx = ctx;
+ int xs[MAX_TOUCH_POINTS], ys[MAX_TOUCH_POINTS], ids[MAX_TOUCH_POINTS];
+ int count = mp_input_get_touch_pos(mpctx->input, MAX_TOUCH_POINTS, xs, ys, ids);
+ const int *pos[3] = {xs, ys, ids};
+ return m_property_read_list(action, arg, MPMIN(MAX_TOUCH_POINTS, count),
+ get_touch_pos, (void *)pos);
+}
+
/// Video fps (RO)
static int mp_property_fps(void *ctx, struct m_property *prop,
int action, void *arg)
@@ -3213,8 +3262,10 @@ static int mp_property_playlist(void *ctx, struct m_property *prop,
for (int n = 0; n < pl->num_entries; n++) {
struct playlist_entry *e = pl->entries[n];
+ res = talloc_strdup_append(res, pl->current == e ? list_current
+ : list_normal);
char *p = e->title;
- if (!p) {
+ if (!p || mpctx->opts->playlist_entry_name > 0) {
p = e->filename;
if (!mp_is_url(bstr0(p))) {
char *s = mp_basename(e->filename);
@@ -3222,8 +3273,11 @@ static int mp_property_playlist(void *ctx, struct m_property *prop,
p = s;
}
}
- const char *m = pl->current == e ? list_current : list_normal;
- res = talloc_asprintf_append(res, "%s%s\n", m, p);
+ if (!e->title || p == e->title || mpctx->opts->playlist_entry_name == 1) {
+ res = talloc_asprintf_append(res, "%s\n", p);
+ } else {
+ res = talloc_asprintf_append(res, "%s (%s)\n", e->title, p);
+ }
}
*(char **)arg =
@@ -3323,7 +3377,7 @@ static int mp_property_packet_bitrate(void *ctx, struct m_property *prop,
if (action == M_PROPERTY_PRINT) {
rate /= 1000;
if (rate < 1000) {
- *(char **)arg = talloc_asprintf(NULL, "%d kbps", (int)rate);
+ *(char **)arg = talloc_asprintf(NULL, "%.f kbps", rate);
} else {
*(char **)arg = talloc_asprintf(NULL, "%.3f Mbps", rate / 1000.0);
}
@@ -3587,6 +3641,12 @@ static int mp_property_option_info(void *ctx, struct m_property *prop,
break;
MP_TARRAY_APPEND(NULL, choices, num, (char *)desc.name);
}
+ if (objs->get_lavfi_filters) {
+ const char **filters = objs->get_lavfi_filters(choices);
+ for (int n = 0; filters[n]; n++) {
+ MP_TARRAY_APPEND(NULL, choices, num, (char *)filters[n]);
+ }
+ }
MP_TARRAY_APPEND(NULL, choices, num, NULL);
}
@@ -3595,6 +3655,7 @@ static int mp_property_option_info(void *ctx, struct m_property *prop,
{"type", SUB_PROP_STR(opt->type->name)},
{"set-from-commandline", SUB_PROP_BOOL(co->is_set_from_cmdline)},
{"set-locally", SUB_PROP_BOOL(co->is_set_locally)},
+ {"expects-file", SUB_PROP_BOOL(opt->flags & M_OPT_FILE)},
{"default-value", *opt, def},
{"min", SUB_PROP_DOUBLE(opt->min),
.unavailable = !(has_minmax && opt->min != DBL_MIN)},
@@ -4045,11 +4106,12 @@ static const struct m_property mp_properties_base[] = {
{"osd-ass-cc", mp_property_osd_ass},
{"mouse-pos", mp_property_mouse_pos},
+ {"touch-pos", mp_property_touch_pos},
// Subs
{"sid", property_switch_track, .priv = (void *)(const int[]){0, STREAM_SUB}},
{"secondary-sid", property_switch_track,
- .priv = (void *)(const int[]){1, STREAM_SUB}},
+ .priv = (void *)(const int[]){1, STREAM_SUB}},
{"sub-delay", mp_property_sub_delay, .priv = (void *)&(const int){0}},
{"secondary-sub-delay", mp_property_sub_delay,
.priv = (void *)&(const int){1}},
@@ -4182,7 +4244,7 @@ static const char *const *const mp_event_property_change[] = {
E(MP_EVENT_CHANGE_PLAYLIST, "playlist", "playlist-pos", "playlist-pos-1",
"playlist-count", "playlist/count", "playlist-current-pos",
"playlist-playing-pos"),
- E(MP_EVENT_INPUT_PROCESSED, "mouse-pos"),
+ E(MP_EVENT_INPUT_PROCESSED, "mouse-pos", "touch-pos"),
E(MP_EVENT_CORE_IDLE, "core-idle", "eof-reached"),
};
#undef E
@@ -4681,9 +4743,9 @@ static void cmd_overlay_add(void *pcmd)
int dw = cmd->args[9].v.i, dh = cmd->args[10].v.i;
if (dw <= 0)
- dw = w;
+ dw = w;
if (dh <= 0)
- dh = h;
+ dh = h;
if (strcmp(fmt, "bgra") != 0) {
MP_ERR(mpctx, "overlay-add: unsupported OSD format '%s'\n", fmt);
goto error;
@@ -5592,6 +5654,19 @@ static void cmd_expand_path(void *p)
};
}
+static void cmd_normalize_path(void *p)
+{
+ struct mp_cmd_ctx *cmd = p;
+ void *ctx = talloc_new(NULL);
+
+ cmd->result = (mpv_node){
+ .format = MPV_FORMAT_STRING,
+ .u.string = talloc_strdup(NULL, mp_normalize_path(ctx, cmd->args[0].v.s)),
+ };
+
+ talloc_free(ctx);
+}
+
static void cmd_escape_ass(void *p)
{
struct mp_cmd_ctx *cmd = p;
@@ -5941,7 +6016,7 @@ static void cmd_track_reload(void *p)
struct track *nt = mpctx->tracks[nt_num];
if (!nt->lang)
- nt->lang = mp_guess_lang_from_filename(nt, nt->external_filename);
+ nt->lang = bstrto0(nt, mp_guess_lang_from_filename(bstr0(nt->external_filename), NULL));
mp_switch_track(mpctx, nt->type, nt, 0);
print_track_list(mpctx, "Reloaded:");
@@ -6272,7 +6347,8 @@ static void cmd_script_binding(void *p)
target = space;
name = sep + 1;
}
- char state[3] = {'p', incmd->is_mouse_button ? 'm' : '-'};
+ char state[4] = {'p', incmd->is_mouse_button ? 'm' : '-',
+ incmd->canceled ? 'c' : '-'};
if (incmd->is_up_down)
state[0] = incmd->repeated ? 'r' : (incmd->is_up ? 'u' : 'd');
event.num_args = 5;
@@ -6712,6 +6788,7 @@ const struct mp_cmd_def mp_cmds[] = {
.is_noisy = true },
{ "expand-path", cmd_expand_path, { {"text", OPT_STRING(v.s)} },
.is_noisy = true },
+ { "normalize-path", cmd_normalize_path, { {"filename", OPT_STRING(v.s)} }},
{ "escape-ass", cmd_escape_ass, { {"text", OPT_STRING(v.s)} },
.is_noisy = true },
{ "show-progress", cmd_show_progress, .allow_auto_repeat = true,
@@ -7370,16 +7447,11 @@ void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags,
if (opt_ptr == &opts->play_dir) {
if (mpctx->play_dir != opts->play_dir) {
- // Some weird things for play_dir if we're at EOF.
- // 1. The option must be set before we seek.
- // 2. queue_seek can change the stop_play value; always keep the old one.
- int old_stop_play = mpctx->stop_play;
- if (old_stop_play == AT_END_OF_FILE)
+ // The option must be set before we seek if we're at EOF.
+ if (mpctx->stop_play == AT_END_OF_FILE)
mpctx->play_dir = opts->play_dir;
queue_seek(mpctx, MPSEEK_ABSOLUTE, get_current_time(mpctx),
MPSEEK_EXACT, 0);
- if (old_stop_play == AT_END_OF_FILE)
- mpctx->stop_play = old_stop_play;
}
}