mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	acp: sync with pulseaudio
This commit is contained in:
		
							parent
							
								
									752afa06a2
								
							
						
					
					
						commit
						57f0fdf746
					
				
					 7 changed files with 680 additions and 552 deletions
				
			
		| 
						 | 
				
			
			@ -469,7 +469,7 @@ static void add_profiles(pa_card *impl)
 | 
			
		|||
					pa_dynarray_append(&impl->out.devices, dev);
 | 
			
		||||
				}
 | 
			
		||||
				if (impl->use_ucm) {
 | 
			
		||||
					pa_alsa_ucm_add_ports_combination(NULL, &m->ucm_context,
 | 
			
		||||
					pa_alsa_ucm_add_port(NULL, &m->ucm_context,
 | 
			
		||||
						true, impl->ports, ap, NULL);
 | 
			
		||||
					pa_alsa_ucm_add_ports(&dev->ports, m->proplist, &m->ucm_context,
 | 
			
		||||
						true, impl, dev->pcm_handle, impl->profile_set->ignore_dB);
 | 
			
		||||
| 
						 | 
				
			
			@ -491,7 +491,7 @@ static void add_profiles(pa_card *impl)
 | 
			
		|||
				}
 | 
			
		||||
 | 
			
		||||
				if (impl->use_ucm) {
 | 
			
		||||
					pa_alsa_ucm_add_ports_combination(NULL, &m->ucm_context,
 | 
			
		||||
					pa_alsa_ucm_add_port(NULL, &m->ucm_context,
 | 
			
		||||
						false, impl->ports, ap, NULL);
 | 
			
		||||
					pa_alsa_ucm_add_ports(&dev->ports, m->proplist, &m->ucm_context,
 | 
			
		||||
						false, impl, dev->pcm_handle, impl->profile_set->ignore_dB);
 | 
			
		||||
| 
						 | 
				
			
			@ -1231,8 +1231,7 @@ static int setup_mixer(pa_card *impl, pa_alsa_device *dev, bool ignore_dB)
 | 
			
		|||
	* will be NULL, but the UCM device enable sequence will still need to be
 | 
			
		||||
	* executed. */
 | 
			
		||||
	if (dev->active_port && dev->ucm_context) {
 | 
			
		||||
		if ((res = pa_alsa_ucm_set_port(dev->ucm_context, dev->active_port,
 | 
			
		||||
					dev->direction == PA_ALSA_DIRECTION_OUTPUT)) < 0)
 | 
			
		||||
		if ((res = pa_alsa_ucm_set_port(dev->ucm_context, dev->active_port)) < 0)
 | 
			
		||||
			return res;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1408,8 +1407,7 @@ int acp_card_set_profile(struct acp_card *card, uint32_t new_index, uint32_t fla
 | 
			
		|||
	/* if UCM is available for this card then update the verb */
 | 
			
		||||
	if (impl->use_ucm) {
 | 
			
		||||
		if ((res = pa_alsa_ucm_set_profile(&impl->ucm, impl,
 | 
			
		||||
		    np->profile.flags & ACP_PROFILE_OFF ? NULL : np->profile.name,
 | 
			
		||||
		    op ? op->profile.name : NULL)) < 0) {
 | 
			
		||||
		    np->profile.flags & ACP_PROFILE_OFF ? NULL : np, op)) < 0) {
 | 
			
		||||
			return res;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1418,7 +1416,7 @@ int acp_card_set_profile(struct acp_card *card, uint32_t new_index, uint32_t fla
 | 
			
		|||
		PA_IDXSET_FOREACH(am, np->output_mappings, idx) {
 | 
			
		||||
			if (impl->use_ucm)
 | 
			
		||||
				/* Update ports priorities */
 | 
			
		||||
				pa_alsa_ucm_add_ports_combination(am->output.ports, &am->ucm_context,
 | 
			
		||||
				pa_alsa_ucm_add_port(am->output.ports, &am->ucm_context,
 | 
			
		||||
					true, impl->ports, np, NULL);
 | 
			
		||||
			device_enable(impl, am, &am->output);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -1428,7 +1426,7 @@ int acp_card_set_profile(struct acp_card *card, uint32_t new_index, uint32_t fla
 | 
			
		|||
		PA_IDXSET_FOREACH(am, np->input_mappings, idx) {
 | 
			
		||||
			if (impl->use_ucm)
 | 
			
		||||
				/* Update ports priorities */
 | 
			
		||||
				pa_alsa_ucm_add_ports_combination(am->input.ports, &am->ucm_context,
 | 
			
		||||
				pa_alsa_ucm_add_port(am->input.ports, &am->ucm_context,
 | 
			
		||||
					false, impl->ports, np, NULL);
 | 
			
		||||
			device_enable(impl, am, &am->input);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -1810,8 +1808,7 @@ int acp_device_set_port(struct acp_device *dev, uint32_t port_index, uint32_t fl
 | 
			
		|||
		mixer_volume_init(impl, d);
 | 
			
		||||
 | 
			
		||||
		sync_mixer(d, p);
 | 
			
		||||
		res = pa_alsa_ucm_set_port(d->ucm_context, p,
 | 
			
		||||
					dev->direction == ACP_DIRECTION_PLAYBACK);
 | 
			
		||||
		res = pa_alsa_ucm_set_port(d->ucm_context, p);
 | 
			
		||||
	} else {
 | 
			
		||||
		pa_alsa_port_data *data;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -381,6 +381,9 @@ struct pa_alsa_profile {
 | 
			
		|||
    pa_idxset *input_mappings;
 | 
			
		||||
    pa_idxset *output_mappings;
 | 
			
		||||
 | 
			
		||||
    /* ucm device context */
 | 
			
		||||
    pa_alsa_ucm_profile_context ucm_context;
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
	pa_dynarray devices;
 | 
			
		||||
    } out;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -142,12 +142,13 @@ typedef struct pa_alsa_ucm_modifier pa_alsa_ucm_modifier;
 | 
			
		|||
typedef struct pa_alsa_ucm_device pa_alsa_ucm_device;
 | 
			
		||||
typedef struct pa_alsa_ucm_config pa_alsa_ucm_config;
 | 
			
		||||
typedef struct pa_alsa_ucm_mapping_context pa_alsa_ucm_mapping_context;
 | 
			
		||||
typedef struct pa_alsa_ucm_profile_context pa_alsa_ucm_profile_context;
 | 
			
		||||
typedef struct pa_alsa_ucm_port_data pa_alsa_ucm_port_data;
 | 
			
		||||
typedef struct pa_alsa_ucm_volume pa_alsa_ucm_volume;
 | 
			
		||||
 | 
			
		||||
int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index);
 | 
			
		||||
pa_alsa_profile_set* pa_alsa_ucm_add_profile_set(pa_alsa_ucm_config *ucm, pa_channel_map *default_channel_map);
 | 
			
		||||
int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, const char *new_profile, const char *old_profile);
 | 
			
		||||
int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, pa_alsa_profile *new_profile, pa_alsa_profile *old_profile);
 | 
			
		||||
 | 
			
		||||
int pa_alsa_ucm_get_verb(snd_use_case_mgr_t *uc_mgr, const char *verb_name, const char *verb_desc, pa_alsa_ucm_verb **p_verb);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -159,14 +160,14 @@ void pa_alsa_ucm_add_ports(
 | 
			
		|||
        pa_card *card,
 | 
			
		||||
        snd_pcm_t *pcm_handle,
 | 
			
		||||
        bool ignore_dB);
 | 
			
		||||
void pa_alsa_ucm_add_ports_combination(
 | 
			
		||||
void pa_alsa_ucm_add_port(
 | 
			
		||||
        pa_hashmap *hash,
 | 
			
		||||
        pa_alsa_ucm_mapping_context *context,
 | 
			
		||||
        bool is_sink,
 | 
			
		||||
        pa_hashmap *ports,
 | 
			
		||||
        pa_card_profile *cp,
 | 
			
		||||
        pa_core *core);
 | 
			
		||||
int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port, bool is_sink);
 | 
			
		||||
int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port);
 | 
			
		||||
 | 
			
		||||
void pa_alsa_ucm_free(pa_alsa_ucm_config *ucm);
 | 
			
		||||
void pa_alsa_ucm_mapping_context_free(pa_alsa_ucm_mapping_context *context);
 | 
			
		||||
| 
						 | 
				
			
			@ -223,11 +224,8 @@ struct pa_alsa_ucm_modifier {
 | 
			
		|||
 | 
			
		||||
    pa_proplist *proplist;
 | 
			
		||||
 | 
			
		||||
    int n_confdev;
 | 
			
		||||
    int n_suppdev;
 | 
			
		||||
 | 
			
		||||
    const char **conflicting_devices;
 | 
			
		||||
    const char **supported_devices;
 | 
			
		||||
    pa_idxset *conflicting_devices;
 | 
			
		||||
    pa_idxset *supported_devices;
 | 
			
		||||
 | 
			
		||||
    pa_direction_t action_direction;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -270,17 +268,19 @@ struct pa_alsa_ucm_mapping_context {
 | 
			
		|||
    pa_alsa_ucm_config *ucm;
 | 
			
		||||
    pa_direction_t direction;
 | 
			
		||||
 | 
			
		||||
    pa_idxset *ucm_devices;
 | 
			
		||||
    pa_idxset *ucm_modifiers;
 | 
			
		||||
    pa_alsa_ucm_device *ucm_device;
 | 
			
		||||
    pa_alsa_ucm_modifier *ucm_modifier;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct pa_alsa_ucm_profile_context {
 | 
			
		||||
    pa_alsa_ucm_verb *verb;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct pa_alsa_ucm_port_data {
 | 
			
		||||
    pa_alsa_ucm_config *ucm;
 | 
			
		||||
    pa_device_port *core_port;
 | 
			
		||||
 | 
			
		||||
    /* A single port will be associated with multiple devices if it represents
 | 
			
		||||
     * a combination of devices. */
 | 
			
		||||
    pa_dynarray *devices; /* pa_alsa_ucm_device */
 | 
			
		||||
    pa_alsa_ucm_device *device;
 | 
			
		||||
 | 
			
		||||
    /* profile name -> pa_alsa_path for volume control */
 | 
			
		||||
    pa_hashmap *paths;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1626,20 +1626,29 @@ static int mixer_class_event(snd_mixer_class_t *class, unsigned int mask,
 | 
			
		|||
{
 | 
			
		||||
    int err;
 | 
			
		||||
    const char *name = snd_hctl_elem_get_name(helem);
 | 
			
		||||
    // NOTE: The remove event defined as '~0U`.
 | 
			
		||||
    /* NOTE: The remove event is defined as '~0U`. */
 | 
			
		||||
    if (mask == SND_CTL_EVENT_MASK_REMOVE) {
 | 
			
		||||
        // NOTE: unless remove pointer to melem from link-list at private_data of helem, hits
 | 
			
		||||
	// assersion in alsa-lib since the list is not empty.
 | 
			
		||||
        /* NOTE: Unless we remove the pointer to melem from the linked-list at
 | 
			
		||||
         * private_data of helem, an assertion will be hit in alsa-lib since
 | 
			
		||||
         * the list is not empty. */
 | 
			
		||||
        snd_mixer_elem_detach(melem, helem);
 | 
			
		||||
    } else if (mask & SND_CTL_EVENT_MASK_ADD) {
 | 
			
		||||
        snd_ctl_elem_iface_t iface = snd_hctl_elem_get_interface(helem);
 | 
			
		||||
        if (iface == SND_CTL_ELEM_IFACE_CARD || iface == SND_CTL_ELEM_IFACE_PCM) {
 | 
			
		||||
            snd_mixer_t *mixer = snd_mixer_class_get_mixer(class);
 | 
			
		||||
            snd_ctl_elem_iface_t iface = snd_hctl_elem_get_interface(helem);
 | 
			
		||||
            const char *name = snd_hctl_elem_get_name(helem);
 | 
			
		||||
            const int index = snd_hctl_elem_get_index(helem);
 | 
			
		||||
            const int device = snd_hctl_elem_get_device(helem);
 | 
			
		||||
            snd_mixer_elem_t *new_melem;
 | 
			
		||||
 
 | 
			
		||||
            /* Put the hctl pointer as our private data - it will be useful for callbacks */
 | 
			
		||||
            if ((err = snd_mixer_elem_new(&new_melem, SND_MIXER_ELEM_PULSEAUDIO, 0, helem, NULL)) < 0) {
 | 
			
		||||
                pa_log_warn("snd_mixer_elem_new failed: %s", pa_alsa_strerror(err));
 | 
			
		||||
                return 0;
 | 
			
		||||
            new_melem = pa_alsa_mixer_find(mixer, iface, name, index, device);
 | 
			
		||||
            if (!new_melem) {
 | 
			
		||||
                /* Put the hctl pointer as our private data - it will be useful for callbacks */
 | 
			
		||||
                if ((err = snd_mixer_elem_new(&new_melem, SND_MIXER_ELEM_PULSEAUDIO, 0, helem, NULL)) < 0) {
 | 
			
		||||
                    pa_log_warn("snd_mixer_elem_new failed: %s", pa_alsa_strerror(err));
 | 
			
		||||
                    return 0;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ((err = snd_mixer_elem_attach(new_melem, helem)) < 0) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,6 +52,7 @@ typedef void (*pa_free_cb_t)(void *p);
 | 
			
		|||
#define PA_UNLIKELY(x) (x)
 | 
			
		||||
#define PA_PRINTF_FUNC(fmt, arg1)
 | 
			
		||||
#endif
 | 
			
		||||
#define PA_UNUSED SPA_UNUSED
 | 
			
		||||
 | 
			
		||||
#define PA_MIN(a,b)                    \
 | 
			
		||||
({                                     \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,6 +115,11 @@ static inline int pa_idxset_put(pa_idxset*s, void *p, uint32_t *idx)
 | 
			
		|||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool pa_idxset_contains(pa_idxset *s, const void *p)
 | 
			
		||||
{
 | 
			
		||||
	return pa_idxset_find(s, p) != NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline pa_idxset *pa_idxset_copy(pa_idxset *s, pa_copy_func_t copy_func)
 | 
			
		||||
{
 | 
			
		||||
	pa_idxset_item *item;
 | 
			
		||||
| 
						 | 
				
			
			@ -134,6 +139,35 @@ static inline bool pa_idxset_isempty(const pa_idxset *s)
 | 
			
		|||
			return false;
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool pa_idxset_isdisjoint(pa_idxset *s, pa_idxset *t)
 | 
			
		||||
{
 | 
			
		||||
	pa_idxset_item *item;
 | 
			
		||||
	pa_array_for_each(item, &s->array)
 | 
			
		||||
		if (item->ptr != NULL && pa_idxset_contains(t, item->ptr))
 | 
			
		||||
			return false;
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool pa_idxset_issubset(pa_idxset *s, pa_idxset *t)
 | 
			
		||||
{
 | 
			
		||||
	pa_idxset_item *item;
 | 
			
		||||
	pa_array_for_each(item, &s->array)
 | 
			
		||||
		if (item->ptr != NULL && !pa_idxset_contains(t, item->ptr))
 | 
			
		||||
			return false;
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool pa_idxset_issuperset(pa_idxset *s, pa_idxset *t)
 | 
			
		||||
{
 | 
			
		||||
	return pa_idxset_issubset(t, s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool pa_idxset_equals(pa_idxset *s, pa_idxset *t)
 | 
			
		||||
{
 | 
			
		||||
	return pa_idxset_issubset(s, t) && pa_idxset_issuperset(s, t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline unsigned pa_idxset_size(pa_idxset*s)
 | 
			
		||||
{
 | 
			
		||||
	unsigned count = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -144,13 +178,13 @@ static inline unsigned pa_idxset_size(pa_idxset*s)
 | 
			
		|||
	return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void *pa_idxset_search(pa_idxset *s, uint32_t *idx)
 | 
			
		||||
static inline pa_idxset_item *pa_idxset_search(pa_idxset *s, uint32_t *idx)
 | 
			
		||||
{
 | 
			
		||||
        pa_idxset_item *item;
 | 
			
		||||
	for (item = pa_array_get_unchecked(&s->array, *idx, pa_idxset_item);
 | 
			
		||||
	     pa_array_check(&s->array, item); item++, (*idx)++) {
 | 
			
		||||
		if (item->ptr != NULL)
 | 
			
		||||
			return item->ptr;
 | 
			
		||||
			return item;
 | 
			
		||||
	}
 | 
			
		||||
	*idx = PA_IDXSET_INVALID;
 | 
			
		||||
	return NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -158,19 +192,52 @@ static inline void *pa_idxset_search(pa_idxset *s, uint32_t *idx)
 | 
			
		|||
 | 
			
		||||
static inline void *pa_idxset_next(pa_idxset *s, uint32_t *idx)
 | 
			
		||||
{
 | 
			
		||||
        pa_idxset_item *item;
 | 
			
		||||
	(*idx)++;;
 | 
			
		||||
	return pa_idxset_search(s, idx);
 | 
			
		||||
	item = pa_idxset_search(s, idx);
 | 
			
		||||
	return item ? item->ptr : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void* pa_idxset_first(pa_idxset *s, uint32_t *idx)
 | 
			
		||||
{
 | 
			
		||||
	uint32_t i = 0;
 | 
			
		||||
	void *ptr = pa_idxset_search(s, &i);
 | 
			
		||||
        pa_idxset_item *item = pa_idxset_search(s, &i);
 | 
			
		||||
	if (idx)
 | 
			
		||||
		*idx = i;
 | 
			
		||||
	return item ? item->ptr : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void* pa_idxset_steal_first(pa_idxset *s, uint32_t *idx)
 | 
			
		||||
{
 | 
			
		||||
	uint32_t i = 0;
 | 
			
		||||
	void *ptr;
 | 
			
		||||
        pa_idxset_item *item = pa_idxset_search(s, &i);
 | 
			
		||||
	if (idx)
 | 
			
		||||
		*idx = i;
 | 
			
		||||
	ptr = item ? item->ptr : NULL;
 | 
			
		||||
	item->ptr = NULL;
 | 
			
		||||
	return ptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void* pa_idxset_steal_last(pa_idxset *s, uint32_t *idx)
 | 
			
		||||
{
 | 
			
		||||
        pa_idxset_item *item;
 | 
			
		||||
	uint32_t i;
 | 
			
		||||
	for (i = pa_array_get_len(&s->array, pa_idxset_item); i > 0; i--) {
 | 
			
		||||
		item = pa_array_get_unchecked(&s->array, i-1, pa_idxset_item);
 | 
			
		||||
		if (item->ptr != NULL) {
 | 
			
		||||
			void *ptr = item->ptr;
 | 
			
		||||
			item->ptr = NULL;
 | 
			
		||||
			if (idx)
 | 
			
		||||
				*idx = i-1;
 | 
			
		||||
			return ptr;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (idx)
 | 
			
		||||
		*idx = PA_IDXSET_INVALID;
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void* pa_idxset_get_by_data(pa_idxset*s, const void *p, uint32_t *idx)
 | 
			
		||||
{
 | 
			
		||||
	pa_idxset_item *item = pa_idxset_find(s, p);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue