DATV demod: allow video player enable/disable

pull/841/head
f4exb 2021-04-11 23:52:16 +02:00
rodzic c5ece265e9
commit f8a512e91b
17 zmienionych plików z 219 dodań i 38 usunięć

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 60 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 62 KiB

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 52 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 55 KiB

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -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(); }

Wyświetl plik

@ -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(); }

Wyświetl plik

@ -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);

Wyświetl plik

@ -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;

Wyświetl plik

@ -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">

Wyświetl plik

@ -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()

Wyświetl plik

@ -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;

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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();

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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;
};
}

Wyświetl plik

@ -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>