mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-23 01:55:48 -05:00
Merge pull request #976 from srcejon/datvmod_udp_buf_util
DATV Mod: Add UDP buffer utilization in GUI on Windows
This commit is contained in:
commit
14e75232df
@ -52,6 +52,7 @@ MESSAGE_CLASS_DEFINITION(DATVMod::MsgConfigureTsFileName, Message)
|
||||
MESSAGE_CLASS_DEFINITION(DATVMod::MsgConfigureTsFileSourceSeek, Message)
|
||||
MESSAGE_CLASS_DEFINITION(DATVMod::MsgConfigureTsFileSourceStreamTiming, Message)
|
||||
MESSAGE_CLASS_DEFINITION(DATVMod::MsgGetUDPBitrate, Message)
|
||||
MESSAGE_CLASS_DEFINITION(DATVMod::MsgGetUDPBufferUtilization, Message)
|
||||
|
||||
const char* const DATVMod::m_channelIdURI = "sdrangel.channeltx.moddatv";
|
||||
const char* const DATVMod::m_channelId = "DATVMod";
|
||||
@ -185,6 +186,12 @@ bool DATVMod::handleMessage(const Message& cmd)
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgGetUDPBufferUtilization::match(cmd))
|
||||
{
|
||||
m_basebandSource->getInputMessageQueue()->push(DATVMod::MsgGetUDPBufferUtilization::create());
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
|
@ -181,6 +181,23 @@ public:
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgGetUDPBufferUtilization : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
|
||||
static MsgGetUDPBufferUtilization* create()
|
||||
{
|
||||
return new MsgGetUDPBufferUtilization();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
MsgGetUDPBufferUtilization() :
|
||||
Message()
|
||||
{ }
|
||||
};
|
||||
|
||||
//=================================================================
|
||||
|
||||
DATVMod(DeviceAPI *deviceAPI);
|
||||
|
@ -192,6 +192,11 @@ bool DATVModBaseband::handleMessage(const Message& cmd)
|
||||
m_source.reportUDPBitrate();
|
||||
return true;
|
||||
}
|
||||
else if (DATVMod::MsgGetUDPBufferUtilization::match(cmd))
|
||||
{
|
||||
m_source.reportUDPBufferUtilization();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
|
@ -98,6 +98,12 @@ DATVModGUI::DATVModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandS
|
||||
|
||||
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages()));
|
||||
|
||||
#ifndef _WIN32
|
||||
// Only currently works on Windows, so hide on other OSes
|
||||
ui->udpBufferUtilization->setVisible(false);
|
||||
ui->udpBufferUtilizationLine->setVisible(false);
|
||||
#endif
|
||||
|
||||
displaySettings();
|
||||
applySettings(true);
|
||||
if (!m_settings.m_tsFileName.isEmpty())
|
||||
@ -174,6 +180,13 @@ bool DATVModGUI::handleMessage(const Message& message)
|
||||
m_tickMsgOutstanding = false;
|
||||
return true;
|
||||
}
|
||||
else if (DATVModReport::MsgReportUDPBufferUtilization::match(message))
|
||||
{
|
||||
DATVModReport::MsgReportUDPBufferUtilization& report = (DATVModReport::MsgReportUDPBufferUtilization&)message;
|
||||
ui->udpBufferUtilization->setText(tr("%1%").arg(report.getUtilization(), 0, 'f', 1));
|
||||
m_tickMsgOutstanding = false;
|
||||
return true;
|
||||
}
|
||||
else if (DATVMod::MsgConfigureDATVMod::match(message))
|
||||
{
|
||||
const DATVMod::MsgConfigureDATVMod& cfg = (DATVMod::MsgConfigureDATVMod&) message;
|
||||
@ -602,6 +615,7 @@ void DATVModGUI::tick()
|
||||
{
|
||||
m_tickMsgOutstanding = true;
|
||||
m_datvMod->getInputMessageQueue()->push(DATVMod::MsgGetUDPBitrate::create());
|
||||
m_datvMod->getInputMessageQueue()->push(DATVMod::MsgGetUDPBufferUtilization::create());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -568,6 +568,23 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="udpBufferUtilizationLine">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="udpBufferUtilization">
|
||||
<property name="toolTip">
|
||||
<string>Indicates how full the UDP receive buffer is. If this reaches 100%, packets will likely be dropped.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0%</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -22,6 +22,7 @@ MESSAGE_CLASS_DEFINITION(DATVModReport::MsgReportTsFileSourceStreamTiming, Messa
|
||||
MESSAGE_CLASS_DEFINITION(DATVModReport::MsgReportTsFileSourceStreamData, Message)
|
||||
MESSAGE_CLASS_DEFINITION(DATVModReport::MsgReportRates, Message)
|
||||
MESSAGE_CLASS_DEFINITION(DATVModReport::MsgReportUDPBitrate, Message)
|
||||
MESSAGE_CLASS_DEFINITION(DATVModReport::MsgReportUDPBufferUtilization, Message)
|
||||
|
||||
DATVModReport::DATVModReport()
|
||||
{ }
|
||||
|
@ -125,6 +125,27 @@ public:
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgReportUDPBufferUtilization : public Message
|
||||
{
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
float getUtilization() const { return m_utilization; }
|
||||
|
||||
static MsgReportUDPBufferUtilization* create(int utilization)
|
||||
{
|
||||
return new MsgReportUDPBufferUtilization(utilization);
|
||||
}
|
||||
|
||||
protected:
|
||||
float m_utilization;
|
||||
|
||||
MsgReportUDPBufferUtilization(int utilization) :
|
||||
Message(),
|
||||
m_utilization(utilization)
|
||||
{ }
|
||||
};
|
||||
|
||||
public:
|
||||
DATVModReport();
|
||||
~DATVModReport();
|
||||
|
@ -108,6 +108,8 @@ struct DATVModSettings
|
||||
static DATVModulation mapModulation(const QString& string);
|
||||
static QString mapModulation(DATVModulation modulation);
|
||||
|
||||
static const int m_udpBufferSize = 5000000;
|
||||
|
||||
};
|
||||
|
||||
#endif /* PLUGINS_CHANNELTX_MODDATV_DATVMODSETTINGS_H_ */
|
||||
|
@ -43,6 +43,11 @@ extern "C"
|
||||
#include "datvmodreport.h"
|
||||
#include "datvmodsource.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock.h>
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
#endif
|
||||
|
||||
const int DATVModSource::m_levelNbSamples = 10000; // every 10ms
|
||||
|
||||
// Get transport stream bitrate from file
|
||||
@ -223,6 +228,7 @@ DATVModSource::DATVModSource() :
|
||||
m_udpByteCount(0),
|
||||
m_udpBufferIdx(0),
|
||||
m_udpBufferCount(0),
|
||||
m_udpMaxBufferUtilization(0),
|
||||
m_sampleRate(0),
|
||||
m_channelSampleRate(1000000),
|
||||
m_channelFrequencyOffset(0),
|
||||
@ -337,6 +343,8 @@ void DATVModSource::modulateSample()
|
||||
&& ((m_udpSocket != nullptr) && m_udpSocket->hasPendingDatagrams())
|
||||
)
|
||||
{
|
||||
updateUDPBufferUtilization();
|
||||
|
||||
// Get transport stream packets from UDP - buffer if more than one
|
||||
QNetworkDatagram datagram = m_udpSocket->receiveDatagram();
|
||||
QByteArray ba = datagram.data();
|
||||
@ -577,6 +585,28 @@ void DATVModSource::reportUDPBitrate()
|
||||
m_udpByteCount = 0;
|
||||
}
|
||||
|
||||
void DATVModSource::updateUDPBufferUtilization()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
u_long count;
|
||||
ioctlsocket(m_udpSocket->socketDescriptor(), FIONREAD, &count);
|
||||
if (count > m_udpMaxBufferUtilization) {
|
||||
m_udpMaxBufferUtilization = count;
|
||||
}
|
||||
#else
|
||||
// On linux, ioctl(s, SIOCINQ, &count); only returns length of first datagram, so we can't support this
|
||||
#endif
|
||||
}
|
||||
|
||||
void DATVModSource::reportUDPBufferUtilization()
|
||||
{
|
||||
// Report maximum utilization since last call
|
||||
updateUDPBufferUtilization();
|
||||
if (getMessageQueueToGUI())
|
||||
getMessageQueueToGUI()->push(DATVModReport::MsgReportUDPBufferUtilization::create(m_udpMaxBufferUtilization / (float)DATVModSettings::m_udpBufferSize * 100.0));
|
||||
m_udpMaxBufferUtilization = 0;
|
||||
}
|
||||
|
||||
void DATVModSource::applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force)
|
||||
{
|
||||
qDebug() << "DATVModSource::applyChannelSettings:"
|
||||
@ -680,7 +710,7 @@ void DATVModSource::applySettings(const DATVModSettings& settings, bool force)
|
||||
{
|
||||
m_udpSocket = new QUdpSocket();
|
||||
m_udpSocket->bind(QHostAddress(settings.m_udpAddress), settings.m_udpPort);
|
||||
m_udpSocket->setSocketOption(QAbstractSocket::ReceiveBufferSizeSocketOption, 1000000);
|
||||
m_udpSocket->setSocketOption(QAbstractSocket::ReceiveBufferSizeSocketOption, DATVModSettings::m_udpBufferSize);
|
||||
m_udpTimingStart = boost::chrono::steady_clock::now();
|
||||
m_udpByteCount = 0;
|
||||
}
|
||||
|
@ -70,6 +70,7 @@ public:
|
||||
void seekTsFileStream(int seekPercentage);
|
||||
void reportTsFileSourceStreamTiming();
|
||||
void reportUDPBitrate();
|
||||
void reportUDPBufferUtilization();
|
||||
|
||||
private:
|
||||
uint8_t m_mpegTS[188]; //!< MPEG transport stream packet
|
||||
@ -99,6 +100,7 @@ private:
|
||||
uint8_t m_udpBuffer[188*10];
|
||||
int m_udpBufferIdx; //!< TS frame index into buffer
|
||||
int m_udpBufferCount; //!< Number of TS frames in buffer
|
||||
int m_udpMaxBufferUtilization;
|
||||
|
||||
int m_sampleRate;
|
||||
int m_channelSampleRate;
|
||||
@ -131,6 +133,7 @@ private:
|
||||
int getTSBitrate(const QString& filename);
|
||||
int getDVBSDataBitrate(const DATVModSettings& settings);
|
||||
void checkBitrates();
|
||||
void updateUDPBufferUtilization();
|
||||
|
||||
MessageQueue *getMessageQueueToGUI() { return m_messageQueueToGUI; }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user