summaryrefslogtreecommitdiff
path: root/services
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2012-05-22 18:55:44 -0700
committerEric Laurent <elaurent@google.com>2012-05-22 19:06:51 -0700
commite737cda649acbfa43fc1b74612a83f2fac9aa449 (patch)
tree01ac3aaf0b68473c7e21c3056547b87a54f89f0f /services
parent8d9846c0693b7651b243f0161caa86be506f764a (diff)
audioflinger: refine latency latency calculation.
There is an audio pipe between the normal mixer output and the fast mixer to cope for scheduling delays and buffer size difference. This pipe depth was not taken into account in latency calculation. Adding the pipe contribution to the latency significantly improves A/V sync. Bug 6520569. Change-Id: I5584908e8aa8a02170eb38b22b4370eea800a235
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp17
-rw-r--r--services/audioflinger/AudioFlinger.h3
-rw-r--r--services/audioflinger/MonoPipe.h4
3 files changed, 23 insertions, 1 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 3c60e5a3..68be7a70 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1804,11 +1804,25 @@ Exit:
return track;
}
+uint32_t AudioFlinger::MixerThread::correctLatency(uint32_t latency) const
+{
+ if (mFastMixer != NULL) {
+ MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
+ latency += (pipe->getAvgFrames() * 1000) / mSampleRate;
+ }
+ return latency;
+}
+
+uint32_t AudioFlinger::PlaybackThread::correctLatency(uint32_t latency) const
+{
+ return latency;
+}
+
uint32_t AudioFlinger::PlaybackThread::latency() const
{
Mutex::Autolock _l(mLock);
if (initCheck() == NO_ERROR) {
- return mOutput->stream->get_latency(mOutput->stream);
+ return correctLatency(mOutput->stream->get_latency(mOutput->stream));
} else {
return 0;
}
@@ -2020,6 +2034,7 @@ void AudioFlinger::PlaybackThread::readOutputParameters()
}
}
+
status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames)
{
if (halFrames == NULL || dspFrames == NULL) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 1ae54148..51cbae73 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -1048,6 +1048,8 @@ public:
// Cache various calculated values, at threadLoop() entry and after a parameter change
virtual void cacheParameters_l();
+ virtual uint32_t correctLatency(uint32_t latency) const;
+
private:
friend class AudioFlinger; // for numerous
@@ -1154,6 +1156,7 @@ public:
virtual void threadLoop_mix();
virtual void threadLoop_sleepTime();
virtual void threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove);
+ virtual uint32_t correctLatency(uint32_t latency) const;
AudioMixer* mAudioMixer; // normal mixer
private:
diff --git a/services/audioflinger/MonoPipe.h b/services/audioflinger/MonoPipe.h
index 1f56e540..545d6acf 100644
--- a/services/audioflinger/MonoPipe.h
+++ b/services/audioflinger/MonoPipe.h
@@ -56,6 +56,10 @@ public:
virtual ssize_t write(const void *buffer, size_t count);
//virtual ssize_t writeVia(writeVia_t via, size_t total, void *user, size_t block);
+ // average number of frames present in the pipe under normal conditions.
+ // See throttling mechanism in MonoPipe::write()
+ size_t getAvgFrames() const { return (mMaxFrames * 11) / 16; }
+
private:
const size_t mMaxFrames; // always a power of 2
void * const mBuffer;