audio: Output latency update in Audio Track
AudioTrack needs to query latency from the output descriptor each
time it uses mAfLatency to calculate timestamp or return the track
latency. Until now, the output descriptor latency was queried and
stored when a track is created. On a device switch, IO descriptors
table saved in AudioSystem is updated to reflected the latest
latency values. Unless a device switch lead to a track teardown,
AudioTrack will be unaware of the latest latency value. Therefore
explicitly check the latest mAfLatency value on each getTimeStamp
call.
Test: Podkicker 2.2x, Photos 240fps and BT
Bug: 35075600
authored-by: Aniket Kumar Lata <alata@codeaurora.org>
Change-Id: I06282182364703574a7d66d2b5cd1301679dfade
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 6f5f7cb..ca6b34c 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -1245,9 +1245,27 @@
return mStreamType;
}
+uint32_t AudioTrack::latency()
+{
+ AutoMutex lock(mLock);
+ updateLatency_l();
+ return mLatency;
+}
+
// -------------------------------------------------------------------------
// must be called with mLock held
+void AudioTrack::updateLatency_l()
+{
+ status_t status = AudioSystem::getLatency(mOutput, &mAfLatency);
+ if (status != NO_ERROR) {
+ ALOGW("getLatency(%d) failed status %d", mOutput, status);
+ } else {
+ // FIXME don't believe this lie
+ mLatency = mAfLatency + (1000 * mFrameCount) / mSampleRate;
+ }
+}
+
status_t AudioTrack::createTrack_l()
{
const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
@@ -1542,9 +1560,7 @@
}
mAudioTrack->attachAuxEffect(mAuxEffectId);
- // FIXME doesn't take into account speed or future sample rate changes (until restoreTrack)
- // FIXME don't believe this lie
- mLatency = mAfLatency + (1000*frameCount) / mSampleRate;
+ updateLatency_l(); // this refetches mAfLatency and sets mLatency
mFrameCount = frameCount;
// If IAudioTrack is re-created, don't let the requested frameCount
@@ -2316,8 +2332,9 @@
return mPosition;
}
-bool AudioTrack::isSampleRateSpeedAllowed_l(uint32_t sampleRate, float speed) const
+bool AudioTrack::isSampleRateSpeedAllowed_l(uint32_t sampleRate, float speed)
{
+ updateLatency_l();
// applicable for mixing tracks only (not offloaded or direct)
if (mStaticProxy != 0) {
return true; // static tracks do not have issues with buffer sizing.
@@ -2325,9 +2342,14 @@
const size_t minFrameCount =
calculateMinFrameCount(mAfLatency, mAfFrameCount, mAfSampleRate, sampleRate, speed
/*, 0 mNotificationsPerBufferReq*/);
- ALOGV("isSampleRateSpeedAllowed_l mFrameCount %zu minFrameCount %zu",
+ const bool allowed = mFrameCount >= minFrameCount;
+ ALOGD_IF(!allowed,
+ "isSampleRateSpeedAllowed_l denied "
+ "mAfLatency:%u mAfFrameCount:%zu mAfSampleRate:%u sampleRate:%u speed:%f "
+ "mFrameCount:%zu < minFrameCount:%zu",
+ mAfLatency, mAfFrameCount, mAfSampleRate, sampleRate, speed,
mFrameCount, minFrameCount);
- return mFrameCount >= minFrameCount;
+ return allowed;
}
status_t AudioTrack::setParameters(const String8& keyValuePairs)
@@ -2471,6 +2493,7 @@
status = ets.getBestTimestamp(×tamp, &location);
if (status == OK) {
+ updateLatency_l();
// It is possible that the best location has moved from the kernel to the server.
// In this case we adjust the position from the previous computed latency.
if (location == ExtendedTimestamp::LOCATION_SERVER) {