Loading services/audioflinger/Threads.cpp +14 −6 Original line number Original line Diff line number Diff line Loading @@ -3185,7 +3185,6 @@ bool AudioFlinger::PlaybackThread::threadLoop() if (mType == OFFLOAD || mType == DIRECT) { if (mType == OFFLOAD || mType == DIRECT) { mTimestampVerifier.setDiscontinuityMode(mTimestampVerifier.DISCONTINUITY_MODE_ZERO); mTimestampVerifier.setDiscontinuityMode(mTimestampVerifier.DISCONTINUITY_MODE_ZERO); } } audio_utils::Statistics<double> downstreamLatencyStatMs(0.999 /* alpha */); audio_patch_handle_t lastDownstreamPatchHandle = AUDIO_PATCH_HANDLE_NONE; audio_patch_handle_t lastDownstreamPatchHandle = AUDIO_PATCH_HANDLE_NONE; while (!exitPending()) while (!exitPending()) Loading Loading @@ -3215,7 +3214,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() downstreamPatchHandle = swPatches[0].getPatchHandle(); downstreamPatchHandle = swPatches[0].getPatchHandle(); } } if (downstreamPatchHandle != lastDownstreamPatchHandle) { if (downstreamPatchHandle != lastDownstreamPatchHandle) { downstreamLatencyStatMs.reset(); mDownstreamLatencyStatMs.reset(); lastDownstreamPatchHandle = downstreamPatchHandle; lastDownstreamPatchHandle = downstreamPatchHandle; } } if (status == OK) { if (status == OK) { Loading @@ -3229,14 +3228,14 @@ bool AudioFlinger::PlaybackThread::threadLoop() if (latencyMs < minLatency) latencyMs = minLatency; if (latencyMs < minLatency) latencyMs = minLatency; else if (latencyMs > maxLatency) latencyMs = maxLatency; else if (latencyMs > maxLatency) latencyMs = maxLatency; } } downstreamLatencyStatMs.add(latencyMs); mDownstreamLatencyStatMs.add(latencyMs); } } mAudioFlinger->mLock.unlock(); mAudioFlinger->mLock.unlock(); } } } else { } else { if (lastDownstreamPatchHandle != AUDIO_PATCH_HANDLE_NONE) { if (lastDownstreamPatchHandle != AUDIO_PATCH_HANDLE_NONE) { // our device is no longer AUDIO_DEVICE_OUT_BUS, reset patch handle and stats. // our device is no longer AUDIO_DEVICE_OUT_BUS, reset patch handle and stats. downstreamLatencyStatMs.reset(); mDownstreamLatencyStatMs.reset(); lastDownstreamPatchHandle = AUDIO_PATCH_HANDLE_NONE; lastDownstreamPatchHandle = AUDIO_PATCH_HANDLE_NONE; } } } } Loading Loading @@ -3285,10 +3284,10 @@ bool AudioFlinger::PlaybackThread::threadLoop() (long long)timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]); (long long)timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]); // Note: Downstream latency only added if timestamp correction enabled. // Note: Downstream latency only added if timestamp correction enabled. if (downstreamLatencyStatMs.getN() > 0) { // we have latency info. if (mDownstreamLatencyStatMs.getN() > 0) { // we have latency info. const int64_t newPosition = const int64_t newPosition = timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] - int64_t(downstreamLatencyStatMs.getMean() * mSampleRate * 1e-3); - int64_t(mDownstreamLatencyStatMs.getMean() * mSampleRate * 1e-3); // prevent retrograde // prevent retrograde timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = max( timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = max( newPosition, newPosition, Loading Loading @@ -3747,6 +3746,15 @@ status_t AudioFlinger::PlaybackThread::getTimestamp_l(AudioTimestamp& timestamp) uint64_t position64; uint64_t position64; if (mOutput->getPresentationPosition(&position64, ×tamp.mTime) == OK) { if (mOutput->getPresentationPosition(&position64, ×tamp.mTime) == OK) { timestamp.mPosition = (uint32_t)position64; timestamp.mPosition = (uint32_t)position64; if (mDownstreamLatencyStatMs.getN() > 0) { const uint32_t positionOffset = (uint32_t)(mDownstreamLatencyStatMs.getMean() * mSampleRate * 1e-3); if (positionOffset > timestamp.mPosition) { timestamp.mPosition = 0; } else { timestamp.mPosition -= positionOffset; } } return NO_ERROR; return NO_ERROR; } } } } Loading services/audioflinger/Threads.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -1082,6 +1082,8 @@ private: static const size_t kFastMixerLogSize = 8 * 1024; static const size_t kFastMixerLogSize = 8 * 1024; sp<NBLog::Writer> mFastMixerNBLogWriter; sp<NBLog::Writer> mFastMixerNBLogWriter; // Downstream patch latency, available if mDownstreamLatencyStatMs.getN() > 0. audio_utils::Statistics<double> mDownstreamLatencyStatMs{0.999}; public: public: virtual bool hasFastMixer() const = 0; virtual bool hasFastMixer() const = 0; Loading Loading
services/audioflinger/Threads.cpp +14 −6 Original line number Original line Diff line number Diff line Loading @@ -3185,7 +3185,6 @@ bool AudioFlinger::PlaybackThread::threadLoop() if (mType == OFFLOAD || mType == DIRECT) { if (mType == OFFLOAD || mType == DIRECT) { mTimestampVerifier.setDiscontinuityMode(mTimestampVerifier.DISCONTINUITY_MODE_ZERO); mTimestampVerifier.setDiscontinuityMode(mTimestampVerifier.DISCONTINUITY_MODE_ZERO); } } audio_utils::Statistics<double> downstreamLatencyStatMs(0.999 /* alpha */); audio_patch_handle_t lastDownstreamPatchHandle = AUDIO_PATCH_HANDLE_NONE; audio_patch_handle_t lastDownstreamPatchHandle = AUDIO_PATCH_HANDLE_NONE; while (!exitPending()) while (!exitPending()) Loading Loading @@ -3215,7 +3214,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() downstreamPatchHandle = swPatches[0].getPatchHandle(); downstreamPatchHandle = swPatches[0].getPatchHandle(); } } if (downstreamPatchHandle != lastDownstreamPatchHandle) { if (downstreamPatchHandle != lastDownstreamPatchHandle) { downstreamLatencyStatMs.reset(); mDownstreamLatencyStatMs.reset(); lastDownstreamPatchHandle = downstreamPatchHandle; lastDownstreamPatchHandle = downstreamPatchHandle; } } if (status == OK) { if (status == OK) { Loading @@ -3229,14 +3228,14 @@ bool AudioFlinger::PlaybackThread::threadLoop() if (latencyMs < minLatency) latencyMs = minLatency; if (latencyMs < minLatency) latencyMs = minLatency; else if (latencyMs > maxLatency) latencyMs = maxLatency; else if (latencyMs > maxLatency) latencyMs = maxLatency; } } downstreamLatencyStatMs.add(latencyMs); mDownstreamLatencyStatMs.add(latencyMs); } } mAudioFlinger->mLock.unlock(); mAudioFlinger->mLock.unlock(); } } } else { } else { if (lastDownstreamPatchHandle != AUDIO_PATCH_HANDLE_NONE) { if (lastDownstreamPatchHandle != AUDIO_PATCH_HANDLE_NONE) { // our device is no longer AUDIO_DEVICE_OUT_BUS, reset patch handle and stats. // our device is no longer AUDIO_DEVICE_OUT_BUS, reset patch handle and stats. downstreamLatencyStatMs.reset(); mDownstreamLatencyStatMs.reset(); lastDownstreamPatchHandle = AUDIO_PATCH_HANDLE_NONE; lastDownstreamPatchHandle = AUDIO_PATCH_HANDLE_NONE; } } } } Loading Loading @@ -3285,10 +3284,10 @@ bool AudioFlinger::PlaybackThread::threadLoop() (long long)timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]); (long long)timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]); // Note: Downstream latency only added if timestamp correction enabled. // Note: Downstream latency only added if timestamp correction enabled. if (downstreamLatencyStatMs.getN() > 0) { // we have latency info. if (mDownstreamLatencyStatMs.getN() > 0) { // we have latency info. const int64_t newPosition = const int64_t newPosition = timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] - int64_t(downstreamLatencyStatMs.getMean() * mSampleRate * 1e-3); - int64_t(mDownstreamLatencyStatMs.getMean() * mSampleRate * 1e-3); // prevent retrograde // prevent retrograde timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = max( timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = max( newPosition, newPosition, Loading Loading @@ -3747,6 +3746,15 @@ status_t AudioFlinger::PlaybackThread::getTimestamp_l(AudioTimestamp& timestamp) uint64_t position64; uint64_t position64; if (mOutput->getPresentationPosition(&position64, ×tamp.mTime) == OK) { if (mOutput->getPresentationPosition(&position64, ×tamp.mTime) == OK) { timestamp.mPosition = (uint32_t)position64; timestamp.mPosition = (uint32_t)position64; if (mDownstreamLatencyStatMs.getN() > 0) { const uint32_t positionOffset = (uint32_t)(mDownstreamLatencyStatMs.getMean() * mSampleRate * 1e-3); if (positionOffset > timestamp.mPosition) { timestamp.mPosition = 0; } else { timestamp.mPosition -= positionOffset; } } return NO_ERROR; return NO_ERROR; } } } } Loading
services/audioflinger/Threads.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -1082,6 +1082,8 @@ private: static const size_t kFastMixerLogSize = 8 * 1024; static const size_t kFastMixerLogSize = 8 * 1024; sp<NBLog::Writer> mFastMixerNBLogWriter; sp<NBLog::Writer> mFastMixerNBLogWriter; // Downstream patch latency, available if mDownstreamLatencyStatMs.getN() > 0. audio_utils::Statistics<double> mDownstreamLatencyStatMs{0.999}; public: public: virtual bool hasFastMixer() const = 0; virtual bool hasFastMixer() const = 0; Loading