mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	pcm: dmix: fix sw_params handling of timestamp types in direct plugins
In pcms using direct plugins (dmix/dsnoop/dshare), the timestamp type could be different from the terminating hw plugin, then the kernel driver. Be sure such pcms have plugins using consistently the same timestamp type. signed-off-by: Sylvain Bertrand <sylvain.bertrand@legeek.net> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
		
							parent
							
								
									fb48ad9e4f
								
							
						
					
					
						commit
						d12df1dc9c
					
				
					 9 changed files with 60 additions and 1 deletions
				
			
		| 
						 | 
					@ -69,6 +69,7 @@ defaults.pcm.minperiodtime 5000		# in us
 | 
				
			||||||
defaults.pcm.ipc_key 5678293
 | 
					defaults.pcm.ipc_key 5678293
 | 
				
			||||||
defaults.pcm.ipc_gid audio
 | 
					defaults.pcm.ipc_gid audio
 | 
				
			||||||
defaults.pcm.ipc_perm 0660
 | 
					defaults.pcm.ipc_perm 0660
 | 
				
			||||||
 | 
					defaults.pcm.tstamp_type "default"
 | 
				
			||||||
defaults.pcm.dmix.max_periods 0
 | 
					defaults.pcm.dmix.max_periods 0
 | 
				
			||||||
defaults.pcm.dmix.channels 2
 | 
					defaults.pcm.dmix.channels 2
 | 
				
			||||||
defaults.pcm.dmix.rate 48000
 | 
					defaults.pcm.dmix.rate 48000
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -56,6 +56,10 @@ pcm.!dmix {
 | 
				
			||||||
		@func refer
 | 
							@func refer
 | 
				
			||||||
		name defaults.pcm.ipc_perm
 | 
							name defaults.pcm.ipc_perm
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						tstamp_type {
 | 
				
			||||||
 | 
							@func refer
 | 
				
			||||||
 | 
							name defaults.pcm.tstamp_type
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	slave {
 | 
						slave {
 | 
				
			||||||
		pcm {
 | 
							pcm {
 | 
				
			||||||
			type hw
 | 
								type hw
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,6 +49,10 @@ pcm.!dsnoop {
 | 
				
			||||||
		@func refer
 | 
							@func refer
 | 
				
			||||||
		name defaults.pcm.ipc_perm
 | 
							name defaults.pcm.ipc_perm
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						tstamp_type {
 | 
				
			||||||
 | 
							@func refer
 | 
				
			||||||
 | 
							name defaults.pcm.tstamp_type
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	slave {
 | 
						slave {
 | 
				
			||||||
		pcm {
 | 
							pcm {
 | 
				
			||||||
			type hw
 | 
								type hw
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -991,8 +991,11 @@ int snd_pcm_direct_hw_free(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int snd_pcm_direct_sw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t * params ATTRIBUTE_UNUSED)
 | 
					int snd_pcm_direct_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						if (params->tstamp_type != pcm->tstamp_type)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* values are cached in the pcm structure */
 | 
						/* values are cached in the pcm structure */
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1318,6 +1321,15 @@ int snd_pcm_direct_initialize_slave(snd_pcm_direct_t *dmix, snd_pcm_t *spcm, str
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dmix->tstamp_type != -1) {
 | 
				
			||||||
 | 
							ret = snd_pcm_sw_params_set_tstamp_type(spcm, &sw_params,
 | 
				
			||||||
 | 
												dmix->tstamp_type);
 | 
				
			||||||
 | 
							if (ret < 0) {
 | 
				
			||||||
 | 
								SNDERR("unable to set tstamp type");
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dmix->type != SND_PCM_TYPE_DMIX &&
 | 
						if (dmix->type != SND_PCM_TYPE_DMIX &&
 | 
				
			||||||
	    dmix->type != SND_PCM_TYPE_DSHARE)
 | 
						    dmix->type != SND_PCM_TYPE_DSHARE)
 | 
				
			||||||
		goto __skip_silencing;
 | 
							goto __skip_silencing;
 | 
				
			||||||
| 
						 | 
					@ -1878,6 +1890,7 @@ int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf,
 | 
				
			||||||
	rec->var_periodsize = 0;
 | 
						rec->var_periodsize = 0;
 | 
				
			||||||
	rec->direct_memory_access = 1;
 | 
						rec->direct_memory_access = 1;
 | 
				
			||||||
	rec->hw_ptr_alignment = SND_PCM_HW_PTR_ALIGNMENT_AUTO;
 | 
						rec->hw_ptr_alignment = SND_PCM_HW_PTR_ALIGNMENT_AUTO;
 | 
				
			||||||
 | 
						rec->tstamp_type = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* read defaults */
 | 
						/* read defaults */
 | 
				
			||||||
	if (snd_config_search(root, "defaults.pcm.dmix_max_periods", &n) >= 0) {
 | 
						if (snd_config_search(root, "defaults.pcm.dmix_max_periods", &n) >= 0) {
 | 
				
			||||||
| 
						 | 
					@ -1941,6 +1954,27 @@ int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if (strcmp(id, "tstamp_type") == 0) {
 | 
				
			||||||
 | 
								const char *str;
 | 
				
			||||||
 | 
								err = snd_config_get_string(n, &str);
 | 
				
			||||||
 | 
								if (err < 0) {
 | 
				
			||||||
 | 
									SNDERR("Invalid type for %s", id);
 | 
				
			||||||
 | 
									return -EINVAL;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (strcmp(str, "default") == 0)
 | 
				
			||||||
 | 
									rec->tstamp_type = -1;
 | 
				
			||||||
 | 
								else if (strcmp(str, "gettimeofday") == 0)
 | 
				
			||||||
 | 
									rec->tstamp_type = SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY;
 | 
				
			||||||
 | 
								else if (strcmp(str, "monotonic") == 0)
 | 
				
			||||||
 | 
									rec->tstamp_type = SND_PCM_TSTAMP_TYPE_MONOTONIC;
 | 
				
			||||||
 | 
								else if (strcmp(str, "monotonic_raw") == 0)
 | 
				
			||||||
 | 
									rec->tstamp_type = SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW;
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									SNDERR("The field tstamp_type is invalid : %s", str);
 | 
				
			||||||
 | 
									return -EINVAL;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if (strcmp(id, "ipc_gid") == 0) {
 | 
							if (strcmp(id, "ipc_gid") == 0) {
 | 
				
			||||||
			char *group;
 | 
								char *group;
 | 
				
			||||||
			char *endp;
 | 
								char *endp;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -173,6 +173,7 @@ struct snd_pcm_direct {
 | 
				
			||||||
	unsigned int recoveries;	/* mirror of executed recoveries on slave */
 | 
						unsigned int recoveries;	/* mirror of executed recoveries on slave */
 | 
				
			||||||
	int direct_memory_access;	/* use arch-optimized buffer RW */
 | 
						int direct_memory_access;	/* use arch-optimized buffer RW */
 | 
				
			||||||
	snd_pcm_direct_hw_ptr_alignment_t hw_ptr_alignment;
 | 
						snd_pcm_direct_hw_ptr_alignment_t hw_ptr_alignment;
 | 
				
			||||||
 | 
						int tstamp_type;		/* cached from conf, can be -1(default) on top of real types */
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		struct {
 | 
							struct {
 | 
				
			||||||
			int shmid_sum;			/* IPC global sum ring buffer memory identification */
 | 
								int shmid_sum;			/* IPC global sum ring buffer memory identification */
 | 
				
			||||||
| 
						 | 
					@ -357,6 +358,7 @@ struct snd_pcm_direct_open_conf {
 | 
				
			||||||
	int var_periodsize;
 | 
						int var_periodsize;
 | 
				
			||||||
	int direct_memory_access;
 | 
						int direct_memory_access;
 | 
				
			||||||
	snd_pcm_direct_hw_ptr_alignment_t hw_ptr_alignment;
 | 
						snd_pcm_direct_hw_ptr_alignment_t hw_ptr_alignment;
 | 
				
			||||||
 | 
						int tstamp_type;
 | 
				
			||||||
	snd_config_t *slave;
 | 
						snd_config_t *slave;
 | 
				
			||||||
	snd_config_t *bindings;
 | 
						snd_config_t *bindings;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1038,6 +1038,7 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
 | 
				
			||||||
	dmix->ipc_key = opts->ipc_key;
 | 
						dmix->ipc_key = opts->ipc_key;
 | 
				
			||||||
	dmix->ipc_perm = opts->ipc_perm;
 | 
						dmix->ipc_perm = opts->ipc_perm;
 | 
				
			||||||
	dmix->ipc_gid = opts->ipc_gid;
 | 
						dmix->ipc_gid = opts->ipc_gid;
 | 
				
			||||||
 | 
						dmix->tstamp_type = opts->tstamp_type;
 | 
				
			||||||
	dmix->semid = -1;
 | 
						dmix->semid = -1;
 | 
				
			||||||
	dmix->shmid = -1;
 | 
						dmix->shmid = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1237,6 +1238,9 @@ pcm.name {
 | 
				
			||||||
				# roundup
 | 
									# roundup
 | 
				
			||||||
				# rounddown
 | 
									# rounddown
 | 
				
			||||||
				# auto (default)
 | 
									# auto (default)
 | 
				
			||||||
 | 
						tstamp_type STR		# timestamp type
 | 
				
			||||||
 | 
									# STR can be one of the below strings :
 | 
				
			||||||
 | 
									# default, gettimeofday, monotonic, monotonic_raw
 | 
				
			||||||
	slave STR
 | 
						slave STR
 | 
				
			||||||
	# or
 | 
						# or
 | 
				
			||||||
	slave {			# Slave definition
 | 
						slave {			# Slave definition
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -723,6 +723,7 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
 | 
				
			||||||
	dshare->ipc_key = opts->ipc_key;
 | 
						dshare->ipc_key = opts->ipc_key;
 | 
				
			||||||
	dshare->ipc_perm = opts->ipc_perm;
 | 
						dshare->ipc_perm = opts->ipc_perm;
 | 
				
			||||||
	dshare->ipc_gid = opts->ipc_gid;
 | 
						dshare->ipc_gid = opts->ipc_gid;
 | 
				
			||||||
 | 
						dshare->tstamp_type = opts->tstamp_type;
 | 
				
			||||||
	dshare->semid = -1;
 | 
						dshare->semid = -1;
 | 
				
			||||||
	dshare->shmid = -1;
 | 
						dshare->shmid = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -929,6 +930,9 @@ pcm.name {
 | 
				
			||||||
		# roundup
 | 
							# roundup
 | 
				
			||||||
		# rounddown
 | 
							# rounddown
 | 
				
			||||||
		# auto (default)
 | 
							# auto (default)
 | 
				
			||||||
 | 
						tstamp_type STR		# timestamp type
 | 
				
			||||||
 | 
									# STR can be one of the below strings :
 | 
				
			||||||
 | 
									# default, gettimeofday, monotonic, monotonic_raw
 | 
				
			||||||
	slave STR
 | 
						slave STR
 | 
				
			||||||
	# or
 | 
						# or
 | 
				
			||||||
	slave {			# Slave definition
 | 
						slave {			# Slave definition
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -591,6 +591,7 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
 | 
				
			||||||
	dsnoop->ipc_key = opts->ipc_key;
 | 
						dsnoop->ipc_key = opts->ipc_key;
 | 
				
			||||||
	dsnoop->ipc_perm = opts->ipc_perm;
 | 
						dsnoop->ipc_perm = opts->ipc_perm;
 | 
				
			||||||
	dsnoop->ipc_gid = opts->ipc_gid;
 | 
						dsnoop->ipc_gid = opts->ipc_gid;
 | 
				
			||||||
 | 
						dsnoop->tstamp_type = opts->tstamp_type;
 | 
				
			||||||
	dsnoop->semid = -1;
 | 
						dsnoop->semid = -1;
 | 
				
			||||||
	dsnoop->shmid = -1;
 | 
						dsnoop->shmid = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -780,6 +781,9 @@ pcm.name {
 | 
				
			||||||
		# roundup
 | 
							# roundup
 | 
				
			||||||
		# rounddown
 | 
							# rounddown
 | 
				
			||||||
		# auto (default)
 | 
							# auto (default)
 | 
				
			||||||
 | 
						tstamp_type STR		# timestamp type
 | 
				
			||||||
 | 
									# STR can be one of the below strings :
 | 
				
			||||||
 | 
									# default, gettimeofday, monotonic, monotonic_raw
 | 
				
			||||||
	slave STR
 | 
						slave STR
 | 
				
			||||||
	# or
 | 
						# or
 | 
				
			||||||
	slave {			# Slave definition
 | 
						slave {			# Slave definition
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -928,6 +928,8 @@ int INTERNAL(snd_pcm_hw_params_set_buffer_size_last)(snd_pcm_t *pcm, snd_pcm_hw_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val);
 | 
					int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val);
 | 
				
			||||||
int INTERNAL(snd_pcm_sw_params_get_tstamp_mode)(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_t *val);
 | 
					int INTERNAL(snd_pcm_sw_params_get_tstamp_mode)(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_t *val);
 | 
				
			||||||
 | 
					int snd_pcm_sw_params_set_tstamp_type(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_type_t val);
 | 
				
			||||||
 | 
					int snd_pcm_sw_params_get_tstamp_type(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_type_t *val);
 | 
				
			||||||
int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
 | 
					int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
 | 
				
			||||||
int INTERNAL(snd_pcm_sw_params_get_avail_min)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val);
 | 
					int INTERNAL(snd_pcm_sw_params_get_avail_min)(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val);
 | 
				
			||||||
int snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
 | 
					int snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue