diff --git a/gui/QT/util/ssrc_container.hpp b/gui/QT/util/ssrc_container.hpp new file mode 100644 index 000000000..387010b5a --- /dev/null +++ b/gui/QT/util/ssrc_container.hpp @@ -0,0 +1,52 @@ +#ifndef SSRC_CONTAINER_HPP_1b2b8951b25f +#define SSRC_CONTAINER_HPP_1b2b8951b25f + +#include + +template +class SSRC_container{ +public: + struct Holder{ + T item; + uint32_t ssrc; + Ts_type timestamp; + }; + + void insert(uint32_t ssrc, const T& item, Ts_type timestamp); + const std::vector& get() const { return items; } + void remove_timed_out(Ts_type timeout, Ts_type now); + void clear() { items.clear(); } + +private: + std::vector items; +}; + +template +inline void SSRC_container::insert(uint32_t ssrc, const T& item, Ts_type timestamp){ + Holder *h = nullptr; + for(auto& i : items){ + if(i.ssrc == ssrc){ + h = &i; + } + } + + if(!h){ + Holder newItem; + newItem.ssrc = ssrc; + items.push_back(newItem); + h = &items.back(); + } + + h->item = item; + h->timestamp = timestamp; +} + +template +inline void SSRC_container::remove_timed_out(Ts_type timeout, Ts_type now){ + auto endIt = std::remove_if(items.begin(), items.end(), + [now, timeout](const Holder& h){ return now - h.timestamp > timeout; }); + + items.erase(endIt, items.end()); +} + +#endif //SSRC_CONTAINER_HPP_1b2b8951b25f diff --git a/gui/QT/uv-qt.pro b/gui/QT/uv-qt.pro index e912533b7..08a460267 100644 --- a/gui/QT/uv-qt.pro +++ b/gui/QT/uv-qt.pro @@ -75,6 +75,7 @@ HEADERS += window/ultragrid_window.hpp \ util/debug.hpp \ util/line_buffer.hpp \ util/control_port.hpp \ + util/ssrc_container.hpp \ FORMS += ui/ultragrid_window.ui \ ui/log_window.ui \ diff --git a/gui/QT/widget/recv_loss.cpp b/gui/QT/widget/recv_loss.cpp index 1790ac2d4..9ee7e4fc6 100644 --- a/gui/QT/widget/recv_loss.cpp +++ b/gui/QT/widget/recv_loss.cpp @@ -47,41 +47,24 @@ void RecvLossWidget::parseLine(std::string_view line){ } void RecvLossWidget::addReport(int ssrc, int received, int total){ - SSRC_report *rep = nullptr; - for(auto& r : reports){ - if(r.ssrc == ssrc){ - rep = &r; - } - } - - if(!rep){ - SSRC_report newRep; - newRep.ssrc = ssrc; - reports.push_back(newRep); - rep = &reports.back(); - } - - rep->received = received; - rep->total = total; - rep->lastReportMs = elapsedTimer.elapsed(); + SSRC_report rep; + rep.received = received; + rep.total = total; + reports.insert(ssrc, rep, elapsedTimer.elapsed()); } void RecvLossWidget::updateVal(){ int received = 0; int total = 0; - auto now = elapsedTimer.elapsed(); - auto endIt = std::remove_if(reports.begin(), reports.end(), - [now](const SSRC_report& r){ return now - r.lastReportMs > timeout_msec; }); - - reports.erase(endIt, reports.end()); + reports.remove_timed_out(timeout_msec, elapsedTimer.elapsed()); QString tooltip; - for(auto& r : reports){ - received += r.received; - total += r.total; + for(auto& r : reports.get()){ + received += r.item.received; + total += r.item.total; tooltip += QString::number(r.ssrc, 16) + ": " - + QString::number(r.received) + '/' + QString::number(r.total) + '\n'; + + QString::number(r.item.received) + '/' + QString::number(r.item.total) + '\n'; } if(tooltip.endsWith('\n')) diff --git a/gui/QT/widget/recv_loss.hpp b/gui/QT/widget/recv_loss.hpp index a79ec6523..a3eefc869 100644 --- a/gui/QT/widget/recv_loss.hpp +++ b/gui/QT/widget/recv_loss.hpp @@ -5,10 +5,11 @@ #include #include -#include #include #include +#include "ssrc_container.hpp" + class RecvLossWidget : public QProgressBar{ Q_OBJECT public: @@ -27,13 +28,10 @@ private: QElapsedTimer elapsedTimer; struct SSRC_report{ - int ssrc = 0; int received = 0; int total = 0; - - qint64 lastReportMs = 0; }; - std::vector reports; + SSRC_container reports; void addReport(int ssrc, int received, int total); void updateVal();