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@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, int (*copy)(struct snd_pcm_substream *substream, int channel, snd_pcm_uframes_t pos, void __user *buf, snd_pcm_uframes_t count);struct snd_pcm_audio_tstamp_report *audio_tstamp_report);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;elseaudio_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);} elsesnd_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;elseaudio_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;elseruntime->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); } } else {goto _tstamp_end;-- 1.9.1
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel