summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/out/vo.c10
-rw-r--r--video/out/vo.h10
-rw-r--r--video/out/vo_gpu_next.c2
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;