summaryrefslogtreecommitdiffstats
path: root/audio_a2dp_hw
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2015-05-26 15:50:29 -0700
committerEric Laurent <elaurent@google.com>2015-05-26 16:16:36 -0700
commit0b6c835cab0391f73a453686f4e665dd02661d77 (patch)
tree6615ec18629d39a09c0dbf078b8ec6da50901e97 /audio_a2dp_hw
parent04b5e9294be52782500f0be01fd10d43bb330ce0 (diff)
downloadandroid_system_bt-0b6c835cab0391f73a453686f4e665dd02661d77.tar.gz
android_system_bt-0b6c835cab0391f73a453686f4e665dd02661d77.tar.bz2
android_system_bt-0b6c835cab0391f73a453686f4e665dd02661d77.zip
A2DP audio HAL: implement get_presentation_position()
Bug: 21199150. Change-Id: If8e95645b636be82a32420cad1ca6a3993e14f1c
Diffstat (limited to 'audio_a2dp_hw')
-rw-r--r--audio_a2dp_hw/audio_a2dp_hw.c43
1 files changed, 38 insertions, 5 deletions
diff --git a/audio_a2dp_hw/audio_a2dp_hw.c b/audio_a2dp_hw/audio_a2dp_hw.c
index 0d621165a..2aa7f43ea 100644
--- a/audio_a2dp_hw/audio_a2dp_hw.c
+++ b/audio_a2dp_hw/audio_a2dp_hw.c
@@ -107,6 +107,7 @@ struct a2dp_stream_common {
struct a2dp_stream_out {
struct audio_stream_out stream;
struct a2dp_stream_common common;
+ uint64_t frames_written;
};
struct a2dp_stream_in {
@@ -583,11 +584,12 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
sent = skt_write(out->common.audio_fd, buffer, bytes);
- if (sent == -1)
- {
+ if (sent == -1) {
skt_disconnect(out->common.audio_fd);
out->common.audio_fd = AUDIO_SKT_DISCONNECTED;
out->common.state = AUDIO_A2DP_STATE_STOPPED;
+ } else {
+ out->frames_written += (uint64_t)bytes / audio_stream_out_frame_size(stream);
}
DEBUG("wrote %d bytes out of %zu bytes", sent, bytes);
@@ -667,6 +669,7 @@ static int out_standby(struct audio_stream *stream)
retVal = suspend_audio_datapath(&out->common, true);
else
retVal = 0;
+ out->frames_written = 0;
pthread_mutex_unlock(&out->common.lock);
return retVal;
@@ -776,16 +779,44 @@ static int out_set_volume(struct audio_stream_out *stream, float left,
return -ENOSYS;
}
+static int out_get_presentation_position(const struct audio_stream_out *stream,
+ uint64_t *frames, struct timespec *timestamp)
+{
+ struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+
+ FNLOG();
+ if (stream == NULL || frames == NULL || timestamp == NULL)
+ return -EINVAL;
+
+ *frames = 0;
+ pthread_mutex_lock(&out->common.lock);
+ uint64_t latency_frames = ((uint64_t)out_get_latency(stream) * out->common.cfg.rate) / 1000;
+ if (out->frames_written >= latency_frames) {
+ *frames = out->frames_written - latency_frames;
+ }
+ clock_gettime(CLOCK_MONOTONIC, timestamp);
+ pthread_mutex_unlock(&out->common.lock);
+ return 0;
+}
static int out_get_render_position(const struct audio_stream_out *stream,
uint32_t *dsp_frames)
{
- UNUSED(stream);
- UNUSED(dsp_frames);
+ struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+ struct timespec timestamp;
+ uint64_t frames;
+ int ret;
FNLOG();
- return -EINVAL;
+
+ if (stream == NULL || dsp_frames == NULL)
+ return -EINVAL;
+ *dsp_frames = 0;
+ ret = out_get_presentation_position(stream, &frames, &timestamp);
+ if (ret == 0)
+ *dsp_frames = (uint32_t)frames;
+ return ret;
}
static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
@@ -1038,6 +1069,8 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
out->stream.set_volume = out_set_volume;
out->stream.write = out_write;
out->stream.get_render_position = out_get_render_position;
+ out->stream.get_presentation_position = out_get_presentation_position;
+
/* initialize a2dp specifics */
a2dp_stream_common_init(&out->common);