summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--options/m_property.c108
-rw-r--r--options/m_property.h35
-rw-r--r--player/command.c1105
-rw-r--r--player/command.h2
-rw-r--r--player/lua.c2
5 files changed, 687 insertions, 565 deletions
diff --git a/options/m_property.c b/options/m_property.c
index 9b3de3cc5d..015313036a 100644
--- a/options/m_property.c
+++ b/options/m_property.c
@@ -37,10 +37,6 @@
#include "common/msg.h"
#include "common/common.h"
-const struct m_option_type m_option_type_dummy = {
- .name = "Unknown",
-};
-
struct legacy_prop {
const char *old, *new;
};
@@ -84,18 +80,28 @@ static bool translate_legacy_property(struct mp_log *log, const char *name,
return true;
}
-static int do_action(const m_option_t *prop_list, const char *name,
+static struct m_property *m_property_list_find(const struct m_property *list,
+ const char *name)
+{
+ for (int n = 0; list && list[n].name; n++) {
+ if (strcmp(list[n].name, name) == 0)
+ return (struct m_property *)&list[n];
+ }
+ return NULL;
+}
+
+static int do_action(const struct m_property *prop_list, const char *name,
int action, void *arg, void *ctx)
{
const char *sep;
- const m_option_t *prop;
+ struct m_property *prop;
struct m_property_action_arg ka;
if ((sep = strchr(name, '/')) && sep[1]) {
int len = sep - name;
char base[len + 1];
memcpy(base, name, len);
base[len] = 0;
- prop = m_option_list_find(prop_list, base);
+ prop = m_property_list_find(prop_list, base);
ka = (struct m_property_action_arg) {
.key = sep + 1,
.action = action,
@@ -104,22 +110,14 @@ static int do_action(const m_option_t *prop_list, const char *name,
action = M_PROPERTY_KEY_ACTION;
arg = &ka;
} else
- prop = m_option_list_find(prop_list, name);
+ prop = m_property_list_find(prop_list, name);
if (!prop)
return M_PROPERTY_UNKNOWN;
- int (*control)(const m_option_t*, int, void*, void*) = prop->p;
- int r = control(prop, action, arg, ctx);
- if (action == M_PROPERTY_GET_TYPE && r < 0 &&
- prop->type != &m_option_type_dummy)
- {
- *(struct m_option *)arg = *prop;
- return M_PROPERTY_OK;
- }
- return r;
+ return prop->call(ctx, prop, action, arg);
}
// (as a hack, log can be NULL on read-only paths)
-int m_property_do(struct mp_log *log, const m_option_t *prop_list,
+int m_property_do(struct mp_log *log, const struct m_property *prop_list,
const char *in_name, int action, void *arg, void *ctx)
{
union m_option_value val = {0};
@@ -259,7 +257,7 @@ static void m_property_unkey(int *action, void **arg)
}
}
-static int m_property_do_bstr(const m_option_t *prop_list, bstr name,
+static int m_property_do_bstr(const struct m_property *prop_list, bstr name,
int action, void *arg, void *ctx)
{
char name0[64];
@@ -276,8 +274,8 @@ static void append_str(char **s, int *len, bstr append)
*len = *len + append.len;
}
-static int expand_property(const m_option_t *prop_list, char **ret, int *ret_len,
- bstr prop, bool silent_error, void *ctx)
+static int expand_property(const struct m_property *prop_list, char **ret,
+ int *ret_len, bstr prop, bool silent_error, void *ctx)
{
bool cond_yes = bstr_eatstart0(&prop, "?");
bool cond_no = !cond_yes && bstr_eatstart0(&prop, "!");
@@ -307,7 +305,7 @@ static int expand_property(const m_option_t *prop_list, char **ret, int *ret_len
return skip;
}
-char *m_properties_expand_string(const m_option_t *prop_list,
+char *m_properties_expand_string(const struct m_property *prop_list,
const char *str0, void *ctx)
{
char *ret = NULL;
@@ -364,67 +362,93 @@ char *m_properties_expand_string(const m_option_t *prop_list,
}
void m_properties_print_help_list(struct mp_log *log,
- const struct m_option* list)
+ const struct m_property *list)
{
int count = 0;
mp_info(log, "Name\n\n");
for (int i = 0; list[i].name; i++) {
- const m_option_t *opt = &list[i];
- mp_info(log, " %s\n", opt->name);
+ const struct m_property *p = &list[i];
+ mp_info(log, " %s\n", p->name);
count++;
}
mp_info(log, "\nTotal: %d properties\n", count);
}
-int m_property_int_ro(const m_option_t *prop, int action,
- void *arg, int var)
+int m_property_flag_ro(int action, void* arg, int var)
+{
+ switch (action) {
+ case M_PROPERTY_GET:
+ *(int *)arg = !!var;
+ return M_PROPERTY_OK;
+ case M_PROPERTY_GET_TYPE:
+ *(struct m_option *)arg = (struct m_option){.type = CONF_TYPE_FLAG};
+ return M_PROPERTY_OK;
+ }
+ return M_PROPERTY_NOT_IMPLEMENTED;
+}
+
+int m_property_int_ro(int action, void *arg, int var)
{
- if (action == M_PROPERTY_GET) {
+ switch (action) {
+ case M_PROPERTY_GET:
*(int *)arg = var;
return M_PROPERTY_OK;
+ case M_PROPERTY_GET_TYPE:
+ *(struct m_option *)arg = (struct m_option){.type = CONF_TYPE_INT};
+ return M_PROPERTY_OK;
}
return M_PROPERTY_NOT_IMPLEMENTED;
}
-int m_property_int64_ro(const struct m_option* prop, int action, void* arg,
- int64_t var)
+int m_property_int64_ro(int action, void* arg, int64_t var)
{
- if (action == M_PROPERTY_GET) {
+ switch (action) {
+ case M_PROPERTY_GET:
*(int64_t *)arg = var;
return M_PROPERTY_OK;
+ case M_PROPERTY_GET_TYPE:
+ *(struct m_option *)arg = (struct m_option){.type = CONF_TYPE_INT64};
+ return M_PROPERTY_OK;
}
return M_PROPERTY_NOT_IMPLEMENTED;
}
-int m_property_float_ro(const m_option_t *prop, int action,
- void *arg, float var)
+int m_property_float_ro(int action, void *arg, float var)
{
- if (action == M_PROPERTY_GET) {
+ switch (action) {
+ case M_PROPERTY_GET:
*(float *)arg = var;
return M_PROPERTY_OK;
+ case M_PROPERTY_GET_TYPE:
+ *(struct m_option *)arg = (struct m_option){.type = CONF_TYPE_FLOAT};
+ return M_PROPERTY_OK;
}
return M_PROPERTY_NOT_IMPLEMENTED;
}
-int m_property_double_ro(const m_option_t *prop, int action,
- void *arg, double var)
+int m_property_double_ro(int action, void *arg, double var)
{
- if (action == M_PROPERTY_GET) {
+ switch (action) {
+ case M_PROPERTY_GET:
*(double *)arg = var;
return M_PROPERTY_OK;
+ case M_PROPERTY_GET_TYPE:
+ *(struct m_option *)arg = (struct m_option){.type = CONF_TYPE_DOUBLE};
+ return M_PROPERTY_OK;
}
return M_PROPERTY_NOT_IMPLEMENTED;
}
-int m_property_strdup_ro(const struct m_option* prop, int action, void* arg,
- const char *var)
+int m_property_strdup_ro(int action, void* arg, const char *var)
{
- if (action == M_PROPERTY_GET) {
- if (!var)
- return M_PROPERTY_UNAVAILABLE;
+ switch (action) {
+ case M_PROPERTY_GET:
*(char **)arg = talloc_strdup(NULL, var);
return M_PROPERTY_OK;
+ case M_PROPERTY_GET_TYPE:
+ *(struct m_option *)arg = (struct m_option){.type = CONF_TYPE_STRING};
+ return M_PROPERTY_OK;
}
return M_PROPERTY_NOT_IMPLEMENTED;
}
diff --git a/options/m_property.h b/options/m_property.h
index 7ba2c5181d..78b3292fba 100644
--- a/options/m_property.h
+++ b/options/m_property.h
@@ -26,8 +26,6 @@
struct mp_log;
-extern const struct m_option_type m_option_type_dummy;
-
enum mp_property_action {
// Get the property type. This defines the fundamental data type read from
// or written to the property.
@@ -120,11 +118,22 @@ enum mp_property_return {
M_PROPERTY_INVALID_FORMAT = -4,
};
+struct m_property {
+ const char *name;
+ // ctx: opaque caller context, which the property might use
+ // prop: pointer to this struct
+ // action: one of enum mp_property_action
+ // arg: specific to the action
+ // returns: one of enum mp_property_return
+ int (*call)(void *ctx, struct m_property *prop, int action, void *arg);
+ void *priv;
+};
+
// Access a property.
// action: one of m_property_action
// ctx: opaque value passed through to property implementation
// returns: one of mp_property_return
-int m_property_do(struct mp_log *log, const struct m_option* prop_list,
+int m_property_do(struct mp_log *log, const struct m_property* prop_list,
const char* property_name, int action, void* arg, void *ctx);
// Given a path of the form "a/b/c", this function will set *prefix to "a",
@@ -135,7 +144,7 @@ bool m_property_split_path(const char *path, bstr *prefix, char **rem);
// Print a list of properties.
void m_properties_print_help_list(struct mp_log *log,
- const struct m_option* list);
+ const struct m_property *list);
// Expand a property string.
// This function allows to print strings containing property values.
@@ -149,20 +158,16 @@ void m_properties_print_help_list(struct mp_log *log,
// STR is recursively expanded using the same rules.
// "$$" can be used to escape "$", and "$}" to escape "}".
// "$>" disables parsing of "$" for the rest of the string.
-char* m_properties_expand_string(const struct m_option* prop_list,
+char* m_properties_expand_string(const struct m_property *prop_list,
const char *str, void *ctx);
// Trivial helpers for implementing properties.
-int m_property_int_ro(const struct m_option* prop, int action, void* arg,
- int var);
-int m_property_int64_ro(const struct m_option* prop, int action, void* arg,
- int64_t var);
-int m_property_float_ro(const struct m_option* prop, int action, void* arg,
- float var);
-int m_property_double_ro(const struct m_option* prop, int action, void* arg,
- double var);
-int m_property_strdup_ro(const struct m_option* prop, int action, void* arg,
- const char *var);
+int m_property_flag_ro(int action, void* arg, int var);
+int m_property_int_ro(int action, void* arg, int var);
+int m_property_int64_ro(int action, void* arg, int64_t var);
+int m_property_float_ro(int action, void* arg, float var);
+int m_property_double_ro(int action, void* arg, double var);
+int m_property_strdup_ro(int action, void* arg, const char *var);
struct m_sub_property {
// Name of the sub-property - this will be prefixed with the parent
diff --git a/player/command.c b/player/command.c
index 87c91f295e..85823371f3 100644
--- a/player/command.c
+++ b/player/command.c
@@ -129,11 +129,12 @@ static char *format_delay(double time)
return talloc_asprintf(NULL, "%d ms", ROUND(time * 1000));
}
-// Property-option bridge.
-static int mp_property_generic_option(struct m_option *prop, int action,
- void *arg, MPContext *mpctx)
+// Property-option bridge. (Maps the property to the option with the same name.)
+static int mp_property_generic_option(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
- char *optname = prop->priv;
+ MPContext *mpctx = ctx;
+ const char *optname = prop->name;
struct m_config_option *opt = m_config_get_co(mpctx->mconfig,
bstr0(optname));
void *valptr = opt->data;
@@ -153,9 +154,10 @@ static int mp_property_generic_option(struct m_option *prop, int action,
}
/// Playback speed (RW)
-static int mp_property_playback_speed(m_option_t *prop, int action,
- void *arg, MPContext *mpctx)
+static int mp_property_playback_speed(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
struct MPOpts *opts = mpctx->opts;
double orig_speed = opts->playback_speed;
switch (action) {
@@ -171,34 +173,36 @@ static int mp_property_playback_speed(m_option_t *prop, int action,
*(char **)arg = talloc_asprintf(NULL, "x %6.2f", orig_speed);
return M_PROPERTY_OK;
}
- return mp_property_generic_option(prop, action, arg, mpctx);
+ return mp_property_generic_option(mpctx, prop, action, arg);
}
/// filename with path (RO)
-static int mp_property_path(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_path(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
if (!mpctx->filename)
return M_PROPERTY_UNAVAILABLE;
- return m_property_strdup_ro(prop, action, arg, mpctx->filename);
+ return m_property_strdup_ro(action, arg, mpctx->filename);
}
-static int mp_property_filename(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_filename(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
if (!mpctx->filename)
return M_PROPERTY_UNAVAILABLE;
char *filename = talloc_strdup(NULL, mpctx->filename);
if (mp_is_url(bstr0(filename)))
mp_url_unescape_inplace(filename);
char *f = (char *)mp_basename(filename);
- int r = m_property_strdup_ro(prop, action, arg, f[0] ? f : filename);
+ int r = m_property_strdup_ro(action, arg, f[0] ? f : filename);
talloc_free(filename);
return r;
}
-static int mp_property_file_size(m_option_t *prop, int action, void *arg,
- void *ctx)
+static int mp_property_file_size(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
MPContext *mpctx = ctx;
if (!mpctx->stream)
@@ -208,54 +212,51 @@ static int mp_property_file_size(m_option_t *prop, int action, void *arg,
if (stream_control(mpctx->stream, STREAM_CTRL_GET_SIZE, &size) != STREAM_OK)
return M_PROPERTY_UNAVAILABLE;
- switch (action) {
- case M_PROPERTY_GET: {
- *(int64_t *)arg = size;
- return M_PROPERTY_OK;
- }
- case M_PROPERTY_PRINT: {
+ if (action == M_PROPERTY_PRINT) {
*(char **)arg = format_file_size(size);
return M_PROPERTY_OK;
}
- }
- return M_PROPERTY_NOT_IMPLEMENTED;
+ return m_property_int64_ro(action, arg, size);
}
-static int mp_property_media_title(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_media_title(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
char *name = NULL;
if (mpctx->resolve_result)
name = mpctx->resolve_result->title;
if (name && name[0])
- return m_property_strdup_ro(prop, action, arg, name);
+ return m_property_strdup_ro(action, arg, name);
if (mpctx->master_demuxer) {
name = demux_info_get(mpctx->master_demuxer, "title");
if (name && name[0])
- return m_property_strdup_ro(prop, action, arg, name);
+ return m_property_strdup_ro(action, arg, name);
struct stream *stream = mpctx->master_demuxer->stream;
if (stream_control(stream, STREAM_CTRL_GET_DISC_NAME, &name) > 0
&& name) {
- int r = m_property_strdup_ro(prop, action, arg, name);
+ int r = m_property_strdup_ro(action, arg, name);
talloc_free(name);
return r;
}
}
- return mp_property_filename(prop, action, arg, mpctx);
+ return mp_property_filename(ctx, prop, action, arg);
}
-static int mp_property_stream_path(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_stream_path(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
struct stream *stream = mpctx->stream;
if (!stream || !stream->url)
return M_PROPERTY_UNAVAILABLE;
- return m_property_strdup_ro(prop, action, arg, stream->url);
+ return m_property_strdup_ro(action, arg, stream->url);
}
-static int mp_property_stream_capture(m_option_t *prop, int action,
- void *arg, MPContext *mpctx)
+static int mp_property_stream_capture(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
if (!mpctx->stream)
return M_PROPERTY_UNAVAILABLE;
@@ -264,52 +265,54 @@ static int mp_property_stream_capture(m_option_t *prop, int action,
stream_set_capture_file(mpctx->stream, filename);
// fall through to mp_property_generic_option
}
- return mp_property_generic_option(prop, action, arg, mpctx);
+ return mp_property_generic_option(mpctx, prop, action, arg);
}
/// Demuxer name (RO)
-static int mp_property_demuxer(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_demuxer(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
struct demuxer *demuxer = mpctx->master_demuxer;
if (!demuxer)
return M_PROPERTY_UNAVAILABLE;
- return m_property_strdup_ro(prop, action, arg, demuxer->desc->name);
+ return m_property_strdup_ro(action, arg, demuxer->desc->name);
}
/// Position in the stream (RW)
-static int mp_property_stream_pos(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_stream_pos(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
struct stream *stream = mpctx->stream;
if (!stream)
return M_PROPERTY_UNAVAILABLE;
- switch (action) {
- case M_PROPERTY_GET:
- *(int64_t *) arg = stream_tell(stream);
- return M_PROPERTY_OK;
- case M_PROPERTY_SET:
+ if (action == M_PROPERTY_SET) {
stream_seek(stream, *(int64_t *) arg);
return M_PROPERTY_OK;
}
- return M_PROPERTY_NOT_IMPLEMENTED;
+ return m_property_int64_ro(action, arg, stream_tell(stream));
}
/// Stream end offset (RO)
-static int mp_property_stream_end(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_stream_end(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
- return mp_property_file_size(prop, action, arg, mpctx);
+ return mp_property_file_size(ctx, prop, action, arg);
}
// Does some magic to handle "<name>/full" as time formatted with milliseconds.
// Assumes prop is the type of the actual property.
-static int property_time(m_option_t *prop, int action, void *arg, double time)
+static int property_time(int action, void *arg, double time)
{
+ const struct m_option time_type = {.type = CONF_TYPE_TIME};
switch (action) {
case M_PROPERTY_GET:
*(double *)arg = time;
return M_PROPERTY_OK;
+ case M_PROPERTY_GET_TYPE:
+ *(struct m_option *)arg = time_type;
+ return M_PROPERTY_OK;
case M_PROPERTY_KEY_ACTION: {
struct m_property_action_arg *ka = arg;
@@ -324,7 +327,7 @@ static int property_time(m_option_t *prop, int action, void *arg, double time)
*(char **)ka->arg = mp_format_time(time, true);
return M_PROPERTY_OK;
case M_PROPERTY_GET_TYPE:
- *(struct m_option *)ka->arg = *prop;
+ *(struct m_option *)ka->arg = time_type;
return M_PROPERTY_OK;
}
}
@@ -333,9 +336,10 @@ static int property_time(m_option_t *prop, int action, void *arg, double time)
}
/// Current stream position in seconds (RO)
-static int mp_property_stream_time_pos(m_option_t *prop, int action,
- void *arg, MPContext *mpctx)
+static int mp_property_stream_time_pos(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
struct demuxer *demuxer = mpctx->demuxer;
if (!demuxer)
return M_PROPERTY_UNAVAILABLE;
@@ -343,57 +347,62 @@ static int mp_property_stream_time_pos(m_option_t *prop, int action,
if (pts == MP_NOPTS_VALUE)
return M_PROPERTY_UNAVAILABLE;
- return property_time(prop, action, arg, pts);
+ return property_time(action, arg, pts);
}
/// Media length in seconds (RO)
-static int mp_property_length(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_length(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
double len;
if (!(int) (len = get_time_length(mpctx)))
return M_PROPERTY_UNAVAILABLE;
- return property_time(prop, action, arg, len);
+ return property_time(action, arg, len);
}
-static int mp_property_avsync(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_avsync(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
if (!mpctx->d_audio || !mpctx->d_video)
return M_PROPERTY_UNAVAILABLE;
if (mpctx->last_av_difference == MP_NOPTS_VALUE)
return M_PROPERTY_UNAVAILABLE;
- return m_property_double_ro(prop, action, arg, mpctx->last_av_difference);
+ return m_property_double_ro(action, arg, mpctx->last_av_difference);
}
-static int mp_property_total_avsync_change(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_total_avsync_change(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
if (!mpctx->d_audio || !mpctx->d_video)
return M_PROPERTY_UNAVAILABLE;
if (mpctx->total_avsync_change == MP_NOPTS_VALUE)
return M_PROPERTY_UNAVAILABLE;
- return m_property_double_ro(prop, action, arg, mpctx->total_avsync_change);
+ return m_property_double_ro(action, arg, mpctx->total_avsync_change);
}
/// Late frames
-static int mp_property_drop_frame_cnt(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_drop_frame_cnt(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
if (!mpctx->d_video)
return M_PROPERTY_UNAVAILABLE;
- return m_property_int_ro(prop, action, arg, mpctx->drop_frame_cnt);
+ return m_property_int_ro(action, arg, mpctx->drop_frame_cnt);
}
/// Current position in percent (RW)
-static int mp_property_percent_pos(m_option_t *prop, int action,
- void *arg, MPContext *mpctx)
+static int mp_property_percent_pos(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
if (!mpctx->num_sources)
return M_PROPERTY_UNAVAILABLE;
@@ -410,6 +419,14 @@ static int mp_property_percent_pos(m_option_t *prop, int action,
*(double *)arg = pos;
return M_PROPERTY_OK;
}
+ case M_PROPERTY_GET_TYPE:
+ *(struct m_option *)arg = (struct m_option){
+ .type = CONF_TYPE_DOUBLE,
+ .flags = M_OPT_RANGE,
+ .min = 0,
+ .max = 100,
+ };
+ return M_PROPERTY_OK;
case M_PROPERTY_PRINT:
*(char **)arg = talloc_asprintf(NULL, "%d", get_percent_pos(mpctx));
return M_PROPERTY_OK;
@@ -417,19 +434,21 @@ static int mp_property_percent_pos(m_option_t *prop, int action,
return M_PROPERTY_NOT_IMPLEMENTED;
}
-static int mp_property_time_start(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_time_start(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
double start = get_start_time(mpctx);
if (start < 0)
return M_PROPERTY_UNAVAILABLE;
- return property_time(prop, action, arg, start);
+ return property_time(action, arg, start);
}
/// Current position in seconds (RW)
-static int mp_property_time_pos(m_option_t *prop, int action,
- void *arg, MPContext *mpctx)
+static int mp_property_time_pos(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
if (!mpctx->num_sources)
return M_PROPERTY_UNAVAILABLE;
@@ -437,7 +456,7 @@ static int mp_property_time_pos(m_option_t *prop, int action,
queue_seek(mpctx, MPSEEK_ABSOLUTE, *(double *)arg, 0, true);
return M_PROPERTY_OK;
}
- return property_time(prop, action, arg, get_current_time(mpctx));
+ return property_time(action, arg, get_current_time(mpctx));
}
static bool time_remaining(MPContext *mpctx, double *remaining)
@@ -451,31 +470,33 @@ static bool time_remaining(MPContext *mpctx, double *remaining)
return len > 0;
}
-static int mp_property_remaining(m_option_t *prop, int action,
- void *arg, MPContext *mpctx)
+static int mp_property_remaining(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
double remaining;
- if (!time_remaining(mpctx, &remaining))
+ if (!time_remaining(ctx, &remaining))
return M_PROPERTY_UNAVAILABLE;
- return property_time(prop, action, arg, remaining);
+ return property_time(action, arg, remaining);
}
-static int mp_property_playtime_remaining(m_option_t *prop, int action,
- void *arg, MPContext *mpctx)
+static int mp_property_playtime_remaining(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
double remaining;
if (!time_remaining(mpctx, &remaining))
return M_PROPERTY_UNAVAILABLE;
double speed = mpctx->opts->playback_speed;
- return property_time(prop, action, arg, remaining / speed);
+ return property_time(action, arg, remaining / speed);
}
/// Current BD/DVD title (RW)
-static int mp_property_disc_title(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_disc_title(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
struct demuxer *demuxer = mpctx->master_demuxer;
if (!demuxer || !demuxer->stream)
return M_PROPERTY_UNAVAILABLE;
@@ -487,29 +508,37 @@ static int mp_property_disc_title(m_option_t *prop, int action, void *arg,
return M_PROPERTY_UNAVAILABLE;
*(int*)arg = title;
return M_PROPERTY_OK;
+ case M_PROPERTY_GET_TYPE:
+ *(struct m_option *)arg = (struct m_option){
+ .type = CONF_TYPE_INT,
+ .flags = M_OPT_MIN,
+ .min = -1,
+ };
+ return M_PROPERTY_OK;
case M_PROPERTY_SET:
title = *(int*)arg;
if (stream_control(stream, STREAM_CTRL_SET_CURRENT_TITLE, &title) <= 0)
return M_PROPERTY_NOT_IMPLEMENTED;
return M_PROPERTY_OK;
- default:
- return M_PROPERTY_NOT_IMPLEMENTED;
}
+ return M_PROPERTY_NOT_IMPLEMENTED;
}
-static int mp_property_disc_menu(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_disc_menu(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
int state = mp_nav_in_menu(mpctx);
if (state < 0)
return M_PROPERTY_UNAVAILABLE;
- return m_property_int_ro(prop, action, arg, !!state);
+ return m_property_flag_ro(action, arg, !!state);
}
/// Current chapter (RW)
-static int mp_property_chapter(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_chapter(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
int chapter = get_current_chapter(mpctx);
if (chapter < -1)
return M_PROPERTY_UNAVAILABLE;
@@ -518,6 +547,14 @@ static int mp_property_chapter(m_option_t *prop, int action, void *arg,
case M_PROPERTY_GET:
*(int *) arg = chapter;
return M_PROPERTY_OK;
+ case M_PROPERTY_GET_TYPE:
+ *(struct m_option *)arg = (struct m_option){
+ .type = CONF_TYPE_INT,
+ .flags = M_OPT_MIN | M_OPT_MAX,
+ .min = -1,
+ .max = get_chapter_count(mpctx) - 1,
+ };
+ return M_PROPERTY_OK;
case M_PROPERTY_PRINT: {
*(char **) arg = chapter_display_name(mpctx, chapter);
return M_PROPERTY_OK;
@@ -571,9 +608,10 @@ static int get_chapter_entry(int item, int action, void *arg, void *ctx)
return r;
}
-static int mp_property_list_chapters(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_list_chapters(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
int count = get_chapter_count(mpctx);
if (action == M_PROPERTY_PRINT) {
int cur = mpctx->num_sources ? get_current_chapter(mpctx) : -1;
@@ -603,9 +641,10 @@ static int mp_property_list_chapters(m_option_t *prop, int action, void *arg,
return m_property_read_list(action, arg, count, get_chapter_entry, mpctx);
}
-static int mp_property_edition(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_edition(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
struct MPOpts *opts = mpctx->opts;
struct demuxer *demuxer = mpctx->master_demuxer;
if (!demuxer)
@@ -661,9 +700,10 @@ static int get_edition_entry(int item, int action, void *arg, void *ctx)
return m_property_read_sub(props, action, arg);
}
-static int property_list_editions(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int property_list_editions(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
struct demuxer *demuxer = mpctx->master_demuxer;
if (!demuxer)
return M_PROPERTY_UNAVAILABLE;
@@ -721,9 +761,10 @@ static struct mp_resolve_src *find_source(struct mp_resolve_result *res,
return res->srcs[src];
}
-static int mp_property_quvi_format(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_quvi_format(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
struct MPOpts *opts = mpctx->opts;
struct mp_resolve_result *res = mpctx->resolve_result;
if (!res || !res->num_srcs)
@@ -766,49 +807,53 @@ static int mp_property_quvi_format(m_option_t *prop, int action, void *arg,
}
}
char *fmt = res->srcs[pos]->encid;
- return mp_property_quvi_format(prop, M_PROPERTY_SET, &fmt, mpctx);
+ return mp_property_quvi_format(mpctx, prop, M_PROPERTY_SET, &fmt);
}
}
- return mp_property_generic_option(prop, action, arg, mpctx);
+ return mp_property_generic_option(mpctx, prop, action, arg);
}
/// Number of titles in BD/DVD
-static int mp_property_disc_titles(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_disc_titles(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
struct demuxer *demuxer = mpctx->master_demuxer;
unsigned int num_titles;
if (!demuxer || stream_control(demuxer->stream, STREAM_CTRL_GET_NUM_TITLES,
&num_titles) < 1)
return M_PROPERTY_UNAVAILABLE;
- return m_property_int_ro(prop, action, arg, num_titles);
+ return m_property_int_ro(action, arg, num_titles);
}
/// Number of chapters in file
-static int mp_property_chapters(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_chapters(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
if (!mpctx->num_sources)
return M_PROPERTY_UNAVAILABLE;
int count = get_chapter_count(mpctx);
- return m_property_int_ro(prop, action, arg, count);
+ return m_property_int_ro(action, arg, count);
}
-static int mp_property_editions(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_editions(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
struct demuxer *demuxer = mpctx->master_demuxer;
if (!demuxer)
return M_PROPERTY_UNAVAILABLE;
if (demuxer->num_editions <= 0)
return M_PROPERTY_UNAVAILABLE;
- return m_property_int_ro(prop, action, arg, demuxer->num_editions);
+ return m_property_int_ro(action, arg, demuxer->num_editions);
}
/// Current dvd angle (RW)
-static int mp_property_angle(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_angle(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
struct demuxer *demuxer = mpctx->master_demuxer;
int angle = -1;
int angles;
@@ -866,8 +911,7 @@ static int get_tag_entry(int item, int action, void *arg, void *ctx)
return m_property_read_sub(props, action, arg);
}
-static int tag_property(m_option_t *prop, int action, void *arg,
- struct mp_tags *tags)
+static int tag_property(int action, void *arg, struct mp_tags *tags)
{
switch (action) {
case M_PROPERTY_GET: {
@@ -935,30 +979,33 @@ static int tag_property(m_option_t *prop, int action, void *arg,
}
/// Demuxer meta data
-static int mp_property_metadata(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_metadata(void *ctx, struct m_property *prop,
+ int action, void *arg)
{
+ MPContext *mpctx = ctx;
struct demuxer *demuxer = mpctx->master_demuxer;
if (!demuxer)
return M_PROPERTY_UNAVAILABLE;
- return tag_property(prop, action, arg, demuxer->metadata);
+ return tag_property(action, arg, demuxer->metadata);
}
-static int mp_property_chapter_metadata(m_option_t *prop, int action, void *arg,
- MPContext *mpctx)
+static int mp_property_chapter_metadata(void *ctx, struct m_property *prop,
+ int action, void *arg)</