Offset direct/offload timestamps by downstream latency

Test: A/V sync of direct/offload DD+ non HW A/V sync playback thread
      through MSD, and MSD -> Audio HAL patch in DD+ non HW A/V sync
      mode.
Change-Id: I244e9fda9741fe9a9ea913f39901654ebefb973c
(cherry picked from commit 8729c2eb3eabda3f6b6985a113bd2022b5b379c9)
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 5555acf..f833cf7 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3185,7 +3185,6 @@
     if (mType == OFFLOAD || mType == DIRECT) {
         mTimestampVerifier.setDiscontinuityMode(mTimestampVerifier.DISCONTINUITY_MODE_ZERO);
     }
-    audio_utils::Statistics<double> downstreamLatencyStatMs(0.999 /* alpha */);
     audio_patch_handle_t lastDownstreamPatchHandle = AUDIO_PATCH_HANDLE_NONE;
 
     while (!exitPending())
@@ -3215,7 +3214,7 @@
                         downstreamPatchHandle = swPatches[0].getPatchHandle();
                 }
                 if (downstreamPatchHandle != lastDownstreamPatchHandle) {
-                    downstreamLatencyStatMs.reset();
+                    mDownstreamLatencyStatMs.reset();
                     lastDownstreamPatchHandle = downstreamPatchHandle;
                 }
                 if (status == OK) {
@@ -3229,14 +3228,14 @@
                         if (latencyMs < minLatency) latencyMs = minLatency;
                         else if (latencyMs > maxLatency) latencyMs = maxLatency;
                     }
-                    downstreamLatencyStatMs.add(latencyMs);
+                    mDownstreamLatencyStatMs.add(latencyMs);
                 }
                 mAudioFlinger->mLock.unlock();
             }
         } else {
             if (lastDownstreamPatchHandle != AUDIO_PATCH_HANDLE_NONE) {
                 // our device is no longer AUDIO_DEVICE_OUT_BUS, reset patch handle and stats.
-                downstreamLatencyStatMs.reset();
+                mDownstreamLatencyStatMs.reset();
                 lastDownstreamPatchHandle = AUDIO_PATCH_HANDLE_NONE;
             }
         }
@@ -3285,10 +3284,10 @@
                             (long long)timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]);
 
                     // 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 =
                                 timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]
-                                - int64_t(downstreamLatencyStatMs.getMean() * mSampleRate * 1e-3);
+                                - int64_t(mDownstreamLatencyStatMs.getMean() * mSampleRate * 1e-3);
                         // prevent retrograde
                         timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = max(
                                 newPosition,
@@ -3747,6 +3746,15 @@
         uint64_t position64;
         if (mOutput->getPresentationPosition(&position64, &timestamp.mTime) == OK) {
             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;
         }
     }
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 61f7baf..49fc234 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1082,6 +1082,8 @@
     static const size_t     kFastMixerLogSize = 8 * 1024;
     sp<NBLog::Writer>       mFastMixerNBLogWriter;
 
+    // Downstream patch latency, available if mDownstreamLatencyStatMs.getN() > 0.
+    audio_utils::Statistics<double> mDownstreamLatencyStatMs{0.999};
 
 public:
     virtual     bool        hasFastMixer() const = 0;