On Wed, Apr 01, 2020 at 05:59:52PM +0200, Takashi Iwai wrote:
Heh, my initial patch was also with that strong type, but I changed it
because I wanted to allow the "system default" value, which isn't
represented with that type.
I stand corrected. I noticed that after sending my email :(
The patch actually did not install the tstamp configuration option. I did add
the installation of the option all direct based plugins (dmix/dsnoop/dshare),
that with a global configuration option.
I did some testing and quickly found out some defaults for sw_params are
installed in pcm_params.c:_snd_pcm_hw_params_internal from a snd_pcm_hw_params
installation call.
Those defaults are defined in pcm_params.c:snd_pcm_sw_params_default which
tstamp value will break in the case of a plugin pipeline ending with already
running direct plugin.
It means that all calls to snd_pcm_sw_params done internally should have their
sw_params values investigated to see if they work with a plugin pipeline ending
with an already running direct plugin.
For the first case, in pcm_params.c:_snd_pcm_hw_params_internal, it seems that
"valid" default sw_params for a plugin pipeline should be made sort of
recursive or "something else".
I'll start to try to find a way to deal with with this first case and will
start to investigate those internal sw_params uses.
Meanwhile, below is the modified patch.
cheers,
--
Sylvain
---
diff --git a/src/conf/alsa.conf b/src/conf/alsa.conf
index a091b810..0e01c887 100644
--- a/src/conf/alsa.conf
+++ b/src/conf/alsa.conf
@@ -69,6 +69,7 @@ defaults.pcm.minperiodtime 5000 # in us
defaults.pcm.ipc_key 5678293
defaults.pcm.ipc_gid audio
defaults.pcm.ipc_perm 0660
+defaults.pcm.tstamp_type "default"
defaults.pcm.dmix.max_periods 0
defaults.pcm.dmix.channels 2
defaults.pcm.dmix.rate 48000
diff --git a/src/conf/pcm/dmix.conf b/src/conf/pcm/dmix.conf
index 7fa5c8b2..50e573da 100644
--- a/src/conf/pcm/dmix.conf
+++ b/src/conf/pcm/dmix.conf
@@ -56,6 +56,10 @@ pcm.!dmix {
@func refer
name defaults.pcm.ipc_perm
}
+ tstamp_type {
+ @func refer
+ name defaults.pcm.tstamp_type
+ }
slave {
pcm {
type hw
diff --git a/src/conf/pcm/dsnoop.conf b/src/conf/pcm/dsnoop.conf
index abbd44f7..f4336e5f 100644
--- a/src/conf/pcm/dsnoop.conf
+++ b/src/conf/pcm/dsnoop.conf
@@ -49,6 +49,10 @@ pcm.!dsnoop {
@func refer
name defaults.pcm.ipc_perm
}
+ tstamp_type {
+ @func refer
+ name defaults.pcm.tstamp_type
+ }
slave {
pcm {
type hw
diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
index 54d99005..b6f5c731 100644
--- a/src/pcm/pcm_direct.c
+++ b/src/pcm/pcm_direct.c
@@ -991,8 +991,13 @@ int snd_pcm_direct_hw_free(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
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)
{
+ snd_pcm_direct_t *dmix = pcm->private_data;
+
+ if ((int)params->tstamp_type != dmix->tstamp_type)
+ return -EINVAL;
+
/* values are cached in the pcm structure */
return 0;
}
@@ -1318,6 +1323,15 @@ int snd_pcm_direct_initialize_slave(snd_pcm_direct_t *dmix, snd_pcm_t *spcm, str
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 &&
dmix->type != SND_PCM_TYPE_DSHARE)
goto __skip_silencing;
@@ -1341,6 +1355,9 @@ int snd_pcm_direct_initialize_slave(snd_pcm_direct_t *dmix, snd_pcm_t *spcm, str
return ret;
}
+ /* copy back the slave setup */
+ dmix->tstamp_type = (int)sw_params.tstamp_type;
+
if (dmix->type == SND_PCM_TYPE_DSHARE) {
const snd_pcm_channel_area_t *dst_areas;
dst_areas = snd_pcm_mmap_areas(spcm);
@@ -1878,6 +1895,7 @@ int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf,
rec->var_periodsize = 0;
rec->direct_memory_access = 1;
rec->hw_ptr_alignment = SND_PCM_HW_PTR_ALIGNMENT_AUTO;
+ rec->tstamp_type = -1;
/* read defaults */
if (snd_config_search(root, "defaults.pcm.dmix_max_periods", &n) >= 0) {
@@ -1941,6 +1959,27 @@ int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf,
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) {
char *group;
char *endp;
diff --git a/src/pcm/pcm_direct.h b/src/pcm/pcm_direct.h
index 221edbe1..63dd645b 100644
--- a/src/pcm/pcm_direct.h
+++ b/src/pcm/pcm_direct.h
@@ -173,6 +173,7 @@ struct snd_pcm_direct {
unsigned int recoveries; /* mirror of executed recoveries on slave */
int direct_memory_access; /* use arch-optimized buffer RW */
snd_pcm_direct_hw_ptr_alignment_t hw_ptr_alignment;
+ int tstamp_type;
union {
struct {
int shmid_sum; /* IPC global sum ring buffer memory identification */
@@ -357,6 +358,7 @@ struct snd_pcm_direct_open_conf {
int var_periodsize;
int direct_memory_access;
snd_pcm_direct_hw_ptr_alignment_t hw_ptr_alignment;
+ int tstamp_type;
snd_config_t *slave;
snd_config_t *bindings;
};
diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c
index d533f40c..843fa316 100644
--- a/src/pcm/pcm_dmix.c
+++ b/src/pcm/pcm_dmix.c
@@ -1038,6 +1038,7 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
dmix->ipc_key = opts->ipc_key;
dmix->ipc_perm = opts->ipc_perm;
dmix->ipc_gid = opts->ipc_gid;
+ dmix->tstamp_type = opts->tstamp_type;
dmix->semid = -1;
dmix->shmid = -1;
@@ -1237,6 +1238,9 @@ pcm.name {
# roundup
# rounddown
# auto (default)
+ tstamp_type STR # timestamp type
+ # STR can be one of the below strings :
+ # default, gettimeofday, monotonic, monotonic_raw
slave STR
# or
slave { # Slave definition
diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c
index 59448cfb..6a99452b 100644
--- a/src/pcm/pcm_dshare.c
+++ b/src/pcm/pcm_dshare.c
@@ -723,6 +723,7 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
dshare->ipc_key = opts->ipc_key;
dshare->ipc_perm = opts->ipc_perm;
dshare->ipc_gid = opts->ipc_gid;
+ dshare->tstamp_type = opts->tstamp_type;
dshare->semid = -1;
dshare->shmid = -1;
@@ -929,6 +930,9 @@ pcm.name {
# roundup
# rounddown
# auto (default)
+ tstamp_type STR # timestamp type
+ # STR can be one of the below strings :
+ # default, gettimeofday, monotonic, monotonic_raw
slave STR
# or
slave { # Slave definition
diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c
index 24f472c7..c64df381 100644
--- a/src/pcm/pcm_dsnoop.c
+++ b/src/pcm/pcm_dsnoop.c
@@ -591,6 +591,7 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
dsnoop->ipc_key = opts->ipc_key;
dsnoop->ipc_perm = opts->ipc_perm;
dsnoop->ipc_gid = opts->ipc_gid;
+ dsnoop->tstamp_type = opts->tstamp_type;
dsnoop->semid = -1;
dsnoop->shmid = -1;
@@ -780,6 +781,9 @@ pcm.name {
# roundup
# rounddown
# auto (default)
+ tstamp_type STR # timestamp type
+ # STR can be one of the below strings :
+ # default, gettimeofday, monotonic, monotonic_raw
slave STR
# or
slave { # Slave definition
diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
index 05ed935f..89d4125b 100644
--- a/src/pcm/pcm_local.h
+++ b/src/pcm/pcm_local.h
@@ -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 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 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);