Loading system/audio_a2dp_hw/audio_a2dp_hw.c +42 −5 Original line number Diff line number Diff line Loading @@ -107,6 +107,8 @@ struct a2dp_stream_common { struct a2dp_stream_out { struct audio_stream_out stream; struct a2dp_stream_common common; uint64_t frames_presented; // frames written, never reset uint64_t frames_rendered; // frames written, reset on standby }; struct a2dp_stream_in { Loading Loading @@ -591,14 +593,17 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, pthread_mutex_unlock(&out->common.lock); 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; if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED) out->common.state = AUDIO_A2DP_STATE_STOPPED; else ERROR("write failed : stream suspended, avoid resetting state"); } else { const size_t frames = bytes / audio_stream_out_frame_size(stream); out->frames_rendered += frames; out->frames_presented += frames; } DEBUG("wrote %d bytes out of %zu bytes", sent, bytes); Loading Loading @@ -676,6 +681,7 @@ static int out_standby(struct audio_stream *stream) // Do nothing in SUSPENDED state. if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED) retVal = suspend_audio_datapath(&out->common, true); out->frames_rendered = 0; // rendered is reset, presented is not pthread_mutex_unlock (&out->common.lock); return retVal; Loading Loading @@ -786,16 +792,45 @@ 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; int ret = -EWOULDBLOCK; pthread_mutex_lock(&out->common.lock); uint64_t latency_frames = (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000; if (out->frames_presented >= latency_frames) { *frames = out->frames_presented - latency_frames; clock_gettime(CLOCK_MONOTONIC, timestamp); // could also be associated with out_write(). ret = 0; } pthread_mutex_unlock(&out->common.lock); return ret; } 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; FNLOG(); if (stream == NULL || dsp_frames == NULL) return -EINVAL; pthread_mutex_lock(&out->common.lock); uint64_t latency_frames = (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000; if (out->frames_rendered >= latency_frames) { *dsp_frames = (uint32_t)(out->frames_rendered - latency_frames); } else { *dsp_frames = 0; } pthread_mutex_unlock(&out->common.lock); return 0; } static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) Loading Loading @@ -1048,6 +1083,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); Loading Loading
system/audio_a2dp_hw/audio_a2dp_hw.c +42 −5 Original line number Diff line number Diff line Loading @@ -107,6 +107,8 @@ struct a2dp_stream_common { struct a2dp_stream_out { struct audio_stream_out stream; struct a2dp_stream_common common; uint64_t frames_presented; // frames written, never reset uint64_t frames_rendered; // frames written, reset on standby }; struct a2dp_stream_in { Loading Loading @@ -591,14 +593,17 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, pthread_mutex_unlock(&out->common.lock); 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; if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED) out->common.state = AUDIO_A2DP_STATE_STOPPED; else ERROR("write failed : stream suspended, avoid resetting state"); } else { const size_t frames = bytes / audio_stream_out_frame_size(stream); out->frames_rendered += frames; out->frames_presented += frames; } DEBUG("wrote %d bytes out of %zu bytes", sent, bytes); Loading Loading @@ -676,6 +681,7 @@ static int out_standby(struct audio_stream *stream) // Do nothing in SUSPENDED state. if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED) retVal = suspend_audio_datapath(&out->common, true); out->frames_rendered = 0; // rendered is reset, presented is not pthread_mutex_unlock (&out->common.lock); return retVal; Loading Loading @@ -786,16 +792,45 @@ 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; int ret = -EWOULDBLOCK; pthread_mutex_lock(&out->common.lock); uint64_t latency_frames = (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000; if (out->frames_presented >= latency_frames) { *frames = out->frames_presented - latency_frames; clock_gettime(CLOCK_MONOTONIC, timestamp); // could also be associated with out_write(). ret = 0; } pthread_mutex_unlock(&out->common.lock); return ret; } 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; FNLOG(); if (stream == NULL || dsp_frames == NULL) return -EINVAL; pthread_mutex_lock(&out->common.lock); uint64_t latency_frames = (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000; if (out->frames_rendered >= latency_frames) { *dsp_frames = (uint32_t)(out->frames_rendered - latency_frames); } else { *dsp_frames = 0; } pthread_mutex_unlock(&out->common.lock); return 0; } static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) Loading Loading @@ -1048,6 +1083,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); Loading