From 4433169a64eddb8598735bd950491ed35ad9c5f8 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Mon, 5 Dec 2011 09:47:19 -0800 Subject: audioflinger: fix audio skipping over A2DP The maximum sleep time allowed in the mixer thread when audio tracks are enabled but not ready for mixing is derived from the latency reported by the output stream. This does not work for A2DP where the latency also reflects encoding, decoding and transfer time. Modified activeSleepTimeUs() to take A2DP case into account. Issue 5682206. Change-Id: I3784ac01fb6f836b5a6ce6f764fb15347586de35 --- services/audioflinger/AudioFlinger.cpp | 19 +++++++++++++------ services/audioflinger/AudioFlinger.h | 3 +-- 2 files changed, 14 insertions(+), 8 deletions(-) (limited to 'services') diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index aea31a8..e9ac3f9 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1816,6 +1816,18 @@ audio_stream_t* AudioFlinger::PlaybackThread::stream() return &mOutput->stream->common; } +uint32_t AudioFlinger::PlaybackThread::activeSleepTimeUs() +{ + // A2DP output latency is not due only to buffering capacity. It also reflects encoding, + // decoding and transfer time. So sleeping for half of the latency would likely cause + // underruns + if (audio_is_a2dp_device((audio_devices_t)mDevice)) { + return (uint32_t)((uint32_t)((mFrameCount * 1000) / mSampleRate) * 1000); + } else { + return (uint32_t)(mOutput->stream->get_latency(mOutput->stream) * 1000) / 2; + } +} + // ---------------------------------------------------------------------------- AudioFlinger::MixerThread::MixerThread(const sp& audioFlinger, AudioStreamOut* output, int id, uint32_t device) @@ -2422,11 +2434,6 @@ status_t AudioFlinger::MixerThread::dumpInternals(int fd, const Vector return NO_ERROR; } -uint32_t AudioFlinger::MixerThread::activeSleepTimeUs() -{ - return (uint32_t)(mOutput->stream->get_latency(mOutput->stream) * 1000) / 2; -} - uint32_t AudioFlinger::MixerThread::idleSleepTimeUs() { return (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000) / 2; @@ -2893,7 +2900,7 @@ uint32_t AudioFlinger::DirectOutputThread::activeSleepTimeUs() { uint32_t time; if (audio_is_linear_pcm(mFormat)) { - time = (uint32_t)(mOutput->stream->get_latency(mOutput->stream) * 1000) / 2; + time = PlaybackThread::activeSleepTimeUs(); } else { time = 10000; } diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 897bc78..6cafa7e 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -776,7 +776,7 @@ private: virtual int getTrackName_l() = 0; virtual void deleteTrackName_l(int name) = 0; - virtual uint32_t activeSleepTimeUs() = 0; + virtual uint32_t activeSleepTimeUs(); virtual uint32_t idleSleepTimeUs() = 0; virtual uint32_t suspendSleepTimeUs() = 0; @@ -833,7 +833,6 @@ private: Vector< sp > *tracksToRemove); virtual int getTrackName_l(); virtual void deleteTrackName_l(int name); - virtual uint32_t activeSleepTimeUs(); virtual uint32_t idleSleepTimeUs(); virtual uint32_t suspendSleepTimeUs(); -- cgit v1.1