Misc debugging support and handling of latency changes.

Change-Id: I682944f793690842219cf1adbae5e61e061b6b62
diff --git a/media/libstagefright/wifi-display/MediaSender.cpp b/media/libstagefright/wifi-display/MediaSender.cpp
index 6fc50f7..123bc1c 100644
--- a/media/libstagefright/wifi-display/MediaSender.cpp
+++ b/media/libstagefright/wifi-display/MediaSender.cpp
@@ -267,37 +267,6 @@
                         tsPackets,
                         33 /* packetType */,
                         RTPSender::PACKETIZATION_TRANSPORT_STREAM);
-
-#if 0
-                {
-                    int64_t nowUs = ALooper::GetNowUs();
-
-                    int64_t timeUs;
-                    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
-
-                    int64_t delayMs = (nowUs - timeUs) / 1000ll;
-
-                    static const int64_t kMinDelayMs = 0;
-                    static const int64_t kMaxDelayMs = 300;
-
-                    const char *kPattern = "########################################";
-                    size_t kPatternSize = strlen(kPattern);
-
-                    int n = (kPatternSize * (delayMs - kMinDelayMs))
-                                / (kMaxDelayMs - kMinDelayMs);
-
-                    if (n < 0) {
-                        n = 0;
-                    } else if ((size_t)n > kPatternSize) {
-                        n = kPatternSize;
-                    }
-
-                    ALOGI("[%lld]: (%4lld ms) %s\n",
-                          timeUs / 1000,
-                          delayMs,
-                          kPattern + kPatternSize - n);
-                }
-#endif
             }
 
             if (err != OK) {
diff --git a/media/libstagefright/wifi-display/sink/DirectRenderer.cpp b/media/libstagefright/wifi-display/sink/DirectRenderer.cpp
index 12338e9..15f9c88 100644
--- a/media/libstagefright/wifi-display/sink/DirectRenderer.cpp
+++ b/media/libstagefright/wifi-display/sink/DirectRenderer.cpp
@@ -467,8 +467,6 @@
         const sp<IGraphicBufferProducer> &bufferProducer)
     : mSurfaceTex(bufferProducer),
       mVideoRenderPending(false),
-      mLatencySum(0ll),
-      mLatencyCount(0),
       mNumFramesLate(0),
       mNumFrames(0) {
 }
@@ -476,25 +474,6 @@
 DirectRenderer::~DirectRenderer() {
 }
 
-int64_t DirectRenderer::getAvgLatenessUs() {
-    if (mLatencyCount == 0) {
-        return 0ll;
-    }
-
-    int64_t avgLatencyUs = mLatencySum / mLatencyCount;
-
-    mLatencySum = 0ll;
-    mLatencyCount = 0;
-
-    if (mNumFrames > 0) {
-        ALOGI("%d / %d frames late", mNumFramesLate, mNumFrames);
-        mNumFramesLate = 0;
-        mNumFrames = 0;
-    }
-
-    return avgLatencyUs;
-}
-
 void DirectRenderer::onMessageReceived(const sp<AMessage> &msg) {
     switch (msg->what()) {
         case kWhatDecoderNotify:
@@ -632,9 +611,6 @@
         }
         ++mNumFrames;
 
-        mLatencySum += nowUs - info.mTimeUs;
-        ++mLatencyCount;
-
         status_t err =
             mDecoderContext[0]->renderOutputBufferAndRelease(info.mIndex);
         CHECK_EQ(err, (status_t)OK);
diff --git a/media/libstagefright/wifi-display/sink/DirectRenderer.h b/media/libstagefright/wifi-display/sink/DirectRenderer.h
index 92c176a..c5a4a83 100644
--- a/media/libstagefright/wifi-display/sink/DirectRenderer.h
+++ b/media/libstagefright/wifi-display/sink/DirectRenderer.h
@@ -34,8 +34,6 @@
     void setFormat(size_t trackIndex, const sp<AMessage> &format);
     void queueAccessUnit(size_t trackIndex, const sp<ABuffer> &accessUnit);
 
-    int64_t getAvgLatenessUs();
-
 protected:
     virtual void onMessageReceived(const sp<AMessage> &msg);
     virtual ~DirectRenderer();
@@ -64,9 +62,6 @@
 
     sp<AudioRenderer> mAudioRenderer;
 
-    int64_t mLatencySum;
-    size_t mLatencyCount;
-
     int32_t mNumFramesLate;
     int32_t mNumFrames;
 
diff --git a/media/libstagefright/wifi-display/sink/WifiDisplaySink.cpp b/media/libstagefright/wifi-display/sink/WifiDisplaySink.cpp
index 62021c0..bc98402 100644
--- a/media/libstagefright/wifi-display/sink/WifiDisplaySink.cpp
+++ b/media/libstagefright/wifi-display/sink/WifiDisplaySink.cpp
@@ -51,8 +51,10 @@
       mIDRFrameRequestPending(false),
       mTimeOffsetUs(0ll),
       mTimeOffsetValid(false),
-      mTargetLatencyUs(-1ll),
-      mSetupDeferred(false) {
+      mSetupDeferred(false),
+      mLatencyCount(0),
+      mLatencySumUs(0ll),
+      mLatencyMaxUs(0ll) {
     // We support any and all resolutions, but prefer 720p30
     mSinkSupportedVideoFormats.setNativeResolution(
             VideoFormats::RESOLUTION_CEA, 5);  // 1280 x 720 p30
@@ -265,13 +267,20 @@
 
         case kWhatReportLateness:
         {
-            int64_t latenessUs = mRenderer->getAvgLatenessUs();
+            if (mLatencyCount > 0) {
+                int64_t avgLatencyUs = mLatencySumUs / mLatencyCount;
 
-            ALOGI("avg. lateness = %lld ms",
-                  (latenessUs + mTargetLatencyUs) / 1000ll);
+                ALOGI("avg. latency = %lld ms (max %lld ms)",
+                      avgLatencyUs / 1000ll,
+                      mLatencyMaxUs / 1000ll);
 
-            mMediaReceiver->notifyLateness(
-                    0 /* trackIndex */, latenessUs);
+                mMediaReceiver->notifyLateness(
+                        0 /* trackIndex */, avgLatencyUs);
+            }
+
+            mLatencyCount = 0;
+            mLatencySumUs = 0ll;
+            mLatencyMaxUs = 0ll;
 
             msg->post(kReportLatenessEveryUs);
             break;
@@ -282,6 +291,30 @@
     }
 }
 
+static void dumpDelay(size_t trackIndex, int64_t timeUs) {
+    int64_t delayMs = (ALooper::GetNowUs() - timeUs) / 1000ll;
+
+    static const int64_t kMinDelayMs = 0;
+    static const int64_t kMaxDelayMs = 300;
+
+    const char *kPattern = "########################################";
+    size_t kPatternSize = strlen(kPattern);
+
+    int n = (kPatternSize * (delayMs - kMinDelayMs))
+                / (kMaxDelayMs - kMinDelayMs);
+
+    if (n < 0) {
+        n = 0;
+    } else if ((size_t)n > kPatternSize) {
+        n = kPatternSize;
+    }
+
+    ALOGI("[%lld]: (%4lld ms) %s",
+          timeUs / 1000,
+          delayMs,
+          kPattern + kPatternSize - n);
+}
+
 void WifiDisplaySink::onMediaReceiverNotify(const sp<AMessage> &msg) {
     int32_t what;
     CHECK(msg->findInt32("what", &what));
@@ -319,24 +352,6 @@
 
             CHECK(mTimeOffsetValid);
 
-            int64_t latencyUs = 200000ll;  // 200ms by default
-
-            char val[PROPERTY_VALUE_MAX];
-            if (property_get("media.wfd-sink.latency", val, NULL)) {
-                char *end;
-                int64_t x = strtoll(val, &end, 10);
-
-                if (end > val && *end == '\0' && x >= 0ll) {
-                    latencyUs = x;
-                }
-            }
-
-            if (latencyUs != mTargetLatencyUs) {
-                mTargetLatencyUs = latencyUs;
-
-                ALOGI("Assuming %lld ms of latency.", latencyUs / 1000ll);
-            }
-
             sp<ABuffer> accessUnit;
             CHECK(msg->findBuffer("accessUnit", &accessUnit));
 
@@ -345,13 +360,24 @@
 
             // We are the timesync _client_,
             // client time = server time - time offset.
-            timeUs += mTargetLatencyUs - mTimeOffsetUs;
+            timeUs -= mTimeOffsetUs;
 
             accessUnit->meta()->setInt64("timeUs", timeUs);
 
             size_t trackIndex;
             CHECK(msg->findSize("trackIndex", &trackIndex));
 
+            int64_t nowUs = ALooper::GetNowUs();
+            int64_t delayUs = nowUs - timeUs;
+
+            mLatencySumUs += delayUs;
+            if (mLatencyCount == 0 || delayUs > mLatencyMaxUs) {
+                mLatencyMaxUs = delayUs;
+            }
+            ++mLatencyCount;
+
+            // dumpDelay(trackIndex, timeUs);
+
 #if USE_TUNNEL_RENDERER
             mRenderer->queueBuffer(accessUnit);
 #else
diff --git a/media/libstagefright/wifi-display/sink/WifiDisplaySink.h b/media/libstagefright/wifi-display/sink/WifiDisplaySink.h
index 2b8c6f7..f515177 100644
--- a/media/libstagefright/wifi-display/sink/WifiDisplaySink.h
+++ b/media/libstagefright/wifi-display/sink/WifiDisplaySink.h
@@ -132,10 +132,12 @@
     int64_t mTimeOffsetUs;
     bool mTimeOffsetValid;
 
-    int64_t mTargetLatencyUs;
-
     bool mSetupDeferred;
 
+    size_t mLatencyCount;
+    int64_t mLatencySumUs;
+    int64_t mLatencyMaxUs;
+
     status_t sendM2(int32_t sessionID);
     status_t sendSetup(int32_t sessionID, const char *uri);
     status_t sendPlay(int32_t sessionID, const char *uri);
diff --git a/media/libstagefright/wifi-display/wfd.cpp b/media/libstagefright/wifi-display/wfd.cpp
index 4f7dcc8..9fee4d0 100644
--- a/media/libstagefright/wifi-display/wfd.cpp
+++ b/media/libstagefright/wifi-display/wfd.cpp
@@ -43,7 +43,8 @@
             "               -u uri        \tconnect to an rtsp uri\n"
             "               -l ip[:port] \tlisten on the specified port "
             "               -f(ilename)  \tstream media "
-            "(create a sink)\n",
+            "(create a sink)\n"
+            "               -s(pecial)   \trun in 'special' mode\n",
             me);
 }
 
@@ -222,8 +223,10 @@
 
     AString path;
 
+    bool specialMode = false;
+
     int res;
-    while ((res = getopt(argc, argv, "hc:l:u:f:")) >= 0) {
+    while ((res = getopt(argc, argv, "hc:l:u:f:s")) >= 0) {
         switch (res) {
             case 'c':
             {
@@ -281,6 +284,12 @@
                 break;
             }
 
+            case 's':
+            {
+                specialMode = true;
+                break;
+            }
+
             case '?':
             case 'h':
             default:
@@ -357,7 +366,7 @@
     sp<ALooper> looper = new ALooper;
 
     sp<WifiDisplaySink> sink = new WifiDisplaySink(
-            0 /* flags */,
+            specialMode ? WifiDisplaySink::FLAG_SPECIAL_MODE : 0 /* flags */,
             session,
             surface->getIGraphicBufferProducer());