DATV demod: allow video player enable/disable

This commit is contained in:
f4exb 2021-04-11 23:52:16 +02:00
parent c5ece265e9
commit f8a512e91b
17 changed files with 219 additions and 38 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

View File

@ -102,10 +102,12 @@ public:
void setCNRMeter(LevelMeterSignalDB *cnrMeter) { m_basebandSink->setCNRMeter(cnrMeter); }
void SetVideoRender(DATVideoRender *objScreen) { m_basebandSink->SetVideoRender(objScreen); }
DATVideostream *getVideoStream() { return m_basebandSink->getVideoStream(); }
DATVUDPStream *getUDPStream() { return m_basebandSink->getUDPStream(); }
bool audioActive() { return m_basebandSink->audioActive(); }
bool audioDecodeOK() { return m_basebandSink->audioDecodeOK(); }
bool videoActive() { return m_basebandSink->videoActive(); }
bool videoDecodeOK() { return m_basebandSink->videoDecodeOK(); }
bool udpRunning() { return m_basebandSink->udpRunning(); }
bool playVideo() { return m_basebandSink->playVideo(); }

View File

@ -74,10 +74,12 @@ public:
void setBasebandSampleRate(int sampleRate); //!< To be used when supporting thread is stopped
void SetVideoRender(DATVideoRender *objScreen) { m_sink.SetVideoRender(objScreen); }
DATVideostream *getVideoStream() { return m_sink.getVideoStream(); }
DATVUDPStream *getUDPStream() { return m_sink.getUDPStream(); }
bool audioActive() { return m_sink.audioActive(); }
bool audioDecodeOK() { return m_sink.audioDecodeOK(); }
bool videoActive() { return m_sink.videoActive(); }
bool videoDecodeOK() { return m_sink.videoDecodeOK(); }
bool udpRunning() { return m_sink.udpRunning(); }
bool playVideo() { return m_sink.playVideo(); }
int getModcodModulation() const { return m_sink.getModcodModulation(); }

View File

@ -219,7 +219,12 @@ DATVDemodGUI::DATVDemodGUI(PluginAPI* objPluginAPI, DeviceUISet *deviceUISet, Ba
m_objDATVDemod->setCNRMeter(ui->cnrMeter);
m_objDATVDemod->SetVideoRender(ui->screenTV_2);
connect(m_objDATVDemod->getVideoStream(), &DATVideostream::fifoData, this, &DATVDemodGUI::on_StreamDataAvailable);
if (m_settings.m_playerEnable) {
connect(m_objDATVDemod->getVideoStream(), &DATVideostream::fifoData, this, &DATVDemodGUI::on_StreamDataAvailable);
} else {
connect(m_objDATVDemod->getUDPStream(), &DATVUDPStream::fifoData, this, &DATVDemodGUI::on_StreamDataAvailable);
}
connect(ui->screenTV_2, &DATVideoRender::onMetaDataChanged, this, &DATVDemodGUI::on_StreamMetaDataChanged);
m_intPreviousDecodedData=0;
@ -270,6 +275,7 @@ DATVDemodGUI::DATVDemodGUI(PluginAPI* objPluginAPI, DeviceUISet *deviceUISet, Ba
#endif
ui->playerIndicator->setStyleSheet("QLabel { background-color: gray; border-radius: 8px; }");
ui->udpIndicator->setStyleSheet("QLabel { background-color: gray; border-radius: 8px; }");
resetToDefaults(); // does applySettings()
}
@ -376,6 +382,18 @@ void DATVDemodGUI::displaySettings()
ui->udpTS->setChecked(m_settings.m_udpTS);
ui->udpTSAddress->setText(m_settings.m_udpTSAddress);
ui->udpTSPort->setText(tr("%1").arg(m_settings.m_udpTSPort));
ui->playerEnable->setChecked(m_settings.m_playerEnable);
if (m_settings.m_playerEnable)
{
disconnect(m_objDATVDemod->getUDPStream(), &DATVUDPStream::fifoData, this, &DATVDemodGUI::on_StreamDataAvailable);
connect(m_objDATVDemod->getVideoStream(), &DATVideostream::fifoData, this, &DATVDemodGUI::on_StreamDataAvailable);
}
else
{
disconnect(m_objDATVDemod->getVideoStream(), &DATVideostream::fifoData, this, &DATVDemodGUI::on_StreamDataAvailable);
connect(m_objDATVDemod->getUDPStream(), &DATVUDPStream::fifoData, this, &DATVDemodGUI::on_StreamDataAvailable);
}
blockApplySettings(false);
}
@ -565,6 +583,12 @@ void DATVDemodGUI::tick()
ui->playerIndicator->setStyleSheet("QLabel { background-color: gray; border-radius: 8px; }");
}
if (m_objDATVDemod->udpRunning()) {
ui->udpIndicator->setStyleSheet("QLabel { background-color: rgb(85, 232, 85); border-radius: 8px; }"); // green
} else {
ui->udpIndicator->setStyleSheet("QLabel { background-color: gray; border-radius: 8px; }");
}
return;
}
@ -817,6 +841,24 @@ void DATVDemodGUI::on_StreamMetaDataChanged(DataTSMetaData2 *objMetaData)
}
}
void DATVDemodGUI::on_playerEnable_clicked()
{
m_settings.m_playerEnable = ui->playerEnable->isChecked();
if (m_settings.m_playerEnable)
{
disconnect(m_objDATVDemod->getUDPStream(), &DATVUDPStream::fifoData, this, &DATVDemodGUI::on_StreamDataAvailable);
connect(m_objDATVDemod->getVideoStream(), &DATVideostream::fifoData, this, &DATVDemodGUI::on_StreamDataAvailable);
}
else
{
disconnect(m_objDATVDemod->getVideoStream(), &DATVideostream::fifoData, this, &DATVDemodGUI::on_StreamDataAvailable);
connect(m_objDATVDemod->getUDPStream(), &DATVUDPStream::fifoData, this, &DATVDemodGUI::on_StreamDataAvailable);
}
applySettings();
}
void DATVDemodGUI::displayRRCParameters(bool blnVisible)
{
ui->spiRollOff->setVisible(blnVisible);

View File

@ -92,6 +92,7 @@ private slots:
void on_udpTS_clicked(bool checked);
void on_udpTSAddress_editingFinished();
void on_udpTSPort_editingFinished();
void on_playerEnable_clicked();
private:
Ui::DATVDemodGUI* ui;

View File

@ -785,7 +785,7 @@
<widget class="QLabel" name="playerIndicator">
<property name="geometry">
<rect>
<x>10</x>
<x>70</x>
<y>250</y>
<width>16</width>
<height>16</height>
@ -813,6 +813,25 @@
<string/>
</property>
</widget>
<widget class="QCheckBox" name="playerEnable">
<property name="geometry">
<rect>
<x>0</x>
<y>250</y>
<width>61</width>
<height>16</height>
</rect>
</property>
<property name="toolTip">
<string>Video player enable</string>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>Video</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget">
<property name="geometry">
@ -892,6 +911,31 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="udpIndicator">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="toolTip">
<string>UDP thread running indicator</string>
</property>
<property name="styleSheet">
<string notr="true">QLabel { background-color: gray; border-radius: 8px; }</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">

View File

@ -62,6 +62,7 @@ void DATVDemodSettings::resetToDefaults()
m_udpTSAddress = "127.0.0.1";
m_udpTSPort = 8882;
m_udpTS = false;
m_playerEnable = true;
m_streamIndex = 0;
m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1";
@ -111,6 +112,7 @@ QByteArray DATVDemodSettings::serialize() const
s.writeS32(33, m_maxBitflips);
s.writeString(34, m_softLDPCToolPath);
s.writeS32(35, m_softLDPCMaxTrials);
s.writeBool(36, m_playerEnable);
return s.final();
}
@ -198,6 +200,7 @@ bool DATVDemodSettings::deserialize(const QByteArray& data)
d.readString(34, &m_softLDPCToolPath, "/opt/install/sdrangel/bin/ldpctool");
d.readS32(35, &tmp, 8);
m_softLDPCMaxTrials = tmp < 1 ? 1 : tmp > m_softLDPCMaxMaxTrials ? m_softLDPCMaxMaxTrials : tmp;
d.readBool(36, &m_playerEnable, true);
validateSystemConfiguration();
@ -235,7 +238,11 @@ void DATVDemodSettings::debug(const QString& msg) const
<< " m_audioMute: " << m_audioMute
<< " m_audioDeviceName: " << m_audioDeviceName
<< " m_audioVolume: " << m_audioVolume
<< " m_videoMute: " << m_videoMute;
<< " m_videoMute: " << m_videoMute
<< " m_udpTS: " << m_udpTS
<< " m_udpTSAddress: " << m_udpTSAddress
<< " m_udpTSPort: " << m_udpTSPort
<< " m_playerEnable: " << m_playerEnable;
}
bool DATVDemodSettings::isDifferent(const DATVDemodSettings& other)
@ -255,7 +262,8 @@ bool DATVDemodSettings::isDifferent(const DATVDemodSettings& other)
|| (m_notchFilters != other.m_notchFilters)
|| (m_symbolRate != other.m_symbolRate)
|| (m_excursion != other.m_excursion)
|| (m_standard != other.m_standard));
|| (m_standard != other.m_standard)
|| (m_playerEnable != other.m_playerEnable));
}
void DATVDemodSettings::validateSystemConfiguration()

View File

@ -100,6 +100,7 @@ struct DATVDemodSettings
QString m_udpTSAddress;
quint32 m_udpTSPort;
bool m_udpTS;
bool m_playerEnable;
int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx).
bool m_useReverseAPI;
QString m_reverseAPIAddress;

View File

@ -155,6 +155,18 @@ bool DATVDemodSink::videoDecodeOK()
}
}
bool DATVDemodSink::udpRunning()
{
if (!r_videoplayer) {
return false;
}
bool udpRunning = r_videoplayer->isUDPRunning();
r_videoplayer->resetUDPRunning();
return udpRunning;
}
bool DATVDemodSink::playVideo()
{
QMutexLocker mlock(&m_mutex);
@ -565,6 +577,7 @@ void DATVDemodSink::InitDATVFramework()
m_objCfg.rrc_steps = 0; //auto
m_objVideoStream->resetTotalReceived();
m_udpStream.resetTotalReceived();
switch(m_settings.m_modulation)
{
@ -861,7 +874,11 @@ void DATVDemodSink::InitDATVFramework()
r_derand = new leansdr::derandomizer(m_objScheduler, *p_rtspackets, *p_tspackets);
// OUTPUT
r_videoplayer = new leansdr::datvvideoplayer<leansdr::tspacket>(m_objScheduler, *p_tspackets, m_objVideoStream, &m_udpStream);
if (m_settings.m_playerEnable) {
r_videoplayer = new leansdr::datvvideoplayer<leansdr::tspacket>(m_objScheduler, *p_tspackets, m_objVideoStream, &m_udpStream);
} else {
r_videoplayer = new leansdr::datvvideoplayer<leansdr::tspacket>(m_objScheduler, *p_tspackets, nullptr, &m_udpStream);
}
m_blnDVBInitialized = true;
}
@ -904,6 +921,7 @@ void DATVDemodSink::InitDATVS2Framework()
m_objCfg.rrc_steps = 0; //auto
m_objVideoStream->resetTotalReceived();
m_udpStream.resetTotalReceived();
switch(m_settings.m_modulation)
{
@ -1224,7 +1242,11 @@ void DATVDemodSink::InitDATVS2Framework()
*/
// OUTPUT
r_videoplayer = new leansdr::datvvideoplayer<leansdr::tspacket>(m_objScheduler, *p_tspackets, m_objVideoStream, &m_udpStream);
if (m_settings.m_playerEnable) {
r_videoplayer = new leansdr::datvvideoplayer<leansdr::tspacket>(m_objScheduler, *p_tspackets, m_objVideoStream, &m_udpStream);
} else {
r_videoplayer = new leansdr::datvvideoplayer<leansdr::tspacket>(m_objScheduler, *p_tspackets, nullptr, &m_udpStream);
}
m_blnDVBInitialized = true;
}

View File

@ -67,10 +67,12 @@ public:
void setCNRMeter(LevelMeterSignalDB *cnrMeter);
void SetVideoRender(DATVideoRender *objScreen);
DATVideostream *getVideoStream() { return m_objVideoStream; }
DATVUDPStream *getUDPStream() { return &m_udpStream; }
bool audioActive();
bool audioDecodeOK();
bool videoActive();
bool videoDecodeOK();
bool udpRunning();
bool playVideo();
void stopVideo();

View File

@ -26,7 +26,11 @@ DATVUDPStream::DATVUDPStream(int tsBlockSize) :
m_address(QHostAddress::LocalHost),
m_port(8882),
m_tsBlockSize(tsBlockSize),
m_tsBlockIndex(0)
m_tsBlockIndex(0),
m_dataBytes(0),
m_percentBuffer(0),
m_totalBytes(0),
m_fifoSignalCount(0)
{
m_tsBuffer = new char[m_tsBlocksPerFrame*m_tsBlockSize];
}
@ -45,15 +49,31 @@ void DATVUDPStream::pushData(const char *chrData, int nbTSBlocks)
for (int i = 0; i < nbTSBlocks; i++)
{
std::copy(chrData + i*m_tsBlockSize, chrData + (i+1)*m_tsBlockSize, m_tsBuffer + m_tsBlockIndex*m_tsBlockSize);
if (m_tsBlockIndex < m_tsBlocksPerFrame - 1)
if (m_tsBlockIndex < m_tsBlocksPerFrame - 1)
{
m_tsBlockIndex++;
}
else
{
m_udpSocket.writeDatagram(m_tsBuffer, m_tsBlocksPerFrame*m_tsBlockSize, m_address, m_port);
m_dataBytes += m_tsBlocksPerFrame*m_tsBlockSize;
m_totalBytes += m_tsBlocksPerFrame*m_tsBlockSize;
if (++m_fifoSignalCount == 10)
{
emit fifoData(&m_dataBytes, &m_percentBuffer, &m_totalBytes);
m_fifoSignalCount = 0;
}
m_dataBytes = 0;
m_tsBlockIndex = 0;
}
}
}
void DATVUDPStream::resetTotalReceived()
{
m_totalBytes = 0;
emit fifoData(&m_dataBytes, &m_percentBuffer, &m_totalBytes);
}

View File

@ -22,22 +22,27 @@
#include <QUdpSocket>
#include <QHostAddress>
#include <QString>
#include <QObject>
class QString;
class DATVUDPStream
class DATVUDPStream : public QObject
{
Q_OBJECT
public:
DATVUDPStream(int tsBlockSize);
~DATVUDPStream();
void pushData(const char *chrData, int nbTSBlocks);
void resetTotalReceived();
void setActive(bool active) { m_active = active; }
bool isActive() const { return m_active; }
bool setAddress(const QString& address) { return m_address.setAddress(address); }
void setPort(quint16 port) { m_port = port; }
static const int m_tsBlocksPerFrame;
signals:
void fifoData(int *dataBytes, int *percentBuffer, qint64 *totalReceived);
private:
bool m_active;
QUdpSocket m_udpSocket;
@ -46,6 +51,10 @@ private:
int m_tsBlockSize;
int m_tsBlockIndex;
char *m_tsBuffer;
int m_dataBytes;
int m_percentBuffer;
qint64 m_totalBytes;
int m_fifoSignalCount;
};
#endif // DATVUDPSTREAM_H
#endif // DATVUDPSTREAM_H

View File

@ -31,12 +31,13 @@ template<typename T> struct datvvideoplayer: runnable
datvvideoplayer(
scheduler *sch,
pipebuf<T> &_in,
DATVideostream *objVideoStream,
DATVideostream *videoStream,
DATVUDPStream *udpStream) :
runnable(sch, _in.name),
in(_in),
m_objVideoStream(objVideoStream),
m_udpStream(udpStream)
m_videoStream(videoStream),
m_udpStream(udpStream),
m_atomicUDPRunning(0)
{
}
@ -48,38 +49,53 @@ template<typename T> struct datvvideoplayer: runnable
return;
}
int nw;
m_udpStream->pushData((const char *) in.rd(), in.readable());
int nw = m_objVideoStream->pushData((const char *) in.rd(), size);
m_atomicUDPRunning.storeRelaxed(m_udpStream->isActive() && (size > 0) ? 1 : 0);
if (!nw)
if (m_videoStream)
{
fatal("leansdr::datvvideoplayer::run: pipe");
return;
}
nw = m_videoStream->pushData((const char *) in.rd(), size);
if (nw < 0)
if (!nw)
{
fatal("leansdr::datvvideoplayer::run: pipe");
return;
}
if (nw < 0)
{
fatal("leansdr::datvvideoplayer::run: write");
return;
}
if (nw % sizeof(T))
{
fatal("leansdr::datvvideoplayer::run: partial write");
return;
}
if (nw != size) {
fprintf(stderr, "leansdr::datvvideoplayer::run: nw: %d size: %d\n", nw, size);
}
}
else
{
fatal("leansdr::datvvideoplayer::run: write");
return;
}
if (nw % sizeof(T))
{
fatal("leansdr::datvvideoplayer::run: partial write");
return;
}
if (nw != size) {
fprintf(stderr, "leansdr::datvvideoplayer::run: nw: %d size: %d\n", nw, size);
nw = size;
}
in.read(nw / sizeof(T));
}
bool isUDPRunning() const { return m_atomicUDPRunning.loadRelaxed() == 1; }
void resetUDPRunning() { m_atomicUDPRunning.storeRelaxed(0); }
private:
pipereader<T> in;
DATVideostream *m_objVideoStream;
DATVideostream *m_videoStream;
DATVUDPStream *m_udpStream;
QAtomicInt m_atomicUDPRunning;
};
}

View File

@ -44,7 +44,7 @@ Power of signal received in the channel (dB)
This gauge gives the MER estimation. The averaged value appears on the right.
<h4>B.3: CNR estimation</h4>
<h4>B.4: CNR estimation</h4>
This gauge gives the CNR estimation. The averaged value appears on the right.
@ -60,6 +60,16 @@ This is the address of the TS UDP
This is the port of the TS UDP
<h4>B.8: UDP streaming indicator</h4>
Indicator turns green if UDP data is streaming to destination
<h4>B.9: Video player enable and indicator</h4>
Use the checkbox to enable or disable the internal video player. The indicator next turns green if the video player thread is active.
Use this control to disable the video player if it causes too many crashes...
<h4>B.1: Symbol constellation</h4>
This is the constellation of the PSK or QAM synchronized signal. When the demodulation parameters are set correctly (modulation type, symbol rate and filtering) and signal is strong enough to recover symbol synchronization the purple dots appear close to the white crosses. White crosses represent the ideal symbols positions in the I/Q plane.
@ -143,13 +153,15 @@ Push this button when you are lost...
<h5>B.2a.12: Amount of data decoded</h5>
Automatically adjusts unit (kB, MB, ...)
Amount data received in the video player. If the video player is disabled this is the amount of data sent via UDP. Automatically adjusts unit (kB, MB, ...)
<h5>B.2a.13: Stream speed</h5>
Current data flow in the video player. If the video player is disabled this is the flow sent via UDP.
<h5>B.2a.14: Buffer status</h5>
Gauge that shows percentage of buffer queue length
Gauge that shows percentage of video player buffer queue length
<h4>B.2b: DATV signal settings (DVB-S2 specific)</h4>