summaryrefslogtreecommitdiffstats
path: root/services/audioflinger
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2011-12-05 09:47:19 -0800
committerEric Laurent <elaurent@google.com>2011-12-05 10:40:18 -0800
commit4433169a64eddb8598735bd950491ed35ad9c5f8 (patch)
tree0af1c5609ff4233ecfad3820200aac096b2ffeeb /services/audioflinger
parente35581ad5ad635f9dcfe4ab6a432c48b46b782cd (diff)
downloadframeworks_base-4433169a64eddb8598735bd950491ed35ad9c5f8.zip
frameworks_base-4433169a64eddb8598735bd950491ed35ad9c5f8.tar.gz
frameworks_base-4433169a64eddb8598735bd950491ed35ad9c5f8.tar.bz2
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
Diffstat (limited to 'services/audioflinger')
-rw-r--r--services/audioflinger/AudioFlinger.cpp19
-rw-r--r--services/audioflinger/AudioFlinger.h3
2 files changed, 14 insertions, 8 deletions
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>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
@@ -2422,11 +2434,6 @@ status_t AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>
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<Track> > *tracksToRemove);
virtual int getTrackName_l();
virtual void deleteTrackName_l(int name);
- virtual uint32_t activeSleepTimeUs();
virtual uint32_t idleSleepTimeUs();
virtual uint32_t suspendSleepTimeUs();