mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	sink/source: Initialize port before fixate hook (fixes volume/mute not saved)
In case a port has not yet been saved, which is e g often the case if a sink/source has only one port, reading volume/mute will be done without port, whereas writing volume/mute will be done with port. Work around this by setting a default port before the fixate hook, so module-device-restore can read volume/mute for the correct port. BugLink: https://bugs.launchpad.net/bugs/1289515 Signed-off-by: David Henningsson <david.henningsson@canonical.com>
This commit is contained in:
		
							parent
							
								
									633bc529e2
								
							
						
					
					
						commit
						e0e6bf6875
					
				
					 4 changed files with 49 additions and 35 deletions
				
			
		| 
						 | 
					@ -176,3 +176,30 @@ void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset) {
 | 
				
			||||||
    pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, p->card->index);
 | 
					    pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, p->card->index);
 | 
				
			||||||
    pa_hook_fire(&core->hooks[PA_CORE_HOOK_PORT_LATENCY_OFFSET_CHANGED], p);
 | 
					    pa_hook_fire(&core->hooks[PA_CORE_HOOK_PORT_LATENCY_OFFSET_CHANGED], p);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pa_device_port *pa_device_port_find_best(pa_hashmap *ports)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    void *state;
 | 
				
			||||||
 | 
					    pa_device_port *p, *best = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!ports)
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* First run: skip unavailable ports */
 | 
				
			||||||
 | 
					    PA_HASHMAP_FOREACH(p, ports, state) {
 | 
				
			||||||
 | 
					        if (p->available == PA_AVAILABLE_NO)
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!best || p->priority > best->priority)
 | 
				
			||||||
 | 
					            best = p;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Second run: if only unavailable ports exist, still suggest a port */
 | 
				
			||||||
 | 
					    if (!best) {
 | 
				
			||||||
 | 
					        PA_HASHMAP_FOREACH(p, ports, state)
 | 
				
			||||||
 | 
					            if (!best || p->priority > best->priority)
 | 
				
			||||||
 | 
					                best = p;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return best;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,4 +83,6 @@ void pa_device_port_set_available(pa_device_port *p, pa_available_t available);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset);
 | 
					void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pa_device_port *pa_device_port_find_best(pa_hashmap *ports);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -235,6 +235,12 @@ pa_sink* pa_sink_new(
 | 
				
			||||||
    pa_device_init_icon(data->proplist, true);
 | 
					    pa_device_init_icon(data->proplist, true);
 | 
				
			||||||
    pa_device_init_intended_roles(data->proplist);
 | 
					    pa_device_init_intended_roles(data->proplist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!data->active_port) {
 | 
				
			||||||
 | 
					        pa_device_port *p = pa_device_port_find_best(data->ports);
 | 
				
			||||||
 | 
					        if (p)
 | 
				
			||||||
 | 
					            pa_sink_new_data_set_port(data, p->name);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_FIXATE], data) < 0) {
 | 
					    if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_FIXATE], data) < 0) {
 | 
				
			||||||
        pa_xfree(s);
 | 
					        pa_xfree(s);
 | 
				
			||||||
        pa_namereg_unregister(core, name);
 | 
					        pa_namereg_unregister(core, name);
 | 
				
			||||||
| 
						 | 
					@ -300,23 +306,10 @@ pa_sink* pa_sink_new(
 | 
				
			||||||
        if ((s->active_port = pa_hashmap_get(s->ports, data->active_port)))
 | 
					        if ((s->active_port = pa_hashmap_get(s->ports, data->active_port)))
 | 
				
			||||||
            s->save_port = data->save_port;
 | 
					            s->save_port = data->save_port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!s->active_port) {
 | 
					    /* Hopefully the active port has already been assigned in the previous call
 | 
				
			||||||
        void *state;
 | 
					       to pa_device_port_find_best, but better safe than sorry */
 | 
				
			||||||
        pa_device_port *p;
 | 
					    if (!s->active_port)
 | 
				
			||||||
 | 
					        s->active_port = pa_device_port_find_best(s->ports);
 | 
				
			||||||
        PA_HASHMAP_FOREACH(p, s->ports, state) {
 | 
					 | 
				
			||||||
            if (p->available == PA_AVAILABLE_NO)
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (!s->active_port || p->priority > s->active_port->priority)
 | 
					 | 
				
			||||||
                s->active_port = p;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (!s->active_port) {
 | 
					 | 
				
			||||||
            PA_HASHMAP_FOREACH(p, s->ports, state)
 | 
					 | 
				
			||||||
                if (!s->active_port || p->priority > s->active_port->priority)
 | 
					 | 
				
			||||||
                    s->active_port = p;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (s->active_port)
 | 
					    if (s->active_port)
 | 
				
			||||||
        s->latency_offset = s->active_port->latency_offset;
 | 
					        s->latency_offset = s->active_port->latency_offset;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -222,6 +222,12 @@ pa_source* pa_source_new(
 | 
				
			||||||
    pa_device_init_icon(data->proplist, false);
 | 
					    pa_device_init_icon(data->proplist, false);
 | 
				
			||||||
    pa_device_init_intended_roles(data->proplist);
 | 
					    pa_device_init_intended_roles(data->proplist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!data->active_port) {
 | 
				
			||||||
 | 
					        pa_device_port *p = pa_device_port_find_best(data->ports);
 | 
				
			||||||
 | 
					        if (p)
 | 
				
			||||||
 | 
					            pa_source_new_data_set_port(data, p->name);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], data) < 0) {
 | 
					    if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], data) < 0) {
 | 
				
			||||||
        pa_xfree(s);
 | 
					        pa_xfree(s);
 | 
				
			||||||
        pa_namereg_unregister(core, name);
 | 
					        pa_namereg_unregister(core, name);
 | 
				
			||||||
| 
						 | 
					@ -288,24 +294,10 @@ pa_source* pa_source_new(
 | 
				
			||||||
        if ((s->active_port = pa_hashmap_get(s->ports, data->active_port)))
 | 
					        if ((s->active_port = pa_hashmap_get(s->ports, data->active_port)))
 | 
				
			||||||
            s->save_port = data->save_port;
 | 
					            s->save_port = data->save_port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!s->active_port) {
 | 
					    /* Hopefully the active port has already been assigned in the previous call
 | 
				
			||||||
        void *state;
 | 
					       to pa_device_port_find_best, but better safe than sorry */
 | 
				
			||||||
        pa_device_port *p;
 | 
					    if (!s->active_port)
 | 
				
			||||||
 | 
					        s->active_port = pa_device_port_find_best(s->ports);
 | 
				
			||||||
        PA_HASHMAP_FOREACH(p, s->ports, state) {
 | 
					 | 
				
			||||||
            if (p->available == PA_AVAILABLE_NO)
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (!s->active_port || p->priority > s->active_port->priority)
 | 
					 | 
				
			||||||
                s->active_port = p;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (!s->active_port) {
 | 
					 | 
				
			||||||
            PA_HASHMAP_FOREACH(p, s->ports, state)
 | 
					 | 
				
			||||||
                if (!s->active_port || p->priority > s->active_port->priority)
 | 
					 | 
				
			||||||
                    s->active_port = p;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (s->active_port)
 | 
					    if (s->active_port)
 | 
				
			||||||
        s->latency_offset = s->active_port->latency_offset;
 | 
					        s->latency_offset = s->active_port->latency_offset;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue