summaryrefslogtreecommitdiffstats
path: root/mpvcore
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-10-31 23:23:38 +0100
committerwm4 <wm4@nowhere>2013-10-31 23:30:14 +0100
commit71ded03123a704ddcbf018dcb0ec633475ccb04a (patch)
treebddcea247a2e2396fbf414168b25aac2a57316d7 /mpvcore
parent94542abf2e2ccb123cf3b0c9eef76a2290dd19b1 (diff)
downloadmpv-71ded03123a704ddcbf018dcb0ec633475ccb04a.tar.bz2
mpv-71ded03123a704ddcbf018dcb0ec633475ccb04a.tar.xz
command: add generic "multiply" command
Essentially works like "add".
Diffstat (limited to 'mpvcore')
-rw-r--r--mpvcore/input/input.c1
-rw-r--r--mpvcore/input/input.h1
-rw-r--r--mpvcore/m_option.c36
-rw-r--r--mpvcore/m_option.h4
-rw-r--r--mpvcore/player/command.c40
5 files changed, 82 insertions, 0 deletions
diff --git a/mpvcore/input/input.c b/mpvcore/input/input.c
index 5b74f1aa33..aaa9cc14df 100644
--- a/mpvcore/input/input.c
+++ b/mpvcore/input/input.c
@@ -216,6 +216,7 @@ static const mp_cmd_t mp_cmds[] = {
.optional = true,
.v.d = 1 },
}},
+ { MP_CMD_MULTIPLY, "multiply", { ARG_STRING, ARG_DOUBLE } },
{ MP_CMD_ENABLE_INPUT_SECTION, "enable_section", {
ARG_STRING,
diff --git a/mpvcore/input/input.h b/mpvcore/input/input.h
index 3e8da7eb75..b3e8ae9543 100644
--- a/mpvcore/input/input.h
+++ b/mpvcore/input/input.h
@@ -66,6 +66,7 @@ enum mp_command_type {
MP_CMD_RADIO_SET_FREQ,
MP_CMD_ADD,
MP_CMD_CYCLE,
+ MP_CMD_MULTIPLY,
MP_CMD_RADIO_STEP_FREQ,
MP_CMD_TV_STEP_FREQ,
MP_CMD_TV_START_SCAN,
diff --git a/mpvcore/m_option.c b/mpvcore/m_option.c
index cd88b4cdca..948e246956 100644
--- a/mpvcore/m_option.c
+++ b/mpvcore/m_option.c
@@ -346,6 +346,25 @@ static void add_int(const m_option_t *opt, void *val, double add, bool wrap)
*(int *)val = tmp;
}
+static void multiply_int64(const m_option_t *opt, void *val, double f)
+{
+ double v = *(int64_t *)val * f;
+ int64_t iv = v;
+ if (v < INT64_MIN)
+ iv = INT64_MIN;
+ if (v > INT64_MAX)
+ iv = INT64_MAX;
+ *(int64_t *)val = iv;
+ clamp_int64(opt, val);
+}
+
+static void multiply_int(const m_option_t *opt, void *val, double f)
+{
+ int64_t tmp = *(int *)val;
+ multiply_int64(opt, &tmp, f);
+ *(int *)val = MPCLAMP(tmp, INT_MIN, INT_MAX);
+}
+
const m_option_type_t m_option_type_int = {
.name = "Integer",
.size = sizeof(int),
@@ -353,6 +372,7 @@ const m_option_type_t m_option_type_int = {
.print = print_int,
.copy = copy_opt,
.add = add_int,
+ .multiply = multiply_int,
.clamp = clamp_int,
};
@@ -363,6 +383,7 @@ const m_option_type_t m_option_type_int64 = {
.print = print_int,
.copy = copy_opt,
.add = add_int64,
+ .multiply = multiply_int64,
.clamp = clamp_int64,
};
@@ -644,6 +665,12 @@ static void add_double(const m_option_t *opt, void *val, double add, bool wrap)
VAL(val) = v;
}
+static void multiply_double(const m_option_t *opt, void *val, double f)
+{
+ *(double *)val *= f;
+ clamp_double(opt, val);
+}
+
const m_option_type_t m_option_type_double = {
// double precision float or ratio (numerator[:/]denominator)
.name = "Double",
@@ -654,6 +681,7 @@ const m_option_type_t m_option_type_double = {
.copy = copy_opt,
.clamp = clamp_double,
.add = add_double,
+ .multiply = multiply_double,
};
#undef VAL
@@ -694,6 +722,13 @@ static void add_float(const m_option_t *opt, void *val, double add, bool wrap)
VAL(val) = tmp;
}
+static void multiply_float(const m_option_t *opt, void *val, double f)
+{
+ double tmp = VAL(val);
+ multiply_double(opt, &tmp, f);
+ VAL(val) = tmp;
+}
+
const m_option_type_t m_option_type_float = {
// floating point number or ratio (numerator[:/]denominator)
.name = "Float",
@@ -703,6 +738,7 @@ const m_option_type_t m_option_type_float = {
.pretty_print = print_float_f3,
.copy = copy_opt,
.add = add_float,
+ .multiply = multiply_float,
.clamp = clamp_float,
};
diff --git a/mpvcore/m_option.h b/mpvcore/m_option.h
index d357456f63..443412a035 100644
--- a/mpvcore/m_option.h
+++ b/mpvcore/m_option.h
@@ -273,6 +273,10 @@ struct m_option_type {
// the value is clipped, or wraps around to the opposite max/min.
void (*add)(const m_option_t *opt, void *val, double add, bool wrap);
+ // Multiply the value with the factor f. The callback must clip the result
+ // to the valid value range of the option.
+ void (*multiply)(const m_option_t *opt, void *val, double f);
+
// Clamp the value in val to the option's valid value range.
// Return values:
// M_OPT_OUT_OF_RANGE: val was invalid, and modified (clamped) to be valid
diff --git a/mpvcore/player/command.c b/mpvcore/player/command.c
index f393318fb6..172a799c03 100644
--- a/mpvcore/player/command.c
+++ b/mpvcore/player/command.c
@@ -2379,6 +2379,29 @@ static void overlay_uninit(struct MPContext *mpctx){}
#endif
+static int mp_property_multiply(char *property, double f, struct MPContext *mpctx)
+{
+ union m_option_value val = {0};
+ struct m_option opt = {0};
+ int r;
+
+ r = mp_property_do(property, M_PROPERTY_GET_TYPE, &opt, mpctx);
+ if (r != M_PROPERTY_OK)
+ return r;
+ assert(opt.type);
+
+ if (!opt.type->multiply)
+ return M_PROPERTY_NOT_IMPLEMENTED;
+
+ r = mp_property_do(property, M_PROPERTY_GET, &val, mpctx);
+ if (r != M_PROPERTY_OK)
+ return r;
+ opt.type->multiply(&opt, &val, f);
+ r = mp_property_do(property, M_PROPERTY_SET, &val, mpctx);
+ m_option_free(&opt, &val);
+ return r;
+}
+
// Whether this property should react to key events generated by auto-repeat.
static bool check_property_autorepeat(char *property, struct MPContext *mpctx)
{
@@ -2484,6 +2507,23 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
break;
}
+ case MP_CMD_MULTIPLY: {
+ char *property = cmd->args[0].v.s;
+ double f = cmd->args[1].v.d;
+ int r = mp_property_multiply(property, f, mpctx);
+
+ if (r == M_PROPERTY_OK || r == M_PROPERTY_UNAVAILABLE) {
+ show_property_osd(mpctx, property, cmd->on_osd);
+ } else if (r == M_PROPERTY_UNKNOWN) {
+ set_osd_msg(mpctx, OSD_MSG_TEXT, osdl, osd_duration,
+ "Unknown property: '%s'", property);
+ } else if (r <= 0) {
+ set_osd_msg(mpctx, OSD_MSG_TEXT, osdl, osd_duration,
+ "Failed to multiply property '%s' by %g", property, f);
+ }
+ break;
+ }
+
case MP_CMD_GET_PROPERTY: {
char *tmp;
int r = mp_property_do(cmd->args[0].v.s, M_PROPERTY_GET_STRING,