From 25f4751f6d0992ec4f988fd4f51f36140a28d0e2 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Tue, 26 May 2015 14:18:10 -0700 Subject: Implement timestamp reporting functions Count number of frames that have been written, reset on standby. The presentation position is the number of written frames minus the frames still in the pipe (they were written but not presented). Bug 21198864 Change-Id: I00ef10f56a825555e7a970cce1504a9bd3744e04 --- modules/audio_remote_submix/audio_hw.cpp | 57 +++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 5 deletions(-) (limited to 'modules') diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp index a13a7c3..20c0fab 100644 --- a/modules/audio_remote_submix/audio_hw.cpp +++ b/modules/audio_remote_submix/audio_hw.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -178,6 +179,7 @@ struct submix_stream_out { struct submix_audio_device *dev; int route_handle; bool output_standby; + uint64_t write_counter_frames; #if LOG_STREAMS_TO_FILES int log_fd; #endif // LOG_STREAMS_TO_FILES @@ -189,11 +191,10 @@ struct submix_stream_in { int route_handle; bool input_standby; bool output_standby_rec_thr; // output standby state as seen from record thread - // wall clock when recording starts struct timespec record_start_time; // how many frames have been requested to be read - int64_t read_counter_frames; + uint64_t read_counter_frames; #if ENABLE_LEGACY_INPUT_OPEN // Number of references to this input stream. @@ -699,6 +700,7 @@ static int out_standby(struct audio_stream *stream) pthread_mutex_lock(&rsxadev->lock); out->output_standby = true; + out->write_counter_frames = 0; pthread_mutex_unlock(&rsxadev->lock); @@ -852,6 +854,9 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, pthread_mutex_lock(&rsxadev->lock); sink.clear(); + if (written_frames > 0) { + out->write_counter_frames += written_frames; + } pthread_mutex_unlock(&rsxadev->lock); if (written_frames < 0) { @@ -863,12 +868,51 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, return written_bytes; } +static int out_get_presentation_position(const struct audio_stream_out *stream, + uint64_t *frames, struct timespec *timestamp) +{ + const submix_stream_out * out = reinterpret_cast + (reinterpret_cast(stream) - + offsetof(struct submix_stream_out, stream)); + struct submix_audio_device * const rsxadev = out->dev; + int ret = 0; + + pthread_mutex_lock(&rsxadev->lock); + + if (frames) { + const ssize_t frames_in_pipe = + rsxadev->routes[out->route_handle].rsxSource->availableToRead(); + if (CC_UNLIKELY(frames_in_pipe < 0)) { + *frames = out->write_counter_frames; + } else { + *frames = out->write_counter_frames > (uint64_t) frames_in_pipe ? + out->write_counter_frames - frames_in_pipe : 0; + } + } + if (timestamp) { + clock_gettime(CLOCK_MONOTONIC, timestamp); + } + + pthread_mutex_unlock(&rsxadev->lock); + + SUBMIX_ALOGV("out_get_presentation_position() got frames=%llu timestamp sec=%llu", + frames ? *frames : -1, timestamp ? timestamp->tv_sec : -1); + + return ret; +} + static int out_get_render_position(const struct audio_stream_out *stream, uint32_t *dsp_frames) { - (void)stream; - (void)dsp_frames; - return -EINVAL; + if (!dsp_frames) { + return -EINVAL; + } + uint64_t frames = 0; + int ret = out_get_presentation_position(stream, &frames, NULL); + if ((ret == 0) && dsp_frames) { + *dsp_frames = (uint32_t) frames; + } + return ret; } static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) @@ -1335,6 +1379,9 @@ 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->write_counter_frames = 0; #if ENABLE_RESAMPLING // Recreate the pipe with the correct sample rate so that MonoPipe.write() rate limits -- cgit v1.1