vo: add params mutex

This mostly is added to resolve player command synchronization with VO
thread discussed in 477a0f83.

The current uses does not necessarily need this as they are all managed
by playloop. But for future use with other params that will be handy.

Those params are mostly to observe current state of VO and does not
necessarly need to be locked along with frame drawing, that changes the
params once at the end.
This commit is contained in:
Kacper Michajłow 2023-11-09 03:18:48 +01:00 committed by sfan5
parent 67deebc5b5
commit 5220725ca5
3 changed files with 19 additions and 3 deletions

View File

@ -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;
}

View File

@ -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).

View File

@ -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;