[alsa-devel] [PATCH v5 08/10] ALSA: core: replace .wall_clock by .get_time_info
Takashi Iwai
tiwai at suse.de
Mon Feb 9 16:19:35 CET 2015
At Fri, 6 Feb 2015 15:55:57 -0600,
Pierre-Louis Bossart wrote:
>
> Introduce more generic .get_time_info to retrieve
> system timestamp and audio timestamp in single routine.
> The .wall_clock method is removed but the same functionality is
> preserved for backwards legacy.
>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
If we remove wall_clock ops here, fold the corresponding HD-audio
change into the same patch. Otherwise you'll get the build error at
this commit, thus it'll break the git bisection.
Or, leave wall_clock ops here as a place holder, and remove it after
fixing the consumer as another patch.
thanks,
Takashi
> ---
> include/sound/pcm.h | 6 ++--
> sound/core/pcm_lib.c | 88 +++++++++++++++++++++++++++++++++----------------
> sound/core/pcm_native.c | 24 ++++++++++++++
> 3 files changed, 87 insertions(+), 31 deletions(-)
>
> diff --git a/include/sound/pcm.h b/include/sound/pcm.h
> index 05ad56a..15484e4 100644
> --- a/include/sound/pcm.h
> +++ b/include/sound/pcm.h
> @@ -74,8 +74,10 @@ struct snd_pcm_ops {
> int (*prepare)(struct snd_pcm_substream *substream);
> int (*trigger)(struct snd_pcm_substream *substream, int cmd);
> snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *substream);
> - int (*wall_clock)(struct snd_pcm_substream *substream,
> - struct timespec *audio_ts);
> + int (*get_time_info)(struct snd_pcm_substream *substream,
> + struct timespec *system_ts, struct timespec *audio_ts,
> + struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
> + struct snd_pcm_audio_tstamp_report *audio_tstamp_report);
> int (*copy)(struct snd_pcm_substream *substream, int channel,
> snd_pcm_uframes_t pos,
> void __user *buf, snd_pcm_uframes_t count);
> diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
> index db05e04..9fbb0db 100644
> --- a/sound/core/pcm_lib.c
> +++ b/sound/core/pcm_lib.c
> @@ -232,6 +232,49 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream,
> return 0;
> }
>
> +static void update_audio_tstamp(struct snd_pcm_substream *substream,
> + struct timespec *curr_tstamp,
> + struct timespec *audio_tstamp)
> +{
> + struct snd_pcm_runtime *runtime = substream->runtime;
> + u64 audio_frames, audio_nsecs;
> + struct timespec driver_tstamp;
> +
> + if (runtime->tstamp_mode != SNDRV_PCM_TSTAMP_ENABLE)
> + return;
> +
> + if (!(substream->ops->get_time_info) ||
> + (runtime->audio_tstamp_report.actual_type ==
> + SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT)) {
> +
> + /*
> + * provide audio timestamp derived from pointer position
> + * add delay only if requested
> + */
> +
> + audio_frames = runtime->hw_ptr_wrap + runtime->status->hw_ptr;
> +
> + if (runtime->audio_tstamp_config.report_delay) {
> + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
> + audio_frames -= runtime->delay;
> + else
> + audio_frames += runtime->delay;
> + }
> + audio_nsecs = div_u64(audio_frames * 1000000000LL,
> + runtime->rate);
> + *audio_tstamp = ns_to_timespec(audio_nsecs);
> + }
> + runtime->status->audio_tstamp = *audio_tstamp;
> + runtime->status->tstamp = *curr_tstamp;
> +
> + /*
> + * re-take a driver timestamp to let apps detect if the reference tstamp
> + * read by low-level hardware was provided with a delay
> + */
> + snd_pcm_gettime(substream->runtime, (struct timespec *)&driver_tstamp);
> + runtime->driver_tstamp = driver_tstamp;
> +}
> +
> static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
> unsigned int in_interrupt)
> {
> @@ -256,11 +299,18 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
> pos = substream->ops->pointer(substream);
> curr_jiffies = jiffies;
> if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
> - snd_pcm_gettime(runtime, (struct timespec *)&curr_tstamp);
> -
> - if ((runtime->hw.info & SNDRV_PCM_INFO_HAS_WALL_CLOCK) &&
> - (substream->ops->wall_clock))
> - substream->ops->wall_clock(substream, &audio_tstamp);
> + if ((substream->ops->get_time_info) &&
> + (runtime->audio_tstamp_config.type_requested != SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT)) {
> + substream->ops->get_time_info(substream, &curr_tstamp,
> + &audio_tstamp,
> + &runtime->audio_tstamp_config,
> + &runtime->audio_tstamp_report);
> +
> + /* re-test in case tstamp type is not supported in hardware and was demoted to DEFAULT */
> + if (runtime->audio_tstamp_report.actual_type == SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT)
> + snd_pcm_gettime(runtime, (struct timespec *)&curr_tstamp);
> + } else
> + snd_pcm_gettime(runtime, (struct timespec *)&curr_tstamp);
> }
>
> if (pos == SNDRV_PCM_POS_XRUN) {
> @@ -403,8 +453,10 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
> }
>
> no_delta_check:
> - if (runtime->status->hw_ptr == new_hw_ptr)
> + if (runtime->status->hw_ptr == new_hw_ptr) {
> + update_audio_tstamp(substream, &curr_tstamp, &audio_tstamp);
> return 0;
> + }
>
> if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
> runtime->silence_size > 0)
> @@ -426,30 +478,8 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
> snd_BUG_ON(crossed_boundary != 1);
> runtime->hw_ptr_wrap += runtime->boundary;
> }
> - if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
> - runtime->status->tstamp = curr_tstamp;
>
> - if (!(runtime->hw.info & SNDRV_PCM_INFO_HAS_WALL_CLOCK)) {
> - /*
> - * no wall clock available, provide audio timestamp
> - * derived from pointer position+delay
> - */
> - u64 audio_frames, audio_nsecs;
> -
> - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
> - audio_frames = runtime->hw_ptr_wrap
> - + runtime->status->hw_ptr
> - - runtime->delay;
> - else
> - audio_frames = runtime->hw_ptr_wrap
> - + runtime->status->hw_ptr
> - + runtime->delay;
> - audio_nsecs = div_u64(audio_frames * 1000000000LL,
> - runtime->rate);
> - audio_tstamp = ns_to_timespec(audio_nsecs);
> - }
> - runtime->status->audio_tstamp = audio_tstamp;
> - }
> + update_audio_tstamp(substream, &curr_tstamp, &audio_tstamp);
>
> return snd_pcm_update_state(substream, runtime);
> }
> diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
> index 40d2943..41c29c1 100644
> --- a/sound/core/pcm_native.c
> +++ b/sound/core/pcm_native.c
> @@ -707,6 +707,23 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
> struct snd_pcm_runtime *runtime = substream->runtime;
>
> snd_pcm_stream_lock_irq(substream);
> +
> + snd_pcm_unpack_audio_tstamp_config(status->audio_tstamp_data,
> + &runtime->audio_tstamp_config);
> +
> + /* backwards compatible behavior */
> + if (runtime->audio_tstamp_config.type_requested ==
> + SNDRV_PCM_AUDIO_TSTAMP_TYPE_COMPAT) {
> + if (runtime->hw.info & SNDRV_PCM_INFO_HAS_WALL_CLOCK)
> + runtime->audio_tstamp_config.type_requested =
> + SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK;
> + else
> + runtime->audio_tstamp_config.type_requested =
> + SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT;
> + runtime->audio_tstamp_report.valid = 0;
> + } else
> + runtime->audio_tstamp_report.valid = 1;
> +
> status->state = runtime->status->state;
> status->suspended_state = runtime->status->suspended_state;
> if (status->state == SNDRV_PCM_STATE_OPEN)
> @@ -716,8 +733,15 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
> snd_pcm_update_hw_ptr(substream);
> if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
> status->tstamp = runtime->status->tstamp;
> + status->driver_tstamp = runtime->driver_tstamp;
> status->audio_tstamp =
> runtime->status->audio_tstamp;
> + if (runtime->audio_tstamp_report.valid == 1)
> + /* backwards compatibility, no report provided in COMPAT mode */
> + snd_pcm_pack_audio_tstamp_report(&status->audio_tstamp_data,
> + &status->audio_tstamp_accuracy,
> + &runtime->audio_tstamp_report);
> +
> goto _tstamp_end;
> }
> } else {
> --
> 1.9.1
>
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>
More information about the Alsa-devel
mailing list