[alsa-devel] [PATCH 4/7] ALSA: core: add report of max inflight bytes
Takashi Iwai
tiwai at suse.de
Fri Sep 30 15:44:02 CEST 2016
On Fri, 30 Sep 2016 14:43:27 +0200,
Subhransu S. Prusty wrote:
>
> From: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
>
> Report size of data burst before updating the hw_ptr, e.g. while DMA
> operations are on-going.
>
> This can help fix two issues with stale data discussed many times over
> on the alsa-devel mailing list (refilling/reading ring buffer too late
> during capture or rewinding too close to the hw_ptr during playback)
>
> This patch only reports the maximum burst of data and does not provide
> hooks to negotiate its size. This might be useful to lower power or
> reduce latency, but isn't typically supported by fixed-function DMA
> hardware.
This needs to be discussed rather from the actual demand.
From the API change POV, the only (and the biggest) question is
whether hw_params is the best API. It looks feasible, so far, but
someone else might have a better idea. Let's see.
Takashi
>
> The use of IOCTL1 is not really required but keep for symmetry with
> existing code used to retried fifo_size
>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty at intel.com>
> ---
> include/sound/pcm.h | 2 ++
> include/uapi/sound/asound.h | 5 +++--
> sound/core/pcm_lib.c | 20 ++++++++++++++++++++
> sound/core/pcm_native.c | 7 +++++++
> 4 files changed, 32 insertions(+), 2 deletions(-)
>
> diff --git a/include/sound/pcm.h b/include/sound/pcm.h
> index 1accb8b..8c9d80a 100644
> --- a/include/sound/pcm.h
> +++ b/include/sound/pcm.h
> @@ -56,6 +56,7 @@ struct snd_pcm_hardware {
> unsigned int periods_min; /* min # of periods */
> unsigned int periods_max; /* max # of periods */
> size_t fifo_size; /* fifo size in bytes */
> + unsigned int max_inflight_bytes;/* hw_ptr precision/fuzziness, e.g. due to DMA transfers */
> };
>
> struct snd_pcm_substream;
> @@ -105,6 +106,7 @@ struct snd_pcm_ops {
> #define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2
> #define SNDRV_PCM_IOCTL1_GSTATE 3
> #define SNDRV_PCM_IOCTL1_FIFO_SIZE 4
> +#define SNDRV_PCM_IOCTL1_MAX_INFLIGHT_BYTES 5
>
> #define SNDRV_PCM_TRIGGER_STOP 0
> #define SNDRV_PCM_TRIGGER_START 1
> diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
> index 6828ed2..5f539d7 100644
> --- a/include/uapi/sound/asound.h
> +++ b/include/uapi/sound/asound.h
> @@ -392,8 +392,9 @@ struct snd_pcm_hw_params {
> unsigned int msbits; /* R: used most significant bits */
> unsigned int rate_num; /* R: rate numerator */
> unsigned int rate_den; /* R: rate denominator */
> - snd_pcm_uframes_t fifo_size; /* R: chip FIFO size in frames */
> - unsigned char reserved[64]; /* reserved for future */
> + snd_pcm_uframes_t fifo_size; /* R: chip FIFO size in frames, indicates buffering after hw_ptr updates */
> + unsigned int max_inflight_bytes;/* R: typically DMA burst in bytes, indicates buffering before hw_ptr updates */
> + unsigned char reserved[60]; /* reserved for future */
> };
>
> enum {
> diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
> index 1656ca9..06b44ed 100644
> --- a/sound/core/pcm_lib.c
> +++ b/sound/core/pcm_lib.c
> @@ -1827,6 +1827,23 @@ static int snd_pcm_lib_ioctl_fifo_size(struct snd_pcm_substream *substream,
> return 0;
> }
>
> +static int snd_pcm_lib_ioctl_max_inflight_bytes(
> + struct snd_pcm_substream *substream,
> + void *arg)
> +{
> + struct snd_pcm_hw_params *params = arg;
> +
> + params->max_inflight_bytes = substream->runtime->hw.max_inflight_bytes;
> + /*
> + * Sanity check that max_inflight_bytes isn't larger than buffer_size,
> + * couldn't think of any other checks
> + */
> + if (params->max_inflight_bytes > substream->runtime->buffer_size)
> + params->max_inflight_bytes = substream->runtime->buffer_size;
> +
> + return 0;
> +}
> +
> /**
> * snd_pcm_lib_ioctl - a generic PCM ioctl callback
> * @substream: the pcm substream instance
> @@ -1850,6 +1867,9 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
> return snd_pcm_lib_ioctl_channel_info(substream, arg);
> case SNDRV_PCM_IOCTL1_FIFO_SIZE:
> return snd_pcm_lib_ioctl_fifo_size(substream, arg);
> + case SNDRV_PCM_IOCTL1_MAX_INFLIGHT_BYTES:
> + return snd_pcm_lib_ioctl_max_inflight_bytes(substream, arg);
> +
> }
> return -ENXIO;
> }
> diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
> index 1965d83..a29b5af 100644
> --- a/sound/core/pcm_native.c
> +++ b/sound/core/pcm_native.c
> @@ -292,6 +292,7 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
>
> params->info = 0;
> params->fifo_size = 0;
> + params->max_inflight_bytes = 0;
> if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_SAMPLE_BITS))
> params->msbits = 0;
> if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_RATE)) {
> @@ -449,6 +450,12 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
> return changed;
> }
> }
> + if (!params->max_inflight_bytes) {
> + changed = substream->ops->ioctl(substream,
> + SNDRV_PCM_IOCTL1_MAX_INFLIGHT_BYTES, params);
> + if (changed < 0)
> + return changed;
> + }
> params->rmask = 0;
> return 0;
> }
> --
> 1.9.1
>
More information about the Alsa-devel
mailing list