diff options
| author | Glenn Kasten <gkasten@google.com> | 2013-09-29 13:54:28 -0700 |
|---|---|---|
| committer | Glenn Kasten <gkasten@google.com> | 2013-09-29 13:54:28 -0700 |
| commit | c5e2864b3d3228ec18cf2da006c67029024f1fcb (patch) | |
| tree | 7b4ca9ab132e9ebfd7ec7934d81f27db671664a4 /audio | |
| parent | f2acf5f2fa363791f05c4c6d53a75b33e9f1d230 (diff) | |
Implement HAL API get_presentation_position
Bug: 9587132
Change-Id: Ic227628c707d08e283bcee91af37a85181d94a7c
Diffstat (limited to 'audio')
| -rw-r--r-- | audio/audio_hw.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/audio/audio_hw.c b/audio/audio_hw.c index 1ddea03..bcec532 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -117,6 +117,7 @@ struct stream_out { struct pcm *pcm; struct pcm_config *pcm_config; bool standby; + uint64_t written; /* total frames written, not cleared when entering standby */ struct resampler_itfe *resampler; int16_t *buffer; @@ -290,7 +291,7 @@ static int start_output_stream(struct stream_out *out) pthread_mutex_unlock(&in->lock); } - out->pcm = pcm_open(PCM_CARD, device, PCM_OUT | PCM_NORESTART, out->pcm_config); + out->pcm = pcm_open(PCM_CARD, device, PCM_OUT | PCM_NORESTART | PCM_MONOTONIC, out->pcm_config); if (out->pcm && !pcm_is_ready(out->pcm)) { ALOGE("pcm_open(out) failed: %s", pcm_get_error(out->pcm)); @@ -747,6 +748,9 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, pthread_mutex_unlock(&out->lock); return ret; } + if (ret == 0) { + out->written += out_frames; + } exit: pthread_mutex_unlock(&out->lock); @@ -781,6 +785,31 @@ static int out_get_next_write_timestamp(const struct audio_stream_out *stream, return -EINVAL; } +static int out_get_presentation_position(const struct audio_stream_out *stream, + uint64_t *frames, struct timespec *timestamp) +{ + struct stream_out *out = (struct stream_out *)stream; + int ret = -1; + + pthread_mutex_lock(&out->lock); + + size_t avail; + if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) { + size_t kernel_buffer_size = out->pcm_config->period_size * out->pcm_config->period_count; + // FIXME This calculation is incorrect if there is buffering after app processor + int64_t signed_frames = out->written - kernel_buffer_size + avail; + // It would be unusual for this value to be negative, but check just in case ... + if (signed_frames >= 0) { + *frames = signed_frames; + ret = 0; + } + } + + pthread_mutex_unlock(&out->lock); + + return ret; +} + /** audio_stream_in implementation **/ static uint32_t in_get_sample_rate(const struct audio_stream *stream) { @@ -1009,6 +1038,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev, out->stream.write = out_write; out->stream.get_render_position = out_get_render_position; out->stream.get_next_write_timestamp = out_get_next_write_timestamp; + out->stream.get_presentation_position = out_get_presentation_position; out->dev = adev; @@ -1017,6 +1047,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev, config->sample_rate = out_get_sample_rate(&out->stream.common); out->standby = true; + /* out->written = 0; by calloc() */ *stream_out = &out->stream; return 0; |
