diff options
Diffstat (limited to 'video')
-rw-r--r-- | video/out/gl_video.c | 26 | ||||
-rw-r--r-- | video/out/gl_video.h | 5 | ||||
-rw-r--r-- | video/out/vo_opengl.c | 17 |
3 files changed, 48 insertions, 0 deletions
diff --git a/video/out/gl_video.c b/video/out/gl_video.c index f1ea03ed80..7420d9d4d1 100644 --- a/video/out/gl_video.c +++ b/video/out/gl_video.c @@ -355,6 +355,7 @@ static int validate_scaler_opt(struct mp_log *log, const m_option_t *opt, const struct m_sub_options gl_video_conf = { .opts = (const m_option_t[]) { OPT_FLOATRANGE("gamma", gamma, 0, 0.1, 2.0), + OPT_FLAG("gamma-auto", gamma_auto, 0), OPT_FLAG("srgb", srgb, 0), OPT_FLAG("npot", npot, 0), OPT_FLAG("pbo", pbo, 0), @@ -2564,6 +2565,31 @@ void gl_video_resize_redraw(struct gl_video *p, int w, int h) gl_video_render_frame(p, 0, NULL); } +float gl_video_scale_ambient_lux(float lmin, float lmax, + float rmin, float rmax, float lux) +{ + assert(lmax > lmin); + + float num = (rmax - rmin) * (log10(lux) - log10(lmin)); + float den = log10(lmax) - log10(lmin); + float result = num / den + rmin; + + // clamp the result + float max = MPMAX(rmax, rmin); + float min = MPMIN(rmax, rmin); + return MPMAX(MPMIN(result, max), min); +} + +void gl_video_set_ambient_lux(struct gl_video *p, int lux) +{ + if (p->opts.gamma_auto) { + float gamma = gl_video_scale_ambient_lux(16.0, 64.0, 2.40, 1.961, lux); + MP_INFO(p, "ambient light changed: %dlux (gamma: %f)\n", lux, gamma); + p->opts.gamma = MPMIN(1.0, 1.961 / gamma); + gl_video_eq_update(p); + } +} + void gl_video_set_hwdec(struct gl_video *p, struct gl_hwdec *hwdec) { p->hwdec = hwdec; diff --git a/video/out/gl_video.h b/video/out/gl_video.h index 74a8b7fd93..8c273faa9e 100644 --- a/video/out/gl_video.h +++ b/video/out/gl_video.h @@ -35,6 +35,7 @@ struct gl_video_opts { float scaler_radius[2]; float scaler_antiring[2]; float gamma; + int gamma_auto; int srgb; int linear_scaling; int fancy_downscaling; @@ -83,6 +84,10 @@ void gl_video_eq_update(struct gl_video *p); void gl_video_set_debug(struct gl_video *p, bool enable); void gl_video_resize_redraw(struct gl_video *p, int w, int h); +float gl_video_scale_ambient_lux(float lmin, float lmax, + float rmin, float rmax, float lux); +void gl_video_set_ambient_lux(struct gl_video *p, int lux); + void gl_video_set_gl_state(struct gl_video *p); void gl_video_unset_gl_state(struct gl_video *p); void gl_video_reset(struct gl_video *p); diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c index a9435eeac2..9318914dbd 100644 --- a/video/out/vo_opengl.c +++ b/video/out/vo_opengl.c @@ -276,6 +276,19 @@ static bool get_and_update_icc_profile(struct gl_priv *p, int *events) return true; } +static void get_and_update_ambient_lighting(struct gl_priv *p, int *events) +{ + int lux; + int r = p->glctx->vo_control(p->vo, events, VOCTRL_GET_AMBIENT_LUX, &lux); + if (r == VO_TRUE) { + gl_video_set_ambient_lux(p->renderer, lux); + } + if (r != VO_TRUE && p->renderer_opts->gamma_auto) { + MP_ERR(p, "gamma_auto option provided, but querying for ambient" + " lighting is not supported on this platform\n"); + } +} + static bool reparse_cmdline(struct gl_priv *p, char *args) { struct m_config *cfg = NULL; @@ -390,6 +403,10 @@ static int control(struct vo *vo, uint32_t request, void *data) get_and_update_icc_profile(p, &events); vo->want_redraw = true; } + if (events & VO_EVENT_AMBIENT_LIGHTING_CHANGED) { + get_and_update_ambient_lighting(p, &events); + vo->want_redraw = true; + } if (events & VO_EVENT_RESIZE) resize(p); if (events & VO_EVENT_EXPOSE) |