diff options
-rw-r--r-- | video/out/vo.c | 10 | ||||
-rw-r--r-- | video/out/vo.h | 10 | ||||
-rw-r--r-- | video/out/vo_gpu_next.c | 2 |
3 files changed, 19 insertions, 3 deletions
diff --git a/video/out/vo.c b/video/out/vo.c index 50129fb306..7581d9680e 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -270,6 +270,7 @@ static void dealloc_vo(struct vo *vo) talloc_free(vo->opts_cache); talloc_free(vo->gl_opts_cache); talloc_free(vo->eq_opts_cache); + mp_mutex_destroy(&vo->params_mutex); mp_mutex_destroy(&vo->in->lock); mp_cond_destroy(&vo->in->wakeup); @@ -301,6 +302,7 @@ static struct vo *vo_create(bool probing, struct mpv_global *global, .probing = probing, .in = talloc(vo, struct vo_internal), }; + mp_mutex_init(&vo->params_mutex); talloc_steal(vo, log); *vo->in = (struct vo_internal) { .dispatch = mp_dispatch_create(vo), @@ -613,8 +615,10 @@ static void run_reconfig(void *p) mp_image_params_get_dsize(params, &vo->dwidth, &vo->dheight); + mp_mutex_lock(&vo->params_mutex); talloc_free(vo->params); vo->params = talloc_dup(vo, params); + mp_mutex_unlock(&vo->params_mutex); if (vo->driver->reconfig2) { *ret = vo->driver->reconfig2(vo, img); @@ -625,8 +629,10 @@ static void run_reconfig(void *p) if (vo->config_ok) { check_vo_caps(vo); } else { + mp_mutex_lock(&vo->params_mutex); talloc_free(vo->params); vo->params = NULL; + mp_mutex_unlock(&vo->params_mutex); } mp_mutex_lock(&in->lock); @@ -1433,9 +1439,9 @@ int lookup_keymap_table(const struct mp_keymap *map, int key) struct mp_image_params vo_get_current_params(struct vo *vo) { struct mp_image_params p = {0}; - mp_mutex_lock(&vo->in->lock); + mp_mutex_lock(&vo->params_mutex); if (vo->params) p = *vo->params; - mp_mutex_unlock(&vo->in->lock); + mp_mutex_unlock(&vo->params_mutex); return p; } diff --git a/video/out/vo.h b/video/out/vo.h index e38dcf8010..40c5746992 100644 --- a/video/out/vo.h +++ b/video/out/vo.h @@ -29,6 +29,7 @@ #include "video/img_format.h" #include "common/common.h" #include "options/options.h" +#include "osdep/threads.h" enum { // VO needs to redraw @@ -470,7 +471,14 @@ struct vo { // be accessed unsynchronized (read-only). int config_ok; // Last config call was successful? - struct mp_image_params *params; // Configured parameters (as in vo_reconfig) + + // --- The following fields are synchronized by params_mutex, most of + // the params are set only in the vo_reconfig and safe to read + // unsynchronized. Some of the parameters are updated in draw_frame, + // which are still safe to read in the play loop, but for correctness + // generic getter is protected by params_mutex. + mp_mutex params_mutex; + struct mp_image_params *params; // Configured parameters (changed in vo_reconfig) // --- The following fields can be accessed only by the VO thread, or from // anywhere _if_ the VO thread is suspended (use vo->dispatch). diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c index 1dc1b181ae..77ab0113bb 100644 --- a/video/out/vo_gpu_next.c +++ b/video/out/vo_gpu_next.c @@ -1079,11 +1079,13 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) } const struct pl_frame *cur_frame = pl_frame_mix_nearest(&mix); + mp_mutex_lock(&vo->params_mutex); if (cur_frame && vo->params) { vo->params->color.hdr = cur_frame->color.hdr; // Augment metadata with peak detection max_pq_y / avg_pq_y pl_renderer_get_hdr_metadata(p->rr, &vo->params->color.hdr); } + mp_mutex_unlock(&vo->params_mutex); p->is_interpolated = pts_offset != 0 && mix.num_frames > 1; valid = true; |