diff --git a/audio/mixer.c b/audio/mixer.c index 7a26b83e5e..b19a2c6438 100644 --- a/audio/mixer.c +++ b/audio/mixer.c @@ -68,6 +68,12 @@ bool mixer_audio_initialized(struct mixer *mixer) return !!mixer->ao; } +float mixer_getneutralvolume(struct mixer *mixer) +{ + // gain == 1 + return 1.0 / mixer->opts->softvol_max * 100.0 * 100.0; +} + static void checkvolume(struct mixer *mixer) { if (!mixer->ao) diff --git a/audio/mixer.h b/audio/mixer.h index d5ec07e9ba..1716401dd5 100644 --- a/audio/mixer.h +++ b/audio/mixer.h @@ -45,6 +45,7 @@ void mixer_setmute(struct mixer *mixer, bool mute); bool mixer_getmute(struct mixer *mixer); void mixer_getbalance(struct mixer *mixer, float *bal); void mixer_setbalance(struct mixer *mixer, float bal); +float mixer_getneutralvolume(struct mixer *mixer); char *mixer_get_volume_restore_data(struct mixer *mixer); #endif /* MPLAYER_MIXER_H */ diff --git a/options/m_property.h b/options/m_property.h index 808066dde6..7ba2c5181d 100644 --- a/options/m_property.h +++ b/options/m_property.h @@ -79,6 +79,11 @@ enum mp_property_action { // Pass down an action to a sub-property. // arg: struct m_property_action_arg* M_PROPERTY_KEY_ACTION, + + // Get the (usually constant) value that indicates no change. Obscure + // special functionality for things like the volume property. + // Otherwise works like M_PROPERTY_GET. + M_PROPERTY_GET_NEUTRAL, }; // Argument for M_PROPERTY_SWITCH diff --git a/player/command.c b/player/command.c index e9f71ebf41..e2788b76be 100644 --- a/player/command.c +++ b/player/command.c @@ -1104,6 +1104,9 @@ static int mp_property_volume(m_option_t *prop, int action, void *arg, case M_PROPERTY_GET: mixer_getbothvolume(mpctx->mixer, arg); return M_PROPERTY_OK; + case M_PROPERTY_GET_NEUTRAL: + *(float *)arg = mixer_getneutralvolume(mpctx->mixer); + return M_PROPERTY_OK; case M_PROPERTY_PRINT: { float val; mixer_getbothvolume(mpctx->mixer, &val); @@ -1823,6 +1826,9 @@ static int mp_property_video_color(m_option_t *prop, int action, void *arg, // Write new value to option variable mp_property_generic_option(prop, M_PROPERTY_SET, arg, mpctx); return M_PROPERTY_OK; + case M_PROPERTY_GET_NEUTRAL: + *(int *)arg = 0; + return M_PROPERTY_OK; } return mp_property_generic_option(prop, action, arg, mpctx); } @@ -2724,15 +2730,19 @@ static void show_property_osd(MPContext *mpctx, const char *pname, int osd_mode) if (osd_progbar && (prop.flags & CONF_RANGE) == CONF_RANGE) { bool ok = false; if (prop.type == CONF_TYPE_INT) { + int n = prop.min; + mp_property_do(name, M_PROPERTY_GET_NEUTRAL, &n, mpctx); int i; ok = mp_property_do(name, M_PROPERTY_GET, &i, mpctx) > 0; if (ok) - set_osd_bar(mpctx, osd_progbar, osd_name, prop.min, prop.max, i); + set_osd_bar(mpctx, osd_progbar, osd_name, prop.min, prop.max, n, i); } else if (prop.type == CONF_TYPE_FLOAT) { + float n = prop.min; + mp_property_do(name, M_PROPERTY_GET_NEUTRAL, &n, mpctx); float f; ok = mp_property_do(name, M_PROPERTY_GET, &f, mpctx) > 0; if (ok) - set_osd_bar(mpctx, osd_progbar, osd_name, prop.min, prop.max, f); + set_osd_bar(mpctx, osd_progbar, osd_name, prop.min, prop.max, n, f); } if (ok && osd_mode == MP_ON_OSD_AUTO && opts->osd_bar_visible) msg = NULL; diff --git a/player/core.h b/player/core.h index ca61ab8f11..5f4789d267 100644 --- a/player/core.h +++ b/player/core.h @@ -423,7 +423,7 @@ void stream_dump(struct MPContext *mpctx); // osd.c void print_status(struct MPContext *mpctx); void set_osd_bar(struct MPContext *mpctx, int type, const char* name, - double min, double max, double val); + double min, double max, double neutral, double val); void set_osd_msg(struct MPContext *mpctx, int level, int time, const char* fmt, ...) PRINTF_ATTRIBUTE(4,5); void set_osd_function(struct MPContext *mpctx, int osd_function); diff --git a/player/osd.c b/player/osd.c index 57dd4aff97..32533eac1d 100644 --- a/player/osd.c +++ b/player/osd.c @@ -332,8 +332,8 @@ static mp_osd_msg_t *get_osd_msg(struct MPContext *mpctx) // type: mp_osd_font_codepoints, ASCII, or OSD_BAR_* // name: fallback for terminal OSD -void set_osd_bar(struct MPContext *mpctx, int type, const char *name, - double min, double max, double val) +void set_osd_bar(struct MPContext *mpctx, int type, const char* name, + double min, double max, double neutral, double val) { struct MPOpts *opts = mpctx->opts; if (opts->osd_level < 1 || !opts->osd_bar_visible) @@ -344,6 +344,11 @@ void set_osd_bar(struct MPContext *mpctx, int type, const char *name, mpctx->osd_progbar.type = type; mpctx->osd_progbar.value = (val - min) / (max - min); mpctx->osd_progbar.num_stops = 0; + if (neutral > min && neutral < max) { + float pos = (neutral - min) / (max - min); + MP_TARRAY_APPEND(mpctx, mpctx->osd_progbar.stops, + mpctx->osd_progbar.num_stops, pos); + } osd_set_progbar(mpctx->osd, &mpctx->osd_progbar); return; } @@ -450,7 +455,7 @@ static void add_seek_osd_messages(struct MPContext *mpctx) { if (mpctx->add_osd_seek_info & OSD_SEEK_INFO_BAR) { double pos = get_current_pos_ratio(mpctx, false); - set_osd_bar(mpctx, OSD_BAR_SEEK, "Position", 0, 1, MPCLAMP(pos, 0, 1)); + set_osd_bar(mpctx, OSD_BAR_SEEK, "Position", 0, 1, 0, MPCLAMP(pos, 0, 1)); set_osd_bar_chapters(mpctx, OSD_BAR_SEEK); } if (mpctx->add_osd_seek_info & OSD_SEEK_INFO_TEXT) {