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);
 | 
										pa_dynarray_append(&impl->out.devices, dev);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if (impl->use_ucm) {
 | 
									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);
 | 
											true, impl->ports, ap, NULL);
 | 
				
			||||||
					pa_alsa_ucm_add_ports(&dev->ports, m->proplist, &m->ucm_context,
 | 
										pa_alsa_ucm_add_ports(&dev->ports, m->proplist, &m->ucm_context,
 | 
				
			||||||
						true, impl, dev->pcm_handle, impl->profile_set->ignore_dB);
 | 
											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) {
 | 
									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);
 | 
											false, impl->ports, ap, NULL);
 | 
				
			||||||
					pa_alsa_ucm_add_ports(&dev->ports, m->proplist, &m->ucm_context,
 | 
										pa_alsa_ucm_add_ports(&dev->ports, m->proplist, &m->ucm_context,
 | 
				
			||||||
						false, impl, dev->pcm_handle, impl->profile_set->ignore_dB);
 | 
											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
 | 
						* will be NULL, but the UCM device enable sequence will still need to be
 | 
				
			||||||
	* executed. */
 | 
						* executed. */
 | 
				
			||||||
	if (dev->active_port && dev->ucm_context) {
 | 
						if (dev->active_port && dev->ucm_context) {
 | 
				
			||||||
		if ((res = pa_alsa_ucm_set_port(dev->ucm_context, dev->active_port,
 | 
							if ((res = pa_alsa_ucm_set_port(dev->ucm_context, dev->active_port)) < 0)
 | 
				
			||||||
					dev->direction == PA_ALSA_DIRECTION_OUTPUT)) < 0)
 | 
					 | 
				
			||||||
			return res;
 | 
								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 UCM is available for this card then update the verb */
 | 
				
			||||||
	if (impl->use_ucm) {
 | 
						if (impl->use_ucm) {
 | 
				
			||||||
		if ((res = pa_alsa_ucm_set_profile(&impl->ucm, impl,
 | 
							if ((res = pa_alsa_ucm_set_profile(&impl->ucm, impl,
 | 
				
			||||||
		    np->profile.flags & ACP_PROFILE_OFF ? NULL : np->profile.name,
 | 
							    np->profile.flags & ACP_PROFILE_OFF ? NULL : np, op)) < 0) {
 | 
				
			||||||
		    op ? op->profile.name : NULL)) < 0) {
 | 
					 | 
				
			||||||
			return res;
 | 
								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) {
 | 
							PA_IDXSET_FOREACH(am, np->output_mappings, idx) {
 | 
				
			||||||
			if (impl->use_ucm)
 | 
								if (impl->use_ucm)
 | 
				
			||||||
				/* Update ports priorities */
 | 
									/* 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);
 | 
										true, impl->ports, np, NULL);
 | 
				
			||||||
			device_enable(impl, am, &am->output);
 | 
								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) {
 | 
							PA_IDXSET_FOREACH(am, np->input_mappings, idx) {
 | 
				
			||||||
			if (impl->use_ucm)
 | 
								if (impl->use_ucm)
 | 
				
			||||||
				/* Update ports priorities */
 | 
									/* 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);
 | 
										false, impl->ports, np, NULL);
 | 
				
			||||||
			device_enable(impl, am, &am->input);
 | 
								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);
 | 
							mixer_volume_init(impl, d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		sync_mixer(d, p);
 | 
							sync_mixer(d, p);
 | 
				
			||||||
		res = pa_alsa_ucm_set_port(d->ucm_context, p,
 | 
							res = pa_alsa_ucm_set_port(d->ucm_context, p);
 | 
				
			||||||
					dev->direction == ACP_DIRECTION_PLAYBACK);
 | 
					 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		pa_alsa_port_data *data;
 | 
							pa_alsa_port_data *data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -381,6 +381,9 @@ struct pa_alsa_profile {
 | 
				
			||||||
    pa_idxset *input_mappings;
 | 
					    pa_idxset *input_mappings;
 | 
				
			||||||
    pa_idxset *output_mappings;
 | 
					    pa_idxset *output_mappings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* ucm device context */
 | 
				
			||||||
 | 
					    pa_alsa_ucm_profile_context ucm_context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct {
 | 
					    struct {
 | 
				
			||||||
	pa_dynarray devices;
 | 
						pa_dynarray devices;
 | 
				
			||||||
    } out;
 | 
					    } 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_device pa_alsa_ucm_device;
 | 
				
			||||||
typedef struct pa_alsa_ucm_config pa_alsa_ucm_config;
 | 
					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_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_port_data pa_alsa_ucm_port_data;
 | 
				
			||||||
typedef struct pa_alsa_ucm_volume pa_alsa_ucm_volume;
 | 
					typedef struct pa_alsa_ucm_volume pa_alsa_ucm_volume;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index);
 | 
					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);
 | 
					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);
 | 
					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,
 | 
					        pa_card *card,
 | 
				
			||||||
        snd_pcm_t *pcm_handle,
 | 
					        snd_pcm_t *pcm_handle,
 | 
				
			||||||
        bool ignore_dB);
 | 
					        bool ignore_dB);
 | 
				
			||||||
void pa_alsa_ucm_add_ports_combination(
 | 
					void pa_alsa_ucm_add_port(
 | 
				
			||||||
        pa_hashmap *hash,
 | 
					        pa_hashmap *hash,
 | 
				
			||||||
        pa_alsa_ucm_mapping_context *context,
 | 
					        pa_alsa_ucm_mapping_context *context,
 | 
				
			||||||
        bool is_sink,
 | 
					        bool is_sink,
 | 
				
			||||||
        pa_hashmap *ports,
 | 
					        pa_hashmap *ports,
 | 
				
			||||||
        pa_card_profile *cp,
 | 
					        pa_card_profile *cp,
 | 
				
			||||||
        pa_core *core);
 | 
					        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_free(pa_alsa_ucm_config *ucm);
 | 
				
			||||||
void pa_alsa_ucm_mapping_context_free(pa_alsa_ucm_mapping_context *context);
 | 
					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;
 | 
					    pa_proplist *proplist;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int n_confdev;
 | 
					    pa_idxset *conflicting_devices;
 | 
				
			||||||
    int n_suppdev;
 | 
					    pa_idxset *supported_devices;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    const char **conflicting_devices;
 | 
					 | 
				
			||||||
    const char **supported_devices;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_direction_t action_direction;
 | 
					    pa_direction_t action_direction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -270,17 +268,19 @@ struct pa_alsa_ucm_mapping_context {
 | 
				
			||||||
    pa_alsa_ucm_config *ucm;
 | 
					    pa_alsa_ucm_config *ucm;
 | 
				
			||||||
    pa_direction_t direction;
 | 
					    pa_direction_t direction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_idxset *ucm_devices;
 | 
					    pa_alsa_ucm_device *ucm_device;
 | 
				
			||||||
    pa_idxset *ucm_modifiers;
 | 
					    pa_alsa_ucm_modifier *ucm_modifier;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct pa_alsa_ucm_profile_context {
 | 
				
			||||||
 | 
					    pa_alsa_ucm_verb *verb;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pa_alsa_ucm_port_data {
 | 
					struct pa_alsa_ucm_port_data {
 | 
				
			||||||
    pa_alsa_ucm_config *ucm;
 | 
					    pa_alsa_ucm_config *ucm;
 | 
				
			||||||
    pa_device_port *core_port;
 | 
					    pa_device_port *core_port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* A single port will be associated with multiple devices if it represents
 | 
					    pa_alsa_ucm_device *device;
 | 
				
			||||||
     * a combination of devices. */
 | 
					 | 
				
			||||||
    pa_dynarray *devices; /* pa_alsa_ucm_device */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* profile name -> pa_alsa_path for volume control */
 | 
					    /* profile name -> pa_alsa_path for volume control */
 | 
				
			||||||
    pa_hashmap *paths;
 | 
					    pa_hashmap *paths;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1626,20 +1626,29 @@ static int mixer_class_event(snd_mixer_class_t *class, unsigned int mask,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int err;
 | 
					    int err;
 | 
				
			||||||
    const char *name = snd_hctl_elem_get_name(helem);
 | 
					    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) {
 | 
					    if (mask == SND_CTL_EVENT_MASK_REMOVE) {
 | 
				
			||||||
        // NOTE: unless remove pointer to melem from link-list at private_data of helem, hits
 | 
					        /* NOTE: Unless we remove the pointer to melem from the linked-list at
 | 
				
			||||||
	// assersion in alsa-lib since the list is not empty.
 | 
					         * private_data of helem, an assertion will be hit in alsa-lib since
 | 
				
			||||||
 | 
					         * the list is not empty. */
 | 
				
			||||||
        snd_mixer_elem_detach(melem, helem);
 | 
					        snd_mixer_elem_detach(melem, helem);
 | 
				
			||||||
    } else if (mask & SND_CTL_EVENT_MASK_ADD) {
 | 
					    } else if (mask & SND_CTL_EVENT_MASK_ADD) {
 | 
				
			||||||
        snd_ctl_elem_iface_t iface = snd_hctl_elem_get_interface(helem);
 | 
					        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) {
 | 
					        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;
 | 
					            snd_mixer_elem_t *new_melem;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
            /* Put the hctl pointer as our private data - it will be useful for callbacks */
 | 
					            new_melem = pa_alsa_mixer_find(mixer, iface, name, index, device);
 | 
				
			||||||
            if ((err = snd_mixer_elem_new(&new_melem, SND_MIXER_ELEM_PULSEAUDIO, 0, helem, NULL)) < 0) {
 | 
					            if (!new_melem) {
 | 
				
			||||||
                pa_log_warn("snd_mixer_elem_new failed: %s", pa_alsa_strerror(err));
 | 
					                /* Put the hctl pointer as our private data - it will be useful for callbacks */
 | 
				
			||||||
                return 0;
 | 
					                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) {
 | 
					            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_UNLIKELY(x) (x)
 | 
				
			||||||
#define PA_PRINTF_FUNC(fmt, arg1)
 | 
					#define PA_PRINTF_FUNC(fmt, arg1)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					#define PA_UNUSED SPA_UNUSED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PA_MIN(a,b)                    \
 | 
					#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;
 | 
						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)
 | 
					static inline pa_idxset *pa_idxset_copy(pa_idxset *s, pa_copy_func_t copy_func)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	pa_idxset_item *item;
 | 
						pa_idxset_item *item;
 | 
				
			||||||
| 
						 | 
					@ -134,6 +139,35 @@ static inline bool pa_idxset_isempty(const pa_idxset *s)
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
	return true;
 | 
						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)
 | 
					static inline unsigned pa_idxset_size(pa_idxset*s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned count = 0;
 | 
						unsigned count = 0;
 | 
				
			||||||
| 
						 | 
					@ -144,13 +178,13 @@ static inline unsigned pa_idxset_size(pa_idxset*s)
 | 
				
			||||||
	return count;
 | 
						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;
 | 
					        pa_idxset_item *item;
 | 
				
			||||||
	for (item = pa_array_get_unchecked(&s->array, *idx, pa_idxset_item);
 | 
						for (item = pa_array_get_unchecked(&s->array, *idx, pa_idxset_item);
 | 
				
			||||||
	     pa_array_check(&s->array, item); item++, (*idx)++) {
 | 
						     pa_array_check(&s->array, item); item++, (*idx)++) {
 | 
				
			||||||
		if (item->ptr != NULL)
 | 
							if (item->ptr != NULL)
 | 
				
			||||||
			return item->ptr;
 | 
								return item;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	*idx = PA_IDXSET_INVALID;
 | 
						*idx = PA_IDXSET_INVALID;
 | 
				
			||||||
	return NULL;
 | 
						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)
 | 
					static inline void *pa_idxset_next(pa_idxset *s, uint32_t *idx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					        pa_idxset_item *item;
 | 
				
			||||||
	(*idx)++;;
 | 
						(*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)
 | 
					static inline void* pa_idxset_first(pa_idxset *s, uint32_t *idx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t i = 0;
 | 
						uint32_t i = 0;
 | 
				
			||||||
	void *ptr = pa_idxset_search(s, &i);
 | 
					        pa_idxset_item *item = pa_idxset_search(s, &i);
 | 
				
			||||||
	if (idx)
 | 
						if (idx)
 | 
				
			||||||
		*idx = i;
 | 
							*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;
 | 
						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)
 | 
					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);
 | 
						pa_idxset_item *item = pa_idxset_find(s, p);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue