From 7b026dc80b2a4b892d1ba8f445f9234bb6730d4d Mon Sep 17 00:00:00 2001
From: Nicolas Pope <nwpope@utu.fi>
Date: Sun, 26 Jul 2020 21:17:30 +0300
Subject: [PATCH] Add latency information

---
 applications/gui2/src/modules/camera.cpp                | 4 ++++
 applications/gui2/src/modules/camera.hpp                | 1 +
 components/codecs/include/ftl/codecs/packet.hpp         | 6 ++----
 components/streams/src/builder.cpp                      | 2 ++
 components/streams/src/filestream.cpp                   | 1 +
 components/streams/src/netstream.cpp                    | 2 +-
 components/streams/src/receiver.cpp                     | 4 ++++
 components/structures/include/ftl/data/new_frameset.hpp | 4 +---
 8 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/applications/gui2/src/modules/camera.cpp b/applications/gui2/src/modules/camera.cpp
index 36e0e3779..aec6695fd 100644
--- a/applications/gui2/src/modules/camera.cpp
+++ b/applications/gui2/src/modules/camera.cpp
@@ -30,13 +30,16 @@ void Camera::update(double delta) {
 	if (nframes_ < 0) { return; }
 	if (nframes_ > update_fps_freq_) {
 		float n = nframes_;
+		float l = latency_ / n;
 		nframes_ = 0;
+		latency_ = 0;
 		auto t =  glfwGetTime();
 		float diff = t - last_;
 		last_ =  t;
 
 		auto *mod = screen->getModule<ftl::gui2::Statistics>();
 		mod->getJSON(StatisticsPanel::PERFORMANCE_INFO)["FPS"] = n/diff;
+		mod->getJSON(StatisticsPanel::PERFORMANCE_INFO)["Latency"] = l;
 		if (live_) mod->getJSON(StatisticsPanel::MEDIA_STATUS)["LIVE"] = nlohmann::json{{"icon", ENTYPO_ICON_VIDEO_CAMERA},{"value", true},{"colour","#0000FF"},{"size",28}};
 
 		auto ptr = std::atomic_load(&latest_);
@@ -285,6 +288,7 @@ void Camera::activate(ftl::data::FrameID id) {
 
 			screen->redraw();
 			nframes_++;
+			latency_ += ftl::timer::get_time() - fs->localTimestamp;
 			return true;
 		}
 	);
diff --git a/applications/gui2/src/modules/camera.hpp b/applications/gui2/src/modules/camera.hpp
index 7405c8c50..d4da36f3b 100644
--- a/applications/gui2/src/modules/camera.hpp
+++ b/applications/gui2/src/modules/camera.hpp
@@ -77,6 +77,7 @@ private:
 	bool vr_=false;
 	float last_=0.0f;
 	std::atomic_int16_t nframes_=0;
+	std::atomic_int64_t latency_=0;
 	int update_fps_freq_=30; // fps counter update frequency (frames)
 
 	ftl::data::FrameSetPtr current_fs_;
diff --git a/components/codecs/include/ftl/codecs/packet.hpp b/components/codecs/include/ftl/codecs/packet.hpp
index 02d0af71f..040f8a1da 100644
--- a/components/codecs/include/ftl/codecs/packet.hpp
+++ b/components/codecs/include/ftl/codecs/packet.hpp
@@ -59,9 +59,8 @@ struct StreamPacketV4 {
 
 	inline int frameNumber() const { return (version >= 4) ? frame_number : streamID; }
 	inline size_t frameSetID() const { return (version >= 4) ? streamID : 0; }
-	inline int64_t localTimestamp() const { return timestamp + originClockDelta; }
 
-	int64_t originClockDelta;  		// Not message packet / saved
+	int64_t localTimestamp;  		// Not message packet / saved
 	unsigned int hint_capability;	// Is this a video stream, for example
 	size_t hint_source_total;		// Number of tracks per frame to expect
 
@@ -86,9 +85,8 @@ struct StreamPacket {
 
 	inline int frameNumber() const { return (version >= 4) ? frame_number : streamID; }
 	inline size_t frameSetID() const { return (version >= 4) ? streamID : 0; }
-	inline int64_t localTimestamp() const { return timestamp + originClockDelta; }
 
-	int64_t originClockDelta;  		// Not message packet / saved
+	int64_t localTimestamp;  		// Not message packet / saved
 	unsigned int hint_capability;	// Is this a video stream, for example
 	size_t hint_source_total;		// Number of tracks per frame to expect
 	int retry_count = 0;			// Decode retry count
diff --git a/components/streams/src/builder.cpp b/components/streams/src/builder.cpp
index 486823cad..232495685 100644
--- a/components/streams/src/builder.cpp
+++ b/components/streams/src/builder.cpp
@@ -88,6 +88,7 @@ std::shared_ptr<ftl::data::FrameSet> LocalBuilder::getNextFrameSet(int64_t ts) {
 	// Must lock to ensure no updates can happen here
 	UNIQUE_LOCK(fs->smtx, lk2);
 	fs->changeTimestamp(ts);
+	fs->localTimestamp = ts;
 	fs->store();
 	//for (auto &f : fs->frames) {
 	//	f.store();
@@ -421,6 +422,7 @@ std::shared_ptr<ftl::data::FrameSet> ForeignBuilder::_addFrameset(int64_t timest
 
 	newf->count = 0;
 	newf->mask = 0;
+	newf->localTimestamp = timestamp;
 	newf->clearFlags();
 
 	// Insertion sort by timestamp
diff --git a/components/streams/src/filestream.cpp b/components/streams/src/filestream.cpp
index ad94a6f09..61db4ce84 100644
--- a/components/streams/src/filestream.cpp
+++ b/components/streams/src/filestream.cpp
@@ -206,6 +206,7 @@ void File::_patchPackets(ftl::codecs::StreamPacket &spkt, ftl::codecs::Packet &p
 	}
 
 	spkt.version = 5;
+	spkt.localTimestamp = spkt.timestamp;
 
 	// Fix for flags corruption
 	if (pkt.data.size() == 0) {
diff --git a/components/streams/src/netstream.cpp b/components/streams/src/netstream.cpp
index 2643b99b3..f904d6638 100644
--- a/components/streams/src/netstream.cpp
+++ b/components/streams/src/netstream.cpp
@@ -169,7 +169,7 @@ bool Net::begin() {
 		StreamPacket spkt = spkt_raw;
 		// FIXME: see #335
 		//spkt.timestamp -= clock_adjust_;
-		spkt.originClockDelta = clock_adjust_;
+		spkt.localTimestamp = now - ttimeoff;
 		spkt.hint_capability = 0;
 		spkt.hint_source_total = 0;
 		//LOG(INFO) << "LATENCY: " << ftl::timer::get_time() - spkt.localTimestamp() << " : " << spkt.timestamp << " - " << clock_adjust_;
diff --git a/components/streams/src/receiver.cpp b/components/streams/src/receiver.cpp
index e1f286c9e..8b59bf6ed 100644
--- a/components/streams/src/receiver.cpp
+++ b/components/streams/src/receiver.cpp
@@ -209,6 +209,7 @@ void Receiver::_processData(const StreamPacket &spkt, const Packet &pkt) {
 		//UNIQUE_LOCK(vidstate.mutex, lk);
 		timestamp_ = spkt.timestamp;
 		fs->completed(spkt.frame_number);
+		fs->localTimestamp = spkt.localTimestamp;
 	}
 
 	/*const auto *cs = stream_;
@@ -258,6 +259,7 @@ void Receiver::_processAudio(const StreamPacket &spkt, const Packet &pkt) {
 		//UNIQUE_LOCK(vidstate.mutex, lk);
 		timestamp_ = spkt.timestamp;
 		fs->completed(spkt.frame_number);
+		fs->localTimestamp = spkt.localTimestamp;
 	}
 
 	// Generate settings from packet data
@@ -435,6 +437,7 @@ void Receiver::_processVideo(const StreamPacket &spkt, const Packet &pkt) {
 			UNIQUE_LOCK(vidstate.mutex, lk);
 			timestamp_ = spkt.timestamp;
 			fs->completed(spkt.frame_number+i);
+			fs->localTimestamp = spkt.localTimestamp;
 		}
 	}
 }
@@ -458,6 +461,7 @@ void Receiver::processPackets(const StreamPacket &spkt, const Packet &pkt) {
 					//UNIQUE_LOCK(vidstate.mutex, lk);  // FIXME: Should have a lock here...
 					timestamp_ = spkt.timestamp;
 					fs->completed(frame.source());
+					fs->localTimestamp = spkt.localTimestamp;
 				}
 
 				//if (frame.availableAll(sel)) {
diff --git a/components/structures/include/ftl/data/new_frameset.hpp b/components/structures/include/ftl/data/new_frameset.hpp
index 096a02c2f..ad75c990b 100644
--- a/components/structures/include/ftl/data/new_frameset.hpp
+++ b/components/structures/include/ftl/data/new_frameset.hpp
@@ -38,7 +38,7 @@ class FrameSet : public ftl::data::Frame {
 
 	//int id=0;
 	//int64_t timestamp;				// Millisecond timestamp of all frames
-	int64_t originClockDelta;
+	int64_t localTimestamp;
 	std::vector<Frame> frames;
 	std::atomic<int> count;				// Number of valid frames
 	std::atomic<unsigned int> mask;		// Mask of all sources that contributed
@@ -47,8 +47,6 @@ class FrameSet : public ftl::data::Frame {
 
 	//Eigen::Matrix4d pose;  // Set to identity by default.
 
-	inline int64_t localTimestamp() const { return timestamp() + originClockDelta; }
-
 	inline void set(FSFlag f) { flags_ |= (1 << static_cast<int>(f)); }
 	inline void clear(FSFlag f) { flags_ &= ~(1 << static_cast<int>(f)); }
 	inline bool test(FSFlag f) const { return flags_ & (1 << static_cast<int>(f)); }
-- 
GitLab