diff --git a/gui/QT/ui/ultragrid_window.ui b/gui/QT/ui/ultragrid_window.ui
index eb872db92..24a2fb2e1 100644
--- a/gui/QT/ui/ultragrid_window.ui
+++ b/gui/QT/ui/ultragrid_window.ui
@@ -53,20 +53,37 @@
-
-
-
-
- 0
- 0
-
-
-
- Local
-
-
- Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft
-
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Local
+
+
+ Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+
@@ -687,6 +704,11 @@
1
+
+ BandwidthWidget
+ QLabel
+
+
diff --git a/gui/QT/uv-qt.pro b/gui/QT/uv-qt.pro
index 08a460267..6f0609df3 100644
--- a/gui/QT/uv-qt.pro
+++ b/gui/QT/uv-qt.pro
@@ -56,6 +56,7 @@ HEADERS += window/ultragrid_window.hpp \
widget/vuMeterWidget.hpp \
widget/recv_report.hpp \
widget/recv_loss.hpp \
+ widget/bandwidth_widget.hpp \
window/settings_window.hpp \
option/widget_ui.hpp \
option/checkable_ui.hpp \
@@ -90,6 +91,7 @@ SOURCES += window/ultragrid_window.cpp \
widget/vuMeterWidget.cpp \
widget/recv_report.cpp \
widget/recv_loss.cpp \
+ widget/bandwidth_widget.cpp \
window/settings_window.cpp \
option/widget_ui.cpp \
option/checkable_ui.cpp \
diff --git a/gui/QT/widget/bandwidth_widget.cpp b/gui/QT/widget/bandwidth_widget.cpp
new file mode 100644
index 000000000..24d3091f8
--- /dev/null
+++ b/gui/QT/widget/bandwidth_widget.cpp
@@ -0,0 +1,82 @@
+#include
+#include "bandwidth_widget.hpp"
+#include "utils/string_view_utils.hpp"
+
+
+BandwidthWidget::BandwidthWidget(QWidget *parent) : QLabel(parent){
+ elapsedTimer.start();
+ reset();
+ QObject::connect(&timer, &QTimer::timeout, this, &BandwidthWidget::timeout);
+ timer.setInterval(timeout_msec);
+}
+
+void BandwidthWidget::updateVal(){
+ reports.remove_timed_out(timeout_msec, elapsedTimer.elapsed());
+
+ long long total = 0;
+ for(const auto& i : reports.get()){
+ total += i.item;
+ }
+
+ report(total);
+
+ timer.start();
+}
+
+void BandwidthWidget::parseLine(std::string_view line){
+ static constexpr std::string_view prefix = "stats tx_send";
+ if(!sv_is_prefix(line, prefix))
+ return;
+
+ line.remove_prefix(prefix.size());
+
+ auto ssrc_sv = tokenize(line, ' ');
+ if(ssrc_sv.substr(0, 2) == "0x")
+ ssrc_sv.remove_prefix(2);
+ auto type = tokenize(line, ' ');
+ auto bytes_sv = tokenize(line, ' ');
+
+ long long bytes = 0;
+ uint32_t ssrc = 0;
+ if(!parse_num(bytes_sv, bytes)
+ || !parse_num(ssrc_sv, ssrc, 16))
+ {
+ return;
+ }
+
+ long long num = 0;
+
+ for(const auto& r : reports.get()){
+ if(r.ssrc != ssrc)
+ continue;
+
+ num = bytes * 1000 / (elapsedTimer.elapsed() - r.timestamp);
+ }
+
+ reports.insert(ssrc, num, elapsedTimer.elapsed());
+ updateVal();
+}
+
+void BandwidthWidget::reset(){
+ reports.clear();
+ report(0);
+ timer.stop();
+}
+
+void BandwidthWidget::timeout(){
+ reset();
+}
+
+void BandwidthWidget::report(long long bytes_per_second){
+ static constexpr std::string_view units = "kMG";
+
+ float num = bytes_per_second;
+ char unit = ' ';
+
+ for(unsigned i = 0; num > 1000 && i < units.size(); i++){
+ unit = units[i];
+ num /= 1000;
+ }
+
+ setText(QString::number(num, 'f', 2) + " " + unit + "Bps");
+}
diff --git a/gui/QT/widget/bandwidth_widget.hpp b/gui/QT/widget/bandwidth_widget.hpp
new file mode 100644
index 000000000..46c2ee4c6
--- /dev/null
+++ b/gui/QT/widget/bandwidth_widget.hpp
@@ -0,0 +1,37 @@
+#ifndef BANDWIDTH_WIDGET_c035f927c51f
+#define BANDWIDTH_WIDGET_c035f927c51f
+
+#include
+#include
+#include
+#include
+
+#include
+
+#include "ssrc_container.hpp"
+
+class BandwidthWidget : public QLabel{
+ Q_OBJECT
+public:
+ BandwidthWidget(QWidget *parent = nullptr);
+ ~BandwidthWidget() = default;
+
+ void updateVal();
+ void parseLine(std::string_view line);
+ void reset();
+
+private slots:
+ void timeout();
+
+private:
+ void report(long long bytes_per_second);
+
+ QTimer timer;
+ QElapsedTimer elapsedTimer;
+
+ SSRC_container reports;
+
+ const int timeout_msec = 2500;
+};
+
+#endif //BANDWIDTH_WIDGET_c035f927c51f
diff --git a/gui/QT/window/ultragrid_window.cpp b/gui/QT/window/ultragrid_window.cpp
index ebd3bf855..daf4dcbcd 100644
--- a/gui/QT/window/ultragrid_window.cpp
+++ b/gui/QT/window/ultragrid_window.cpp
@@ -124,6 +124,9 @@ UltragridWindow::UltragridWindow(QWidget *parent): QMainWindow(parent){
ui.statusbar->addPermanentWidget(&versionLabel);
ui.vuMeter->setControlPort(&controlPort);
+
+ using namespace std::placeholders;
+ controlPort.addLineCallback(std::bind(&BandwidthWidget::parseLine, ui.send_bandwidth, _1));
}
void UltragridWindow::refresh(){
@@ -458,6 +461,7 @@ void UltragridWindow::processStateChanged(UgProcessManager::State state){
receiverLoss.reset();
rtcpRr.reset();
+ ui.send_bandwidth->reset();
}
void UltragridWindow::unexpectedExit(UgProcessManager::State state,