diff mbox

[v2] ALSA: core: update tstamp only if audio_tstamp changed

Message ID 20171121082921.GA25386@lnxhenriken2.se.axis.com (mailing list archive)
State New, archived
Headers show

Commit Message

Henrik Eriksson Nov. 21, 2017, 8:29 a.m. UTC
commit 3179f6200188 ("ALSA: core: add .get_time_info") had a side effect
of changing the behaviour of the PCM runtime tstamp.  Prior to this
change tstamp was not updated by snd_pcm_update_hw_ptr0() unless the
hw_ptr had moved, after this change tstamp was always updated.

For an application using alsa-lib, doing snd_pcm_readi() followed by
snd_pcm_status() to estimate the age of the read samples by subtracting
status->avail * [sample rate] from status->tstamp this change degraded
the accuracy of the estimate on devices where the pcm hw does not
provide a granular hw_ptr, e.g., devices using
soc-generic-dmaengine-pcm.c and a dma-engine with residue_granularity
DMA_RESIDUE_GRANULARITY_DESCRIPTOR.  The accuracy of the estimate
depended on the latency between the PCM hw completing a period and the
driver called snd_pcm_period_elapsed() to notify ALSA core, typically
determined by interrupt handling latency.  After the change the accuracy
of the estimate depended on the latency between the PCM hw completing a
period and the application calling snd_pcm_status(), determined by the
scheduling of the application process.  The maximum error of the
estimate is one period length in both cases, but the error average and
variance is smaller when it depends on interrupt latency.

Instead of always updating tstamp, update it only if audio_tstamp
changed.

Fixes: 3179f6200188 ("ALSA: core: add .get_time_info")
Suggested-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Henrik Eriksson <henrik.eriksson@axis.com>
---
Changes since v1:
- Use Pierre-Louis Bossart's suggested fix
- Clean up commit log

 sound/core/pcm_lib.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Comments

Takashi Iwai Nov. 21, 2017, 12:59 p.m. UTC | #1
On Tue, 21 Nov 2017 09:29:28 +0100,
Henrik Eriksson wrote:
> 
> commit 3179f6200188 ("ALSA: core: add .get_time_info") had a side effect
> of changing the behaviour of the PCM runtime tstamp.  Prior to this
> change tstamp was not updated by snd_pcm_update_hw_ptr0() unless the
> hw_ptr had moved, after this change tstamp was always updated.
> 
> For an application using alsa-lib, doing snd_pcm_readi() followed by
> snd_pcm_status() to estimate the age of the read samples by subtracting
> status->avail * [sample rate] from status->tstamp this change degraded
> the accuracy of the estimate on devices where the pcm hw does not
> provide a granular hw_ptr, e.g., devices using
> soc-generic-dmaengine-pcm.c and a dma-engine with residue_granularity
> DMA_RESIDUE_GRANULARITY_DESCRIPTOR.  The accuracy of the estimate
> depended on the latency between the PCM hw completing a period and the
> driver called snd_pcm_period_elapsed() to notify ALSA core, typically
> determined by interrupt handling latency.  After the change the accuracy
> of the estimate depended on the latency between the PCM hw completing a
> period and the application calling snd_pcm_status(), determined by the
> scheduling of the application process.  The maximum error of the
> estimate is one period length in both cases, but the error average and
> variance is smaller when it depends on interrupt latency.
> 
> Instead of always updating tstamp, update it only if audio_tstamp
> changed.
> 
> Fixes: 3179f6200188 ("ALSA: core: add .get_time_info")
> Suggested-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Signed-off-by: Henrik Eriksson <henrik.eriksson@axis.com>
> ---
> Changes since v1:
> - Use Pierre-Louis Bossart's suggested fix
> - Clean up commit log

Applied, thanks.


Takashi
diff mbox

Patch

diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index a93a4235a332..10e7ef7a8804 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -248,8 +248,10 @@  static void update_audio_tstamp(struct snd_pcm_substream *substream,
 				runtime->rate);
 		*audio_tstamp = ns_to_timespec(audio_nsecs);
 	}
-	runtime->status->audio_tstamp = *audio_tstamp;
-	runtime->status->tstamp = *curr_tstamp;
+	if (!timespec_equal(&runtime->status->audio_tstamp, audio_tstamp)) {
+		runtime->status->audio_tstamp = *audio_tstamp;
+		runtime->status->tstamp = *curr_tstamp;
+	}
 
 	/*
 	 * re-take a driver timestamp to let apps detect if the reference tstamp