mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
context: handle route changes better
Track the current route and the properties independently. Else we might skip parsing the volumes/mute properties when the current route didn't change. Fixes #281
This commit is contained in:
parent
d995df95f8
commit
0d1b01147f
1 changed files with 40 additions and 10 deletions
|
|
@ -295,8 +295,10 @@ static void do_global_sync(struct global *g)
|
||||||
{
|
{
|
||||||
pa_subscription_event_type_t event;
|
pa_subscription_event_type_t event;
|
||||||
|
|
||||||
|
pw_log_debug("global %p sync", g);
|
||||||
if (g->ginfo && g->ginfo->sync)
|
if (g->ginfo && g->ginfo->sync)
|
||||||
g->ginfo->sync(g);
|
g->ginfo->sync(g);
|
||||||
|
|
||||||
if (g->init) {
|
if (g->init) {
|
||||||
if ((g->mask & (PA_SUBSCRIPTION_MASK_SINK_INPUT | PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT))) {
|
if ((g->mask & (PA_SUBSCRIPTION_MASK_SINK_INPUT | PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT))) {
|
||||||
if (g->node_info.device_index == SPA_ID_INVALID ||
|
if (g->node_info.device_index == SPA_ID_INVALID ||
|
||||||
|
|
@ -308,7 +310,6 @@ static void do_global_sync(struct global *g)
|
||||||
} else {
|
} else {
|
||||||
event = PA_SUBSCRIPTION_EVENT_CHANGE;
|
event = PA_SUBSCRIPTION_EVENT_CHANGE;
|
||||||
}
|
}
|
||||||
pw_log_debug("emit because of pending");
|
|
||||||
emit_event(g->context, g, event);
|
emit_event(g->context, g, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -436,6 +437,7 @@ static void device_event_info(void *object, const struct pw_device_info *info)
|
||||||
g->card_info.pending_ports = true;
|
g->card_info.pending_ports = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
pw_log_debug("global %p: do enum:%d", g, id);
|
||||||
pw_device_enum_params((struct pw_device*)g->proxy,
|
pw_device_enum_params((struct pw_device*)g->proxy,
|
||||||
0, id, 0, -1, NULL);
|
0, id, 0, -1, NULL);
|
||||||
}
|
}
|
||||||
|
|
@ -446,31 +448,47 @@ static void device_event_info(void *object, const struct pw_device_info *info)
|
||||||
global_sync(g);
|
global_sync(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_props(struct global *g, const struct spa_pod *param, bool device)
|
static int parse_props(struct global *g, const struct spa_pod *param, bool device)
|
||||||
{
|
{
|
||||||
|
int changed = 0;
|
||||||
struct spa_pod_prop *prop;
|
struct spa_pod_prop *prop;
|
||||||
struct spa_pod_object *obj = (struct spa_pod_object *) param;
|
struct spa_pod_object *obj = (struct spa_pod_object *) param;
|
||||||
|
|
||||||
SPA_POD_OBJECT_FOREACH(obj, prop) {
|
SPA_POD_OBJECT_FOREACH(obj, prop) {
|
||||||
switch (prop->key) {
|
switch (prop->key) {
|
||||||
case SPA_PROP_volume:
|
case SPA_PROP_volume:
|
||||||
spa_pod_get_float(&prop->value, &g->node_info.volume);
|
{
|
||||||
|
float vol;
|
||||||
|
if (spa_pod_get_float(&prop->value, &vol) >= 0 &&
|
||||||
|
g->node_info.volume != vol) {
|
||||||
|
g->node_info.volume = vol;
|
||||||
|
changed++;
|
||||||
|
}
|
||||||
SPA_FLAG_UPDATE(g->node_info.flags, NODE_FLAG_DEVICE_VOLUME, device);
|
SPA_FLAG_UPDATE(g->node_info.flags, NODE_FLAG_DEVICE_VOLUME, device);
|
||||||
SPA_FLAG_UPDATE(g->node_info.flags, NODE_FLAG_HW_VOLUME,
|
SPA_FLAG_UPDATE(g->node_info.flags, NODE_FLAG_HW_VOLUME,
|
||||||
prop->flags & SPA_POD_PROP_FLAG_HARDWARE);
|
prop->flags & SPA_POD_PROP_FLAG_HARDWARE);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case SPA_PROP_mute:
|
case SPA_PROP_mute:
|
||||||
spa_pod_get_bool(&prop->value, &g->node_info.mute);
|
{
|
||||||
|
bool mute;
|
||||||
|
if (spa_pod_get_bool(&prop->value, &mute) >= 0 &&
|
||||||
|
g->node_info.mute != mute) {
|
||||||
|
g->node_info.mute = mute;
|
||||||
|
changed++;
|
||||||
|
}
|
||||||
SPA_FLAG_UPDATE(g->node_info.flags, NODE_FLAG_DEVICE_MUTE, device);
|
SPA_FLAG_UPDATE(g->node_info.flags, NODE_FLAG_DEVICE_MUTE, device);
|
||||||
SPA_FLAG_UPDATE(g->node_info.flags, NODE_FLAG_HW_MUTE,
|
SPA_FLAG_UPDATE(g->node_info.flags, NODE_FLAG_HW_MUTE,
|
||||||
prop->flags & SPA_POD_PROP_FLAG_HARDWARE);
|
prop->flags & SPA_POD_PROP_FLAG_HARDWARE);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case SPA_PROP_channelVolumes:
|
case SPA_PROP_channelVolumes:
|
||||||
{
|
{
|
||||||
uint32_t n_vals;
|
uint32_t n_vals;
|
||||||
|
float vol[SPA_AUDIO_MAX_CHANNELS];
|
||||||
|
|
||||||
n_vals = spa_pod_copy_array(&prop->value, SPA_TYPE_Float,
|
n_vals = spa_pod_copy_array(&prop->value, SPA_TYPE_Float,
|
||||||
g->node_info.channel_volumes, SPA_AUDIO_MAX_CHANNELS);
|
vol, SPA_AUDIO_MAX_CHANNELS);
|
||||||
|
|
||||||
if (n_vals != g->node_info.n_channel_volumes) {
|
if (n_vals != g->node_info.n_channel_volumes) {
|
||||||
pw_log_debug("channel change %d->%d, trigger remove",
|
pw_log_debug("channel change %d->%d, trigger remove",
|
||||||
|
|
@ -480,7 +498,12 @@ static void parse_props(struct global *g, const struct spa_pod *param, bool devi
|
||||||
g->node_info.n_channel_volumes = n_vals;
|
g->node_info.n_channel_volumes = n_vals;
|
||||||
/* mark as init, this will emit the NEW event when the
|
/* mark as init, this will emit the NEW event when the
|
||||||
* params are updated */
|
* params are updated */
|
||||||
g->init = true;
|
g->init = g->sync = true;
|
||||||
|
changed++;
|
||||||
|
}
|
||||||
|
if (memcmp(g->node_info.channel_volumes, vol, n_vals * sizeof(float)) != 0) {
|
||||||
|
memcpy(g->node_info.channel_volumes, vol, n_vals * sizeof(float));
|
||||||
|
changed++;
|
||||||
}
|
}
|
||||||
SPA_FLAG_UPDATE(g->node_info.flags, NODE_FLAG_DEVICE_VOLUME, device);
|
SPA_FLAG_UPDATE(g->node_info.flags, NODE_FLAG_DEVICE_VOLUME, device);
|
||||||
SPA_FLAG_UPDATE(g->node_info.flags, NODE_FLAG_HW_VOLUME,
|
SPA_FLAG_UPDATE(g->node_info.flags, NODE_FLAG_HW_VOLUME,
|
||||||
|
|
@ -497,6 +520,7 @@ static void parse_props(struct global *g, const struct spa_pod *param, bool devi
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct global *find_node_for_route(pa_context *c, struct global *card, uint32_t device)
|
static struct global *find_node_for_route(pa_context *c, struct global *card, uint32_t device)
|
||||||
|
|
@ -834,10 +858,16 @@ static void device_sync_ports(struct global *g)
|
||||||
}
|
}
|
||||||
|
|
||||||
ng = find_node_for_route(c, g, device);
|
ng = find_node_for_route(c, g, device);
|
||||||
if (props && ng && ng->node_info.active_port != index) {
|
if (ng) {
|
||||||
ng->node_info.active_port = index;
|
int changed = 0;
|
||||||
parse_props(ng, props, true);
|
if (ng->node_info.active_port != index) {
|
||||||
emit_event(c, ng, PA_SUBSCRIPTION_EVENT_CHANGE);
|
ng->node_info.active_port = index;
|
||||||
|
changed++;
|
||||||
|
}
|
||||||
|
if (props)
|
||||||
|
changed += parse_props(ng, props, true);
|
||||||
|
if (changed)
|
||||||
|
emit_event(c, ng, PA_SUBSCRIPTION_EVENT_CHANGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue