Modified udptest to sync time across devices.
Change-Id: Ib055cd8ab5931395907d017331e27f5d781d7019
diff --git a/media/libstagefright/wifi-display/udptest.cpp b/media/libstagefright/wifi-display/udptest.cpp
index 1cd82c3..86437e0 100644
--- a/media/libstagefright/wifi-display/udptest.cpp
+++ b/media/libstagefright/wifi-display/udptest.cpp
@@ -47,8 +47,18 @@
kWhatStartClient,
kWhatUDPNotify,
kWhatSendPacket,
+ kWhatTimedOut,
};
+ struct TimeInfo {
+ int64_t mT1; // client timestamp at send
+ int64_t mT2; // server timestamp at receive
+ int64_t mT3; // server timestamp at send
+ int64_t mT4; // client timestamp at receive
+ };
+
+ static const int64_t kTimeoutDelayUs = 1000000ll;
+
sp<ANetworkSession> mNetSession;
bool mIsServer;
@@ -57,9 +67,16 @@
uint32_t mSeqNo;
double mTotalTimeUs;
int32_t mCount;
+ int64_t mSumOffsets;
+
+ int64_t mPendingT1;
+ int32_t mTimeoutGeneration;
void postSendPacket(int64_t delayUs = 0ll);
+ void postTimeout();
+ void cancelTimeout();
+
DISALLOW_EVIL_CONSTRUCTORS(TestHandler);
};
@@ -70,7 +87,10 @@
mUDPSession(0),
mSeqNo(0),
mTotalTimeUs(0.0),
- mCount(0) {
+ mCount(0),
+ mSumOffsets(0ll),
+ mPendingT1(0ll),
+ mTimeoutGeneration(0) {
}
TestHandler::~TestHandler() {
@@ -131,30 +151,31 @@
case kWhatSendPacket:
{
- char buffer[12];
- memset(buffer, 0, sizeof(buffer));
+ TimeInfo ti;
+ memset(&ti, 0, sizeof(ti));
- buffer[0] = mSeqNo >> 24;
- buffer[1] = (mSeqNo >> 16) & 0xff;
- buffer[2] = (mSeqNo >> 8) & 0xff;
- buffer[3] = mSeqNo & 0xff;
- ++mSeqNo;
-
- int64_t nowUs = ALooper::GetNowUs();
- buffer[4] = nowUs >> 56;
- buffer[5] = (nowUs >> 48) & 0xff;
- buffer[6] = (nowUs >> 40) & 0xff;
- buffer[7] = (nowUs >> 32) & 0xff;
- buffer[8] = (nowUs >> 24) & 0xff;
- buffer[9] = (nowUs >> 16) & 0xff;
- buffer[10] = (nowUs >> 8) & 0xff;
- buffer[11] = nowUs & 0xff;
+ ti.mT1 = ALooper::GetNowUs();
CHECK_EQ((status_t)OK,
mNetSession->sendRequest(
- mUDPSession, buffer, sizeof(buffer)));
+ mUDPSession, &ti, sizeof(ti)));
- postSendPacket(20000ll);
+ mPendingT1 = ti.mT1;
+ postTimeout();
+ break;
+ }
+
+ case kWhatTimedOut:
+ {
+ int32_t generation;
+ CHECK(msg->findInt32("generation", &generation));
+
+ if (generation != mTimeoutGeneration) {
+ break;
+ }
+
+ ALOGI("timed out, sending another request");
+ postSendPacket();
break;
}
@@ -182,6 +203,9 @@
strerror(-err));
mNetSession->destroySession(sessionID);
+
+ cancelTimeout();
+ looper()->stop();
break;
}
@@ -190,8 +214,16 @@
int32_t sessionID;
CHECK(msg->findInt32("sessionID", &sessionID));
- sp<ABuffer> data;
- CHECK(msg->findBuffer("data", &data));
+ sp<ABuffer> packet;
+ CHECK(msg->findBuffer("data", &packet));
+
+ int64_t arrivalTimeUs;
+ CHECK(packet->meta()->findInt64(
+ "arrivalTimeUs", &arrivalTimeUs));
+
+ CHECK_EQ(packet->size(), sizeof(TimeInfo));
+
+ TimeInfo *ti = (TimeInfo *)packet->data();
if (mIsServer) {
if (!mConnected) {
@@ -208,43 +240,41 @@
mConnected = true;
}
- int64_t nowUs = ALooper::GetNowUs();
-
- sp<ABuffer> buffer = new ABuffer(data->size() + 8);
- memcpy(buffer->data(), data->data(), data->size());
-
- uint8_t *ptr = buffer->data() + data->size();
-
- *ptr++ = nowUs >> 56;
- *ptr++ = (nowUs >> 48) & 0xff;
- *ptr++ = (nowUs >> 40) & 0xff;
- *ptr++ = (nowUs >> 32) & 0xff;
- *ptr++ = (nowUs >> 24) & 0xff;
- *ptr++ = (nowUs >> 16) & 0xff;
- *ptr++ = (nowUs >> 8) & 0xff;
- *ptr++ = nowUs & 0xff;
+ ti->mT2 = arrivalTimeUs;
+ ti->mT3 = ALooper::GetNowUs();
CHECK_EQ((status_t)OK,
mNetSession->sendRequest(
- mUDPSession, buffer->data(), buffer->size()));
+ mUDPSession, ti, sizeof(*ti)));
} else {
- CHECK_EQ(data->size(), 20u);
+ if (ti->mT1 != mPendingT1) {
+ break;
+ }
- uint32_t seqNo = U32_AT(data->data());
- int64_t t1 = U64_AT(data->data() + 4);
- int64_t t2 = U64_AT(data->data() + 12);
+ cancelTimeout();
+ mPendingT1 = 0;
- int64_t t3;
- CHECK(data->meta()->findInt64("arrivalTimeUs", &t3));
+ ti->mT4 = arrivalTimeUs;
-#if 0
- printf("roundtrip seqNo %u, time = %lld us\n",
- seqNo, t3 - t1);
-#else
- mTotalTimeUs += t3 - t1;
+ // One way delay for a packet to travel from client
+ // to server or back (assumed to be the same either way).
+ int64_t delay =
+ (ti->mT2 - ti->mT1 + ti->mT4 - ti->mT3) / 2;
+
+ // Offset between the client clock (T1, T4) and the
+ // server clock (T2, T3) timestamps.
+ int64_t offset =
+ (ti->mT2 - ti->mT1 - ti->mT4 + ti->mT3) / 2;
+
+ mSumOffsets += offset;
++mCount;
- printf("avg. roundtrip time %.2f us\n", mTotalTimeUs / mCount);
-#endif
+
+ printf("delay = %lld us,\toffset %lld us\n",
+ delay,
+ offset);
+ fflush(stdout);
+
+ postSendPacket(1000000ll / 30);
}
break;
}
@@ -265,6 +295,16 @@
(new AMessage(kWhatSendPacket, id()))->post(delayUs);
}
+void TestHandler::postTimeout() {
+ sp<AMessage> msg = new AMessage(kWhatTimedOut, id());
+ msg->setInt32("generation", mTimeoutGeneration);
+ msg->post(kTimeoutDelayUs);
+}
+
+void TestHandler::cancelTimeout() {
+ ++mTimeoutGeneration;
+}
+
} // namespace android
static void usage(const char *me) {