From 71ded03123a704ddcbf018dcb0ec633475ccb04a Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 31 Oct 2013 23:23:38 +0100 Subject: command: add generic "multiply" command Essentially works like "add". --- DOCS/man/en/input.rst | 3 +++ mpvcore/input/input.c | 1 + mpvcore/input/input.h | 1 + mpvcore/m_option.c | 36 ++++++++++++++++++++++++++++++++++++ mpvcore/m_option.h | 4 ++++ mpvcore/player/command.c | 40 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 85 insertions(+) diff --git a/DOCS/man/en/input.rst b/DOCS/man/en/input.rst index 67dbac07bf..5ba139e83b 100644 --- a/DOCS/man/en/input.rst +++ b/DOCS/man/en/input.rst @@ -112,6 +112,9 @@ List of Input Commands overflow, set the property back to the minimum, on underflow set it to the maximum. If ``up`` or ``down`` is omitted, assume ``up``. +``multiply `` + Multiplies the value of a property with the numeric factor. + ``speed_mult `` Multiply the ``speed`` property by the given value. 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, -- cgit v1.2.3