diff --git a/applications/gui/src/screen.cpp b/applications/gui/src/screen.cpp index 187ff7945d608f72ef45f4674101209bb3e2f7f7..b5b642d8925217357b15eedc0ea1adb5b60ed044 100644 --- a/applications/gui/src/screen.cpp +++ b/applications/gui/src/screen.cpp @@ -1,5 +1,8 @@ #include "screen.hpp" +#include <ftl/streams/netstream.hpp> +#include <ftl/rgbd/frameset.hpp> + #include <nanogui/opengl.h> #include <nanogui/glutil.h> #include <nanogui/screen.h> @@ -10,6 +13,8 @@ #include <nanogui/toolbutton.h> #include <nanogui/popupbutton.h> +#include <sstream> + #include <nlohmann/json.hpp> #include <loguru.hpp> @@ -60,6 +65,14 @@ namespace { })"; } +template <typename T> +std::string to_string_with_precision(const T a_value, const int n = 6) { + std::ostringstream out; + out.precision(n); + out << std::fixed << a_value; + return out.str(); +} + ftl::gui::Screen::Screen(ftl::Configurable *proot, ftl::net::Universe *pnet, ftl::ctrl::Master *controller) : nanogui::Screen(Eigen::Vector2i(1024, 768), "FT-Lab Remote Presence"), status_("FT-Lab Remote Presence System") { @@ -573,6 +586,22 @@ void ftl::gui::Screen::draw(NVGcontext *ctx) { } nvgTextAlign(ctx, NVG_ALIGN_RIGHT); + + if (root()->value("show_information", false)) { + string msg; + + // FIXME: Do not do this every frame, or cache the results every N frames... + + auto [fps,latency] = ftl::rgbd::Builder::getStatistics(); + msg = string("Frame rate: ") + std::to_string((int)fps); + nvgText(ctx, screenSize[0]-10, 20, msg.c_str(), NULL); + msg = string("Latency: ") + std::to_string((int)latency) + string("ms"); + nvgText(ctx, screenSize[0]-10, 40, msg.c_str(), NULL); + + msg = string("Bitrate: ") + to_string_with_precision(ftl::stream::Net::getRequiredBitrate(), 2) + string("Mbps"); + nvgText(ctx, screenSize[0]-10, 60, msg.c_str(), NULL); + } + nvgText(ctx, screenSize[0]-10, screenSize[1]-20, status_.c_str(), NULL); /* Draw the user interface */ diff --git a/components/rgbd-sources/include/ftl/rgbd/frameset.hpp b/components/rgbd-sources/include/ftl/rgbd/frameset.hpp index eb646b4b4c70d2dd4140abea9bf85c94ca8df931..2f267b55b2367a315546bea3264e43cd24757f7d 100644 --- a/components/rgbd-sources/include/ftl/rgbd/frameset.hpp +++ b/components/rgbd-sources/include/ftl/rgbd/frameset.hpp @@ -133,6 +133,12 @@ class Builder : public Generator { void setBufferSize(size_t n) { bufferSize_ = n; } + /** + * Retrieve an fps + latency pair, averaged since last call to this + * function. + */ + static std::pair<float,float> getStatistics(); + private: std::list<FrameSet*> framesets_; // Active framesets std::list<FrameSet*> allocated_; // Keep memory allocations @@ -141,9 +147,6 @@ class Builder : public Generator { ftl::rgbd::VideoCallback cb_; MUTEX mutex_; int mspf_; - float latency_; - float fps_; - int stats_count_; int64_t last_ts_; int64_t last_frame_; int id_; @@ -156,6 +159,11 @@ class Builder : public Generator { std::string name_; + static MUTEX msg_mutex__; + static float latency__; + static float fps__; + static int stats_count__; + /* Insert a new frameset into the buffer, along with all intermediate * framesets between the last in buffer and the new one. */ diff --git a/components/rgbd-sources/src/frameset.cpp b/components/rgbd-sources/src/frameset.cpp index 4c9fa2eada0880949decfa8dfb8a99ff9127bc20..785d991ad8eb04a3ad005ffb495d6f931bd949d3 100644 --- a/components/rgbd-sources/src/frameset.cpp +++ b/components/rgbd-sources/src/frameset.cpp @@ -16,6 +16,11 @@ using ftl::codecs::Channel; using ftl::rgbd::FrameSet; using ftl::codecs::Channels; +float Builder::latency__ = 0.0f; +float Builder::fps__ = 0.0f; +int Builder::stats_count__ = 0; +MUTEX Builder::msg_mutex__; + /*void FrameSet::upload(ftl::codecs::Channels<0> c, cudaStream_t stream) { for (auto &f : frames) { f.upload(c, stream); @@ -69,10 +74,6 @@ Builder::Builder() : head_(0), id_(0) { mspf_ = ftl::timer::getInterval(); name_ = "NoName"; - latency_ = 0.0f;; - stats_count_ = 0; - fps_ = 0.0f; - if (size_ > 0) states_.resize(size_); } @@ -241,18 +242,33 @@ static void mergeFrameset(ftl::rgbd::FrameSet &f1, ftl::rgbd::FrameSet &f2) { } void Builder::_recordStats(float fps, float latency) { - latency_ += latency; - fps_ += fps; - ++stats_count_; + UNIQUE_LOCK(msg_mutex__, lk); + latency__ += latency; + fps__ += fps; + ++stats_count__; - if (fps_/float(stats_count_) <= float(stats_count_)) { + /*if (fps_/float(stats_count_) <= float(stats_count_)) { fps_ /= float(stats_count_); latency_ /= float(stats_count_); LOG(INFO) << name_ << ": fps = " << fps_ << ", latency = " << latency_; fps_ = 0.0f; latency_ = 0.0f; stats_count_ = 0; - } + }*/ +} + +std::pair<float,float> Builder::getStatistics() { + UNIQUE_LOCK(msg_mutex__, lk); + if (stats_count__ == 0.0f) return {0.0f,0.0f}; + fps__ /= float(stats_count__); + latency__ /= float(stats_count__); + float fps = fps__; + float latency = latency__; + //LOG(INFO) << name_ << ": fps = " << fps_ << ", latency = " << latency_; + fps__ = 0.0f; + latency__ = 0.0f; + stats_count__ = 0; + return {fps,latency}; } ftl::rgbd::FrameSet *Builder::_findFrameset(int64_t ts) { diff --git a/components/streams/include/ftl/streams/netstream.hpp b/components/streams/include/ftl/streams/netstream.hpp index 3c7aef3c64e917e4daac0722340414b2123dffd8..0db0013196f0fe8aa03adc74480223a004863c95 100644 --- a/components/streams/include/ftl/streams/netstream.hpp +++ b/components/streams/include/ftl/streams/netstream.hpp @@ -60,6 +60,12 @@ class Net : public Stream { inline const ftl::UUID &getPeer() const { return peer_; } + /** + * Return the average bitrate of all streams since the last call to this + * function. Units are Mbps. + */ + static float getRequiredBitrate(); + private: SHARED_MUTEX mutex_; bool active_; @@ -76,10 +82,10 @@ class Net : public Stream { std::array<std::atomic<int>,32> reqtally_; ftl::codecs::Channels<0> last_selected_; - float req_bitrate_; - float sample_count_; - int64_t last_msg_; - MUTEX msg_mtx_; + static float req_bitrate__; + static float sample_count__; + static int64_t last_msg__; + static MUTEX msg_mtx__; std::list<detail::StreamClient> clients_; diff --git a/components/streams/src/netstream.cpp b/components/streams/src/netstream.cpp index b12480d0e5126feba87e60d49458a487158d3e00..72d435fb57ebe3c26d747e2a124e4b6405fc4057 100644 --- a/components/streams/src/netstream.cpp +++ b/components/streams/src/netstream.cpp @@ -17,6 +17,11 @@ using std::optional; static constexpr int kTallyScale = 10; +float Net::req_bitrate__ = 0.0f; +float Net::sample_count__ = 0.0f; +int64_t Net::last_msg__ = 0; +MUTEX Net::msg_mtx__; + Net::Net(nlohmann::json &config, ftl::net::Universe *net) : Stream(config), active_(false), net_(net), clock_adjust_(0) { // TODO: Install "find_stream" binding if not installed... if (!net_->isBound("find_stream")) { @@ -40,7 +45,6 @@ Net::Net(nlohmann::json &config, ftl::net::Universe *net) : Stream(config), acti } last_frame_ = 0; - last_msg_ = 0; time_peer_ = ftl::UUID(0); } @@ -378,16 +382,26 @@ void Net::_checkDataRate(size_t tx_size, int64_t tx_latency, int64_t ts) { float min_mbps = (float(tx_size) * 8.0f * (1000.0f / float(ftl::timer::getInterval()))) / 1048576.0f; //if (actual_mbps > 0.0f && actual_mbps < min_mbps) LOG(WARNING) << "Bitrate = " << actual_mbps << "Mbps, min required = " << min_mbps << "Mbps"; - UNIQUE_LOCK(msg_mtx_,lk); - req_bitrate_ += float(tx_size) * 8.0f; - sample_count_ += 1.0f; + UNIQUE_LOCK(msg_mtx__,lk); + req_bitrate__ += float(tx_size) * 8.0f; + sample_count__ += 1.0f; - if (ts - last_msg_ >= 1000) { + /*if (ts - last_msg_ >= 1000) { DLOG(INFO) << "Required Bitrate = " << (req_bitrate_ / float(ts - last_msg_) * 1000.0f / 1048576.0f) << "Mbps"; last_msg_ = ts; req_bitrate_ = 0.0f; sample_count_ = 0.0f; - } + }*/ +} + +float Net::getRequiredBitrate() { + int64_t ts = ftl::timer::get_time(); + UNIQUE_LOCK(msg_mtx__,lk); + float r = (req_bitrate__ / float(ts - last_msg__) * 1000.0f / 1048576.0f); + last_msg__ = ts; + req_bitrate__ = 0.0f; + sample_count__ = 0.0f; + return r; } bool Net::end() {