From patchwork Mon Dec 8 22:23:45 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre-Louis Bossart X-Patchwork-Id: 5459381 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 5CCD1BEEA8 for ; Mon, 8 Dec 2014 22:28:03 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 63A7120155 for ; Mon, 8 Dec 2014 22:28:02 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id C03E62011D for ; Mon, 8 Dec 2014 22:28:00 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id D28F62651ED; Mon, 8 Dec 2014 23:27:59 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,NO_DNS_FOR_FROM, UNPARSEABLE_RELAY autolearn=no version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id 642F22605BA; Mon, 8 Dec 2014 23:25:12 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id DD33D261629; Mon, 8 Dec 2014 23:25:10 +0100 (CET) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by alsa0.perex.cz (Postfix) with ESMTP id CC16F2605BD for ; Mon, 8 Dec 2014 23:24:42 +0100 (CET) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga101.jf.intel.com with ESMTP; 08 Dec 2014 14:24:41 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.04,691,1406617200"; d="scan'208";a="495693419" Received: from kzhu-mobl2.ccr.corp.intel.com (HELO pbossart-mobl1.amr.corp.intel.com) ([10.254.79.156]) by orsmga003.jf.intel.com with ESMTP; 08 Dec 2014 14:21:01 -0800 From: Pierre-Louis Bossart To: alsa-devel@alsa-project.org Date: Mon, 8 Dec 2014 16:23:45 -0600 Message-Id: <1418077426-8309-9-git-send-email-pierre-louis.bossart@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1418077426-8309-1-git-send-email-pierre-louis.bossart@linux.intel.com> References: <1418077426-8309-1-git-send-email-pierre-louis.bossart@linux.intel.com> Cc: Pierre-Louis Bossart Subject: [alsa-devel] [PATCH RFC 8/9] ALSA: core: replace .wall_clock by .get_time_info X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Introduce more generic .get_time_info to retrieve system timestamp and audio timestamp in single routine. Signed-off-by: Pierre-Louis Bossart --- include/sound/pcm.h | 6 ++-- sound/core/pcm_lib.c | 81 +++++++++++++++++++++++++++++++------------------ sound/core/pcm_native.c | 7 +++++ 3 files changed, 63 insertions(+), 31 deletions(-) diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 2bd7914..b490363 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 ec9e786..6c61e6c 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -232,6 +232,42 @@ 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; + + if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) { + runtime->status->tstamp = *curr_tstamp; + + 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; + } +} + static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, unsigned int in_interrupt) { @@ -256,11 +292,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 +446,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 +471,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 7dcd6bd..f079be8 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -706,6 +706,10 @@ 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); memset(status, 0, sizeof(*status)); status->state = runtime->status->state; status->suspended_state = runtime->status->suspended_state; @@ -718,6 +722,9 @@ int snd_pcm_status(struct snd_pcm_substream *substream, status->tstamp = runtime->status->tstamp; status->audio_tstamp = runtime->status->audio_tstamp; + snd_pcm_pack_audio_tstamp_report(&status->audio_tstamp_data, + &runtime->audio_tstamp_report); + goto _tstamp_end; } } else {