diff --git a/applications/gui2/src/modules/camera.cpp b/applications/gui2/src/modules/camera.cpp index 36e0e37793c1a66dc356e121166820af3ad7706c..aec6695fdaa9aaf429681437e165a7f191fa8193 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 7405c8c5091dda95b43fdfd44dd6d594b4ff8193..d4da36f3b391b484711960a332ffb06f0bcd4549 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 02d0af71f4d46ebf7a2a6a196b46d3ffdf51d98a..040f8a1dae03d2f0f87bc34d54c022ab41845bf3 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 486823cadbaa3192663d758acc96771dd43ebcdb..23249568542140e034a377b1f7eb6d73aa83f74d 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 ad94a6f090d85a66a080ebd7ba88af8477a6b1d0..61db4ce84b78f1f12e84f638c4f6eca1cb1e11ea 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 2643b99b307d4806936782ed0e64a8fe415a58e6..f904d66382634a9505c8fdb37e6fd7c21dfe0c11 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 e1f286c9ed6809f74bc54cbb9c537bbb01562bde..8b59bf6ed1676486d4aa0435e1e3b4fdcd4e7f37 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 096a02c2f616f404b97d7cbabc82796d5b14141c..ad75c990ba0d6e6822774e257d560d1e6eea28ab 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)); }