]> git.alsa-project.org Git - alsa-lib.git/commitdiff
pcm: dmix: fix sw_params handling of timestamp types in direct plugins
authorsylvain.bertrand@gmail.com <sylvain.bertrand@gmail.com>
Wed, 15 Apr 2020 00:44:39 +0000 (00:44 +0000)
committerTakashi Iwai <tiwai@suse.de>
Fri, 17 Apr 2020 09:17:02 +0000 (11:17 +0200)
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>
src/conf/alsa.conf
src/conf/pcm/dmix.conf
src/conf/pcm/dsnoop.conf
src/pcm/pcm_direct.c
src/pcm/pcm_direct.h
src/pcm/pcm_dmix.c
src/pcm/pcm_dshare.c
src/pcm/pcm_dsnoop.c
src/pcm/pcm_local.h

index a091b810f9ed3f342a581d3f5e1d6fe6db1a9df4..0e01c887dc28023cd0f7b75f443bde73443afbe1 100644 (file)
@@ -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
index 7fa5c8b2e20ae4bcbc7fd0953ac638e98a001203..50e573da5d35acb05cfc41addaf0079f2535d1fd 100644 (file)
@@ -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
index abbd44f7fd796ae0ffda3476e8ea7e8e5e9cf3b9..f4336e5f5e070a071bba21f573f64fabdd4ff645 100644 (file)
@@ -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
index 54d99005461b0150a65a6fa3ebf5e95a8485b02f..aa60a47774aebdeda7b4f9e3afe8ffad831c52b5 100644 (file)
@@ -991,8 +991,11 @@ 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)
 {
+       if (params->tstamp_type != pcm->tstamp_type)
+               return -EINVAL;
+
        /* values are cached in the pcm structure */
        return 0;
 }
@@ -1318,6 +1321,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;
@@ -1878,6 +1890,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 +1954,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;
index 221edbe168795e496ac4e2ba2a33d82e64cd3680..8a236970a3a1b87f58a5352aa4495ad62e804b91 100644 (file)
@@ -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;                /* cached from conf, can be -1(default) on top of real types */
        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;
 };
index d533f40c58924e89924574a5f7b911e4376d721f..843fa3168756b5260170ac8145593092245ebc95 100644 (file)
@@ -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
index 59448cfb58838ee45812a7815f34e2d7f0ffbbc1..6a99452b80fb48df30c8ae13e778ff8adc6d473c 100644 (file)
@@ -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
index 24f472c72c8ecd4761268798ccac8d981350ade6..c64df381e2250b8c02d0ba763fd27183df83b9e2 100644 (file)
@@ -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
index 05ed935f1f163620313c3a838e7b797894fec53e..89d4125b875d2c6072746470c0de6f6220bcd7a1 100644 (file)
@@ -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);