diff --git a/gui/QT/widget/recv_loss.cpp b/gui/QT/widget/recv_loss.cpp index a38e26a36..f824c5db9 100644 --- a/gui/QT/widget/recv_loss.cpp +++ b/gui/QT/widget/recv_loss.cpp @@ -2,6 +2,7 @@ #include "utils/string_view_utils.hpp" RecvLossWidget::RecvLossWidget(QWidget *parent) : QProgressBar(parent){ + elapsedTimer.start(); reset(); QObject::connect(&timer, &QTimer::timeout, this, &RecvLossWidget::timeout); timer.setInterval(timeout_msec); @@ -14,30 +15,76 @@ void RecvLossWidget::reset(){ setFormat("Nothing received"); setTextVisible(true); setToolTip("Nothing received"); + + reports.clear(); } void RecvLossWidget::parseLine(std::string_view line){ if(!sv_is_prefix(line, "SSRC ")) - return; + return; auto tmp = line; tokenize(tmp, ' '); //"SSRC" auto ssrc_sv = tokenize(tmp, ' '); //actual ssrc + if(ssrc_sv.substr(0, 2) == "0x") + ssrc_sv.remove_prefix(2); auto packet_counts = tokenize(tmp, ' '); //received/total auto received_sv = tokenize(packet_counts, '/'); auto total_sv = tokenize(packet_counts, '/'); + int ssrc; int received; int total; - if(!parse_num(received_sv, received) || !parse_num(total_sv, total)) - return; + if(!parse_num(received_sv, received) + || !parse_num(total_sv, total) + || !parse_num(ssrc_sv, ssrc, 16)) + return; + + addReport(ssrc, received, total); + updateVal(); +} + +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(); +} + +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()); + + for(auto& r : reports){ + received += r.received; + total += r.total; + } float ratio = ((float) received / total) * 100.f; setFormat("Received %p% of packets"); setValue(ratio); - setToolTip(QString::fromUtf8(line.data(), line.length())); + //setToolTip(QString::fromUtf8(line.data(), line.length())); timer.start(); } diff --git a/gui/QT/widget/recv_loss.hpp b/gui/QT/widget/recv_loss.hpp index 47f401581..a79ec6523 100644 --- a/gui/QT/widget/recv_loss.hpp +++ b/gui/QT/widget/recv_loss.hpp @@ -5,10 +5,12 @@ #include #include +#include +#include #include class RecvLossWidget : public QProgressBar{ - Q_OBJECT +Q_OBJECT public: RecvLossWidget(QWidget *parent = nullptr); ~RecvLossWidget() = default; @@ -20,9 +22,21 @@ private slots: void timeout(); private: + static const int timeout_msec = 15000; QTimer timer; + QElapsedTimer elapsedTimer; - const int timeout_msec = 15000; + struct SSRC_report{ + int ssrc = 0; + int received = 0; + int total = 0; + + qint64 lastReportMs = 0; + }; + std::vector reports; + + void addReport(int ssrc, int received, int total); + void updateVal(); }; #endif //RECV_LOSS_WIDGET_fcb5ae52ae4c