mirror of https://github.com/mpv-player/mpv
client API: fix missing property change events after property updates
When update_prop() successfully fetched a changed property value, it
set prop->changed to true to indicate the success.
mark_property_changed() also always set
prop->changed to true and additionally prop->need_new_value to true
This is the case since 6ac0ef78
If the observed property changes every frame and then due to timing
the next mark_property_changed() is called before
gen_property_change_event() and therefore directly after update_prop(),
prop->need_new_value was again true and indicated that a new value
has to be retrieved with update_prop(). As a result the event for the
last successful update_prop() was never triggered. This meant that
a property change event were never generated for frame-based properties
only for properties that were observed with MPV_FORMAT_NONE or when the
timing was different and gen_property_change_event() was called after
update_prop().
To fix this, mark_property_change() and update_prop() should not use the
same flag to indicate different things and therefore a new flag for
successfully update a property is introduced. But with the now decoupled property
changed and updated the need_new_value flag is redundant and removed completely.
Fixes #4195
This commit is contained in:
parent
c1f1a0845e
commit
31a39334a2
|
@ -90,6 +90,7 @@ struct observe_property {
|
||||||
bool changed; // property change should be signaled to user
|
bool changed; // property change should be signaled to user
|
||||||
bool need_new_value; // a new value should be retrieved
|
bool need_new_value; // a new value should be retrieved
|
||||||
bool updating; // a new value is being retrieved
|
bool updating; // a new value is being retrieved
|
||||||
|
bool updated; // a new value was successfully retrieved
|
||||||
bool dead; // property unobserved while retrieving value
|
bool dead; // property unobserved while retrieving value
|
||||||
bool new_value_valid, user_value_valid;
|
bool new_value_valid, user_value_valid;
|
||||||
union m_option_value new_value, user_value;
|
union m_option_value new_value, user_value;
|
||||||
|
@ -1467,7 +1468,8 @@ int mpv_observe_property(mpv_handle *ctx, uint64_t userdata,
|
||||||
.reply_id = userdata,
|
.reply_id = userdata,
|
||||||
.format = format,
|
.format = format,
|
||||||
.changed = true,
|
.changed = true,
|
||||||
.need_new_value = true,
|
.updating = false,
|
||||||
|
.updated = false,
|
||||||
};
|
};
|
||||||
MP_TARRAY_APPEND(ctx, ctx->properties, ctx->num_properties, prop);
|
MP_TARRAY_APPEND(ctx, ctx->properties, ctx->num_properties, prop);
|
||||||
ctx->property_event_masks |= prop->event_mask;
|
ctx->property_event_masks |= prop->event_mask;
|
||||||
|
@ -1510,7 +1512,6 @@ static void mark_property_changed(struct mpv_handle *client, int index)
|
||||||
{
|
{
|
||||||
struct observe_property *prop = client->properties[index];
|
struct observe_property *prop = client->properties[index];
|
||||||
prop->changed = true;
|
prop->changed = true;
|
||||||
prop->need_new_value = prop->format != 0;
|
|
||||||
client->lowest_changed = MPMIN(client->lowest_changed, index);
|
client->lowest_changed = MPMIN(client->lowest_changed, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1574,10 +1575,10 @@ static void update_prop(void *p)
|
||||||
if (prop->new_value_valid)
|
if (prop->new_value_valid)
|
||||||
memcpy(&prop->new_value, &val, type->type->size);
|
memcpy(&prop->new_value, &val, type->type->size);
|
||||||
if (prop->user_value_valid != prop->new_value_valid) {
|
if (prop->user_value_valid != prop->new_value_valid) {
|
||||||
prop->changed = true;
|
prop->updated = true;
|
||||||
} else if (prop->user_value_valid && prop->new_value_valid) {
|
} else if (prop->user_value_valid && prop->new_value_valid) {
|
||||||
if (!equal_mpv_value(&prop->user_value, &prop->new_value, prop->format))
|
if (!equal_mpv_value(&prop->user_value, &prop->new_value, prop->format))
|
||||||
prop->changed = true;
|
prop->updated = true;
|
||||||
}
|
}
|
||||||
if (prop->dead)
|
if (prop->dead)
|
||||||
talloc_steal(ctx->cur_event, prop);
|
talloc_steal(ctx->cur_event, prop);
|
||||||
|
@ -1595,35 +1596,38 @@ static bool gen_property_change_event(struct mpv_handle *ctx)
|
||||||
ctx->lowest_changed = ctx->num_properties;
|
ctx->lowest_changed = ctx->num_properties;
|
||||||
for (int n = start; n < ctx->num_properties; n++) {
|
for (int n = start; n < ctx->num_properties; n++) {
|
||||||
struct observe_property *prop = ctx->properties[n];
|
struct observe_property *prop = ctx->properties[n];
|
||||||
if ((prop->changed || prop->updating) && n < ctx->lowest_changed)
|
if ((prop->changed || prop->updating || prop->updated) && n < ctx->lowest_changed)
|
||||||
ctx->lowest_changed = n;
|
ctx->lowest_changed = n;
|
||||||
if (prop->changed) {
|
if (prop->changed) {
|
||||||
bool get_value = prop->need_new_value;
|
|
||||||
prop->need_new_value = false;
|
|
||||||
prop->changed = false;
|
prop->changed = false;
|
||||||
if (prop->format && get_value) {
|
if (prop->format != MPV_FORMAT_NONE) {
|
||||||
ctx->properties_updating++;
|
ctx->properties_updating++;
|
||||||
prop->updating = true;
|
prop->updating = true;
|
||||||
mp_dispatch_enqueue(ctx->mpctx->dispatch, update_prop, prop);
|
mp_dispatch_enqueue(ctx->mpctx->dispatch, update_prop, prop);
|
||||||
} else {
|
} else {
|
||||||
const struct m_option *type = get_mp_type_get(prop->format);
|
prop->updated = true;
|
||||||
prop->user_value_valid = prop->new_value_valid;
|
|
||||||
if (prop->new_value_valid)
|
|
||||||
m_option_copy(type, &prop->user_value, &prop->new_value);
|
|
||||||
ctx->cur_property_event = (struct mpv_event_property){
|
|
||||||
.name = prop->name,
|
|
||||||
.format = prop->user_value_valid ? prop->format : 0,
|
|
||||||
};
|
|
||||||
if (prop->user_value_valid)
|
|
||||||
ctx->cur_property_event.data = &prop->user_value;
|
|
||||||
*ctx->cur_event = (struct mpv_event){
|
|
||||||
.event_id = MPV_EVENT_PROPERTY_CHANGE,
|
|
||||||
.reply_userdata = prop->reply_id,
|
|
||||||
.data = &ctx->cur_property_event,
|
|
||||||
};
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bool updated = prop->updated;
|
||||||
|
prop->updated = false;
|
||||||
|
if (updated) {
|
||||||
|
const struct m_option *type = get_mp_type_get(prop->format);
|
||||||
|
prop->user_value_valid = prop->new_value_valid;
|
||||||
|
if (prop->new_value_valid)
|
||||||
|
m_option_copy(type, &prop->user_value, &prop->new_value);
|
||||||
|
ctx->cur_property_event = (struct mpv_event_property){
|
||||||
|
.name = prop->name,
|
||||||
|
.format = prop->user_value_valid ? prop->format : 0,
|
||||||
|
};
|
||||||
|
if (prop->user_value_valid)
|
||||||
|
ctx->cur_property_event.data = &prop->user_value;
|
||||||
|
*ctx->cur_event = (struct mpv_event){
|
||||||
|
.event_id = MPV_EVENT_PROPERTY_CHANGE,
|
||||||
|
.reply_userdata = prop->reply_id,
|
||||||
|
.data = &ctx->cur_property_event,
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue