diff --git a/pipewire-alsa/alsa-plugins/pcm_pipewire.c b/pipewire-alsa/alsa-plugins/pcm_pipewire.c index 600f68ef0..e536d3e1a 100644 --- a/pipewire-alsa/alsa-plugins/pcm_pipewire.c +++ b/pipewire-alsa/alsa-plugins/pcm_pipewire.c @@ -721,6 +721,36 @@ static int snd_pcm_pipewire_hw_params(snd_pcm_ioplug_t * io, return 0; } +static int snd_pcm_pipewire_sw_params(snd_pcm_ioplug_t * io, + snd_pcm_sw_params_t * sw_params) +{ + snd_pcm_pipewire_t *pw = io->private_data; + + if (pw->stream) { + snd_pcm_uframes_t min_avail; + snd_pcm_sw_params_get_avail_min( sw_params, &min_avail); + snd_pcm_sw_params_get_boundary(sw_params, &pw->boundary); + if (min_avail != pw->min_avail) { + char *latency; + struct spa_dict_item item[1]; + uint32_t min_period = (MIN_PERIOD * io->rate / 48000); + + pw->min_avail = SPA_MAX(min_avail, min_period); + + latency = spa_aprintf("%lu/%u", pw->min_avail, io->rate); + item[0] = SPA_DICT_ITEM_INIT(PW_KEY_NODE_LATENCY, latency); + + pw_log_debug("%p: sw_params update props %p %ld", pw, pw->stream, pw->min_avail); + pw_stream_update_properties(pw->stream, &SPA_DICT_INIT(item, 1)); + free(latency); + } + } else { + pw_log_debug("%p: sw_params pre-prepare noop", pw); + } + + return 0; +} + struct chmap_info { enum snd_pcm_chmap_position pos; enum spa_audio_channel channel; @@ -855,6 +885,7 @@ static snd_pcm_ioplug_callback_t pipewire_pcm_callback = { .poll_descriptors = snd_pcm_pipewire_poll_descriptors, .poll_revents = snd_pcm_pipewire_poll_revents, .hw_params = snd_pcm_pipewire_hw_params, + .sw_params = snd_pcm_pipewire_sw_params, .set_chmap = snd_pcm_pipewire_set_chmap, .get_chmap = snd_pcm_pipewire_get_chmap, .query_chmaps = snd_pcm_pipewire_query_chmaps,