mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-26 17:58:43 -05:00
DATV demod: added UDP transport stream output
This commit is contained in:
parent
1466883c38
commit
2f5b50d206
@ -7,6 +7,7 @@ set(datv_SOURCES
|
||||
datvdemodplugin.cpp
|
||||
datvdemodsettings.cpp
|
||||
datvideostream.cpp
|
||||
datvudpstream.cpp
|
||||
datvideorender.cpp
|
||||
leansdr/dvb.cpp
|
||||
leansdr/filtergen.cpp
|
||||
@ -23,6 +24,7 @@ set(datv_HEADERS
|
||||
datvdemodplugin.h
|
||||
datvdemodsettings.h
|
||||
datvideostream.h
|
||||
datvudpstream.h
|
||||
datvideorender.h
|
||||
datvconstellation.h
|
||||
datvdvbs2constellation.h
|
||||
|
@ -46,6 +46,7 @@ DATVDemod::DATVDemod(DeviceAPI *deviceAPI) :
|
||||
m_objRegisteredTVScreen(0),
|
||||
m_objRegisteredVideoRender(0),
|
||||
m_objVideoStream(nullptr),
|
||||
m_udpStream(leansdr::tspacket::SIZE),
|
||||
m_objRenderThread(nullptr),
|
||||
m_audioFifo(48000),
|
||||
m_blnRenderingVideo(false),
|
||||
@ -859,7 +860,7 @@ void DATVDemod::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);
|
||||
r_videoplayer = new leansdr::datvvideoplayer<leansdr::tspacket>(m_objScheduler, *p_tspackets, m_objVideoStream, &m_udpStream);
|
||||
|
||||
m_blnDVBInitialized = true;
|
||||
}
|
||||
@ -1144,7 +1145,7 @@ void DATVDemod::InitDATVS2Framework()
|
||||
//**********************************************
|
||||
|
||||
// OUTPUT
|
||||
r_videoplayer = new leansdr::datvvideoplayer<leansdr::tspacket>(m_objScheduler, *p_tspackets, m_objVideoStream);
|
||||
r_videoplayer = new leansdr::datvvideoplayer<leansdr::tspacket>(m_objScheduler, *p_tspackets, m_objVideoStream, &m_udpStream);
|
||||
|
||||
m_blnDVBInitialized = true;
|
||||
}
|
||||
@ -1358,29 +1359,31 @@ void DATVDemod::applyChannelSettings(int inputSampleRate, int inputFrequencyOffs
|
||||
<< " inputSampleRate: " << inputSampleRate
|
||||
<< " inputFrequencyOffset: " << inputFrequencyOffset;
|
||||
|
||||
bool callApplySettings = false;
|
||||
|
||||
if ((m_settings.m_centerFrequency != inputFrequencyOffset) ||
|
||||
(m_sampleRate != inputSampleRate) || force)
|
||||
{
|
||||
m_objNCO.setFreq(-(float) inputFrequencyOffset, (float) inputSampleRate);
|
||||
qDebug("DATVDemod::applyChannelSettings: NCO: IF: %d <> TF: %d ISR: %d",
|
||||
inputFrequencyOffset, m_settings.m_centerFrequency, inputSampleRate);
|
||||
callApplySettings = true;
|
||||
}
|
||||
|
||||
if ((m_sampleRate != inputSampleRate) || force)
|
||||
{
|
||||
//m_objSettingsMutex.lock();
|
||||
//Bandpass filter shaping
|
||||
Real fltLowCut = -((float) m_settings.m_rfBandwidth / 2.0) / (float) inputSampleRate;
|
||||
Real fltHiCut = ((float) m_settings.m_rfBandwidth / 2.0) / (float) inputSampleRate;
|
||||
m_objRFFilter->create_filter(fltLowCut, fltHiCut);
|
||||
//m_blnNeedConfigUpdate = true;
|
||||
//applySettings(m_settings,true);
|
||||
//m_objSettingsMutex.unlock();
|
||||
}
|
||||
|
||||
m_sampleRate = inputSampleRate;
|
||||
m_settings.m_centerFrequency = inputFrequencyOffset;
|
||||
applySettings(m_settings,true);
|
||||
|
||||
if (callApplySettings) {
|
||||
applySettings(m_settings, true);
|
||||
}
|
||||
}
|
||||
|
||||
void DATVDemod::applySettings(const DATVDemodSettings& settings, bool force)
|
||||
@ -1443,6 +1446,18 @@ void DATVDemod::applySettings(const DATVDemodSettings& settings, bool force)
|
||||
m_objNCO.setFreq(-(float) settings.m_centerFrequency, (float) m_sampleRate);
|
||||
}
|
||||
|
||||
if ((m_settings.m_udpTS != settings.m_udpTS) || force) {
|
||||
m_udpStream.setActive(settings.m_udpTS);
|
||||
}
|
||||
|
||||
if ((m_settings.m_udpTSAddress != settings.m_udpTSAddress) || force) {
|
||||
m_udpStream.setAddress(settings.m_udpTSAddress);
|
||||
}
|
||||
|
||||
if ((m_settings.m_udpTSPort != settings.m_udpTSPort) || force) {
|
||||
m_udpStream.setPort(settings.m_udpTSPort);
|
||||
}
|
||||
|
||||
if (m_settings.isDifferent(settings) || force)
|
||||
{
|
||||
m_blnNeedConfigUpdate = true;
|
||||
|
@ -39,6 +39,7 @@ class DownChannelizer;
|
||||
#include "datvdvbs2constellation.h"
|
||||
#include "datvvideoplayer.h"
|
||||
#include "datvideostream.h"
|
||||
#include "datvudpstream.h"
|
||||
#include "datvideorender.h"
|
||||
#include "datvdemodsettings.h"
|
||||
|
||||
@ -404,6 +405,7 @@ private:
|
||||
TVScreen *m_objRegisteredTVScreen;
|
||||
DATVideoRender *m_objRegisteredVideoRender;
|
||||
DATVideostream *m_objVideoStream;
|
||||
DATVUDPStream m_udpStream;
|
||||
DATVideoRenderThread *m_objRenderThread;
|
||||
|
||||
// Audio
|
||||
|
@ -243,6 +243,7 @@ void DATVDemodGUI::displaySettings()
|
||||
blockApplySettings(true);
|
||||
|
||||
m_objChannelMarker.setCenterFrequency(m_settings.m_centerFrequency);
|
||||
m_objChannelMarker.setBandwidth(m_settings.m_rfBandwidth);
|
||||
ui->deltaFrequency->setValue(m_settings.m_centerFrequency);
|
||||
m_objChannelMarker.setColor(m_settings.m_rgbColor);
|
||||
|
||||
@ -292,6 +293,9 @@ void DATVDemodGUI::displaySettings()
|
||||
ui->audioVolume->setValue(m_settings.m_audioVolume);
|
||||
ui->audioVolumeText->setText(tr("%1").arg(m_settings.m_audioVolume));
|
||||
ui->videoMute->setChecked(m_settings.m_videoMute);
|
||||
ui->udpTS->setChecked(m_settings.m_udpTS);
|
||||
ui->udpTSAddress->setText(m_settings.m_udpTSAddress);
|
||||
ui->udpTSPort->setText(tr("%1").arg(m_settings.m_udpTSPort));
|
||||
|
||||
blockApplySettings(false);
|
||||
m_objChannelMarker.blockSignals(false);
|
||||
@ -347,38 +351,12 @@ void DATVDemodGUI::applySettings(bool force)
|
||||
{
|
||||
qDebug("DATVDemodGUI::applySettings");
|
||||
|
||||
//Bandwidth and center frequency
|
||||
m_objChannelMarker.setCenterFrequency(ui->deltaFrequency->getValueNew());
|
||||
m_objChannelMarker.setBandwidth(ui->rfBandwidth->getValueNew());
|
||||
|
||||
DATVDemod::MsgConfigureChannelizer *msgChan = DATVDemod::MsgConfigureChannelizer::create(m_objChannelMarker.getCenterFrequency());
|
||||
m_objDATVDemod->getInputMessageQueue()->push(msgChan);
|
||||
|
||||
setTitleColor(m_objChannelMarker.getColor());
|
||||
|
||||
if (ui->cmbFilter->currentIndex() == 0) {
|
||||
m_settings.m_filter = DATVDemodSettings::SAMP_LINEAR;
|
||||
} else if (ui->cmbFilter->currentIndex() == 1) {
|
||||
m_settings.m_filter = DATVDemodSettings::SAMP_NEAREST;
|
||||
} else {
|
||||
m_settings.m_filter = DATVDemodSettings::SAMP_RRC;
|
||||
}
|
||||
|
||||
m_settings.m_rfBandwidth = m_objChannelMarker.getBandwidth();
|
||||
m_settings.m_centerFrequency = m_objChannelMarker.getCenterFrequency();
|
||||
m_settings.m_symbolRate = ui->spiSymbolRate->value();
|
||||
m_settings.m_notchFilters = ui->spiNotchFilters->value();
|
||||
m_settings.m_allowDrift = ui->chkAllowDrift->isChecked();
|
||||
m_settings.m_fastLock = ui->chkFastlock->isChecked();
|
||||
m_settings.m_hardMetric = ui->chkHardMetric->isChecked();
|
||||
m_settings.m_rollOff = ((float)ui->spiRollOff->value()) / 100.0f;
|
||||
m_settings.m_viterbi = ui->chkViterbi->isChecked();
|
||||
m_settings.m_excursion = ui->spiExcursion->value();
|
||||
m_settings.m_audioMute = ui->audioMute->isChecked();
|
||||
m_settings.m_audioVolume = ui->audioVolume->value();
|
||||
m_settings.m_videoMute = ui->videoMute->isChecked();
|
||||
|
||||
QString msg = tr("DATVDemodGUI::applySettings: force: %1").arg(force);
|
||||
QString msg = tr("DATVDemodGUI::applySettings: force: %1").arg(force ? "true" : "false");
|
||||
m_settings.debug(msg);
|
||||
|
||||
DATVDemod::MsgConfigureDATVDemod* message = DATVDemod::MsgConfigureDATVDemod::create(m_settings, force);
|
||||
@ -548,11 +526,13 @@ void DATVDemodGUI::on_cmbFEC_currentIndexChanged(const QString &arg1)
|
||||
|
||||
void DATVDemodGUI::on_chkViterbi_clicked()
|
||||
{
|
||||
m_settings.m_viterbi = ui->chkViterbi->isChecked();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void DATVDemodGUI::on_chkHardMetric_clicked()
|
||||
{
|
||||
m_settings.m_hardMetric = ui->chkHardMetric->isChecked();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
@ -561,21 +541,22 @@ void DATVDemodGUI::on_resetDefaults_clicked()
|
||||
resetToDefaults();
|
||||
}
|
||||
|
||||
void DATVDemodGUI::on_spiSymbolRate_valueChanged(int arg1)
|
||||
void DATVDemodGUI::on_spiSymbolRate_valueChanged(int value)
|
||||
{
|
||||
(void) arg1;
|
||||
m_settings.m_symbolRate = value;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void DATVDemodGUI::on_spiNotchFilters_valueChanged(int arg1)
|
||||
void DATVDemodGUI::on_spiNotchFilters_valueChanged(int value)
|
||||
{
|
||||
(void) arg1;
|
||||
m_settings.m_notchFilters = value;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void DATVDemodGUI::on_chkAllowDrift_clicked()
|
||||
{
|
||||
applySettings();
|
||||
m_settings.m_allowDrift = ui->chkAllowDrift->isChecked();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void DATVDemodGUI::on_fullScreen_clicked()
|
||||
@ -619,36 +600,46 @@ void DATVDemodGUI::on_StreamDataAvailable(int *intPackets, int *intBytes, int *i
|
||||
|
||||
void DATVDemodGUI::on_deltaFrequency_changed(qint64 value)
|
||||
{
|
||||
(void) value;
|
||||
m_objChannelMarker.setCenterFrequency(value);
|
||||
m_settings.m_centerFrequency = m_objChannelMarker.getCenterFrequency();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void DATVDemodGUI::on_rfBandwidth_changed(qint64 value)
|
||||
{
|
||||
(void) value;
|
||||
m_objChannelMarker.setBandwidth(value);
|
||||
m_settings.m_rfBandwidth = m_objChannelMarker.getBandwidth();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void DATVDemodGUI::on_chkFastlock_clicked()
|
||||
{
|
||||
m_settings.m_fastLock = ui->chkFastlock->isChecked();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void DATVDemodGUI::on_audioMute_toggled(bool checked)
|
||||
{
|
||||
(void) checked;
|
||||
m_settings.m_audioMute = checked;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void DATVDemodGUI::on_videoMute_toggled(bool checked)
|
||||
{
|
||||
(void) checked;
|
||||
m_settings.m_videoMute = checked;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void DATVDemodGUI::on_audioVolume_valueChanged(int value)
|
||||
{
|
||||
ui->audioVolumeText->setText(tr("%1").arg(value));
|
||||
m_settings.m_audioVolume = value;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void DATVDemodGUI::on_udpTS_clicked(bool checked)
|
||||
{
|
||||
m_settings.m_udpTS = checked;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
@ -669,7 +660,7 @@ void DATVDemodGUI::on_StreamMetaDataChanged(DataTSMetaData2 *objMetaData)
|
||||
objMetaData->CodecDescription.toStdString().c_str());
|
||||
}
|
||||
|
||||
ui->textEdit->setText(strMetaData);
|
||||
ui->streamInfo->setText(strMetaData);
|
||||
ui->chkData->setChecked(objMetaData->OK_Data);
|
||||
ui->chkTS->setChecked(objMetaData->OK_TransportStream);
|
||||
ui->chkVS->setChecked(objMetaData->OK_VideoStream);
|
||||
@ -691,19 +682,46 @@ void DATVDemodGUI::displayRRCParameters(bool blnVisible)
|
||||
|
||||
void DATVDemodGUI::on_cmbFilter_currentIndexChanged(int index)
|
||||
{
|
||||
(void) index;
|
||||
displayRRCParameters((ui->cmbFilter->currentIndex() == 2));
|
||||
if (index == 0) {
|
||||
m_settings.m_filter = DATVDemodSettings::SAMP_LINEAR;
|
||||
} else if (index == 1) {
|
||||
m_settings.m_filter = DATVDemodSettings::SAMP_NEAREST;
|
||||
} else {
|
||||
m_settings.m_filter = DATVDemodSettings::SAMP_RRC;
|
||||
}
|
||||
|
||||
displayRRCParameters(index == 2);
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void DATVDemodGUI::on_spiRollOff_valueChanged(int arg1)
|
||||
void DATVDemodGUI::on_spiRollOff_valueChanged(int value)
|
||||
{
|
||||
(void) arg1;
|
||||
m_settings.m_rollOff = ((float) value) / 100.0f;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void DATVDemodGUI::on_spiExcursion_valueChanged(int arg1)
|
||||
void DATVDemodGUI::on_spiExcursion_valueChanged(int value)
|
||||
{
|
||||
(void) arg1;
|
||||
m_settings.m_excursion = value;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void DATVDemodGUI::on_udpTSAddress_editingFinished()
|
||||
{
|
||||
m_settings.m_udpTSAddress = ui->udpTSAddress->text();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void DATVDemodGUI::on_udpTSPort_editingFinished()
|
||||
{
|
||||
bool ok;
|
||||
quint16 udpPort = ui->udpTSPort->text().toInt(&ok);
|
||||
|
||||
if((!ok) || (udpPort < 1024)) {
|
||||
udpPort = 8882;
|
||||
}
|
||||
|
||||
m_settings.m_udpTSPort = udpPort;
|
||||
ui->udpTSPort->setText(tr("%1").arg(udpPort));
|
||||
applySettings();
|
||||
}
|
@ -94,6 +94,9 @@ private slots:
|
||||
void on_audioMute_toggled(bool checked);
|
||||
void on_audioVolume_valueChanged(int value);
|
||||
void on_videoMute_toggled(bool checked);
|
||||
void on_udpTS_clicked(bool checked);
|
||||
void on_udpTSAddress_editingFinished();
|
||||
void on_udpTSPort_editingFinished();
|
||||
|
||||
private:
|
||||
Ui::DATVDemodGUI* ui;
|
||||
|
@ -732,6 +732,99 @@
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="horizontalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>260</y>
|
||||
<width>481</width>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="udpLayout">
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="udpTS">
|
||||
<property name="toolTip">
|
||||
<string>Copy transport stream to UDP</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>UDP</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="udpTSAddressLabel">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Addr</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="udpTSAddress">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>140</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Destination UDP address</string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>000.000.000.000</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>127.0.0.1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="udpTSPortLabel">
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="udpTSPort">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Destination UDP port</string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>00000</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>9998</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="videoTab">
|
||||
<attribute name="title">
|
||||
@ -752,7 +845,7 @@
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<widget class="QTextEdit" name="streamInfo">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>2</x>
|
||||
@ -1030,6 +1123,11 @@
|
||||
<header>gui/tvscreen.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ButtonSwitch</class>
|
||||
<extends>QToolButton</extends>
|
||||
<header>gui/buttonswitch.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../../sdrgui/resources/res.qrc"/>
|
||||
|
@ -28,7 +28,7 @@
|
||||
const PluginDescriptor DATVDemodPlugin::m_ptrPluginDescriptor =
|
||||
{
|
||||
QString("DATV Demodulator"),
|
||||
QString("4.11.3"),
|
||||
QString("4.11.4"),
|
||||
QString("(c) F4HKW for SDRAngel using LeanSDR framework (c) F4DAV"),
|
||||
QString("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -52,6 +52,9 @@ void DATVDemodSettings::resetToDefaults()
|
||||
m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName;
|
||||
m_audioVolume = 0;
|
||||
m_videoMute = false;
|
||||
m_udpTSAddress = "127.0.0.1";
|
||||
m_udpTSPort = 8882;
|
||||
m_udpTS = false;
|
||||
}
|
||||
|
||||
QByteArray DATVDemodSettings::serialize() const
|
||||
@ -82,6 +85,9 @@ QByteArray DATVDemodSettings::serialize() const
|
||||
s.writeString(20, m_audioDeviceName);
|
||||
s.writeS32(21, m_audioVolume);
|
||||
s.writeBool(22, m_videoMute);
|
||||
s.writeString(23, m_udpTSAddress);
|
||||
s.writeU32(24, m_udpTSPort);
|
||||
s.writeBool(25, m_udpTS);
|
||||
|
||||
return s.final();
|
||||
}
|
||||
@ -100,6 +106,7 @@ bool DATVDemodSettings::deserialize(const QByteArray& data)
|
||||
{
|
||||
QByteArray bytetmp;
|
||||
qint32 tmp;
|
||||
quint32 utmp;
|
||||
QString strtmp;
|
||||
|
||||
d.readS32(2, &m_rfBandwidth, 512000);
|
||||
@ -143,6 +150,10 @@ bool DATVDemodSettings::deserialize(const QByteArray& data)
|
||||
d.readString(20, &m_audioDeviceName, AudioDeviceManager::m_defaultDeviceName);
|
||||
d.readS32(21, &m_audioVolume, 0);
|
||||
d.readBool(22, &m_videoMute, false);
|
||||
d.readString(23, &m_udpTSAddress, "127.0.0.1");
|
||||
d.readU32(24, &utmp, 8882);
|
||||
m_udpTSPort = utmp < 1024 ? 1024 : utmp > 65536 ? 65535 : utmp;
|
||||
d.readBool(25, &m_udpTS, false);
|
||||
|
||||
validateSystemConfiguration();
|
||||
|
||||
|
@ -93,6 +93,9 @@ struct DATVDemodSettings
|
||||
int m_excursion;
|
||||
int m_audioVolume;
|
||||
bool m_videoMute;
|
||||
QString m_udpTSAddress;
|
||||
quint32 m_udpTSPort;
|
||||
bool m_udpTS;
|
||||
|
||||
DATVDemodSettings();
|
||||
void resetToDefaults();
|
||||
|
@ -208,7 +208,7 @@ bool DATVideoRender::PreprocessStream()
|
||||
{
|
||||
avformat_close_input(&m_formatCtx);
|
||||
m_formatCtx = nullptr;
|
||||
qDebug() << "DATVideoProcess::PreprocessStream cannot find stream info";
|
||||
qDebug() << "DATVideoRender::PreprocessStream cannot find stream info";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -218,7 +218,7 @@ bool DATVideoRender::PreprocessStream()
|
||||
if (intRet < 0)
|
||||
{
|
||||
avformat_close_input(&m_formatCtx);
|
||||
qDebug() << "DATVideoProcess::PreprocessStream cannot find video stream";
|
||||
qDebug() << "DATVideoRender::PreprocessStream cannot find video stream";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -229,7 +229,7 @@ bool DATVideoRender::PreprocessStream()
|
||||
|
||||
if (intRet < 0)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::PreprocessStream cannot find audio stream";
|
||||
qDebug() << "DATVideoRender::PreprocessStream cannot find audio stream";
|
||||
}
|
||||
|
||||
m_audioStreamIndex = intRet;
|
||||
@ -285,12 +285,12 @@ bool DATVideoRender::PreprocessStream()
|
||||
avformat_close_input(&m_formatCtx);
|
||||
m_formatCtx = nullptr;
|
||||
|
||||
qDebug() << "DATVideoProcess::PreprocessStream cannot find associated video CODEC";
|
||||
qDebug() << "DATVideoRender::PreprocessStream cannot find associated video CODEC";
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "DATVideoProcess::PreprocessStream: video CODEC found: " << videoCodec->name;
|
||||
qDebug() << "DATVideoRender::PreprocessStream: video CODEC found: " << videoCodec->name;
|
||||
}
|
||||
|
||||
av_dict_set(&opts, "refcounted_frames", "1", 0);
|
||||
@ -300,7 +300,7 @@ bool DATVideoRender::PreprocessStream()
|
||||
avformat_close_input(&m_formatCtx);
|
||||
m_formatCtx = nullptr;
|
||||
|
||||
qDebug() << "DATVideoProcess::PreprocessStream cannot open associated video CODEC";
|
||||
qDebug() << "DATVideoRender::PreprocessStream cannot open associated video CODEC";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -312,7 +312,7 @@ bool DATVideoRender::PreprocessStream()
|
||||
avformat_close_input(&m_formatCtx);
|
||||
m_formatCtx = nullptr;
|
||||
|
||||
qDebug() << "DATVideoProcess::PreprocessStream cannot allocate frame";
|
||||
qDebug() << "DATVideoRender::PreprocessStream cannot allocate frame";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -336,12 +336,12 @@ bool DATVideoRender::PreprocessStream()
|
||||
avcodec_free_context(&m_audioDecoderCtx);
|
||||
}
|
||||
|
||||
m_audioDecoderCtx = avcodec_alloc_context3(NULL);
|
||||
m_audioDecoderCtx = avcodec_alloc_context3(nullptr);
|
||||
avcodec_parameters_to_context(m_audioDecoderCtx, parms);
|
||||
|
||||
//m_audioDecoderCtx = m_formatCtx->streams[m_audioStreamIndex]->codec; // old style
|
||||
|
||||
qDebug() << "DATVideoProcess::PreprocessStream: audio: "
|
||||
qDebug() << "DATVideoRender::PreprocessStream: audio: "
|
||||
<< " channels: " << m_audioDecoderCtx->channels
|
||||
<< " channel_layout: " << m_audioDecoderCtx->channel_layout
|
||||
<< " sample_rate: " << m_audioDecoderCtx->sample_rate
|
||||
@ -352,16 +352,16 @@ bool DATVideoRender::PreprocessStream()
|
||||
|
||||
if (audioCodec == nullptr)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::PreprocessStream cannot find associated audio CODEC";
|
||||
qDebug() << "DATVideoRender::PreprocessStream cannot find associated audio CODEC";
|
||||
m_audioStreamIndex = -1; // invalidate audio
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "DATVideoProcess::PreprocessStream: audio CODEC found: " << audioCodec->name;
|
||||
qDebug() << "DATVideoRender::PreprocessStream: audio CODEC found: " << audioCodec->name;
|
||||
|
||||
if (avcodec_open2(m_audioDecoderCtx, audioCodec, nullptr) < 0)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::PreprocessStream cannot open associated audio CODEC";
|
||||
qDebug() << "DATVideoRender::PreprocessStream cannot open associated audio CODEC";
|
||||
m_audioStreamIndex = -1; // invalidate audio
|
||||
}
|
||||
else
|
||||
@ -388,19 +388,19 @@ bool DATVideoRender::OpenStream(DATVideostream *device)
|
||||
|
||||
if (device == nullptr)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::OpenStream QIODevice is nullptr";
|
||||
qDebug() << "DATVideoRender::OpenStream QIODevice is nullptr";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_isOpen)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::OpenStream already open";
|
||||
qDebug() << "DATVideoRender::OpenStream already open";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (device->bytesAvailable() <= 0)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::OpenStream no data available";
|
||||
qDebug() << "DATVideoRender::OpenStream no data available";
|
||||
MetaData.OK_Data = false;
|
||||
emit onMetaDataChanged(&MetaData);
|
||||
return false;
|
||||
@ -416,14 +416,14 @@ bool DATVideoRender::OpenStream(DATVideostream *device)
|
||||
|
||||
if (!m_isFFMPEGInitialized)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::OpenStream FFMPEG not initialized";
|
||||
qDebug() << "DATVideoRender::OpenStream FFMPEG not initialized";
|
||||
m_running = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!device->open(QIODevice::ReadOnly))
|
||||
{
|
||||
qDebug() << "DATVideoProcess::OpenStream cannot open QIODevice";
|
||||
qDebug() << "DATVideoRender::OpenStream cannot open QIODevice";
|
||||
m_running = false;
|
||||
return false;
|
||||
}
|
||||
@ -434,7 +434,7 @@ bool DATVideoRender::OpenStream(DATVideostream *device)
|
||||
|
||||
if (m_formatCtx == nullptr)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::OpenStream cannot alloc format FFMPEG context";
|
||||
qDebug() << "DATVideoRender::OpenStream cannot alloc format FFMPEG context";
|
||||
m_running = false;
|
||||
return false;
|
||||
}
|
||||
@ -454,7 +454,7 @@ bool DATVideoRender::OpenStream(DATVideostream *device)
|
||||
|
||||
if (avformat_open_input(&m_formatCtx, nullptr, nullptr, nullptr) < 0)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::OpenStream cannot open stream";
|
||||
qDebug() << "DATVideoRender::OpenStream cannot open stream";
|
||||
m_running = false;
|
||||
return false;
|
||||
}
|
||||
@ -479,7 +479,7 @@ bool DATVideoRender::RenderStream()
|
||||
|
||||
if (!m_isOpen)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::RenderStream Stream not open";
|
||||
qDebug() << "DATVideoRender::RenderStream Stream not open";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -495,7 +495,7 @@ bool DATVideoRender::RenderStream()
|
||||
|
||||
if (av_read_frame(m_formatCtx, &packet) < 0)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::RenderStream reading packet error";
|
||||
qDebug() << "DATVideoRender::RenderStream reading packet error";
|
||||
m_running = false;
|
||||
return false;
|
||||
}
|
||||
@ -546,7 +546,7 @@ bool DATVideoRender::RenderStream()
|
||||
|
||||
if (sws_init_context(m_swsCtx, nullptr, nullptr) < 0)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::RenderStream cannont init video data converter";
|
||||
qDebug() << "DATVideoRender::RenderStream cannont init video data converter";
|
||||
m_swsCtx = nullptr;
|
||||
m_running = false;
|
||||
return false;
|
||||
@ -560,7 +560,7 @@ bool DATVideoRender::RenderStream()
|
||||
|
||||
if (av_image_alloc(m_pbytDecodedData, m_pintDecodedLineSize, m_frame->width, m_frame->height, AV_PIX_FMT_RGB24, 1) < 0)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::RenderStream cannont init video image buffer";
|
||||
qDebug() << "DATVideoRender::RenderStream cannont init video image buffer";
|
||||
sws_freeContext(m_swsCtx);
|
||||
m_swsCtx = nullptr;
|
||||
m_running = false;
|
||||
@ -586,7 +586,7 @@ bool DATVideoRender::RenderStream()
|
||||
|
||||
if (sws_scale(m_swsCtx, m_frame->data, m_frame->linesize, 0, m_frame->height, m_pbytDecodedData, m_pintDecodedLineSize) < 0)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::RenderStream error converting video frame to RGB";
|
||||
qDebug() << "DATVideoRender::RenderStream error converting video frame to RGB";
|
||||
m_running = false;
|
||||
return false;
|
||||
}
|
||||
@ -599,7 +599,7 @@ bool DATVideoRender::RenderStream()
|
||||
else
|
||||
{
|
||||
m_videoDecodeOK = false;
|
||||
// qDebug() << "DATVideoProcess::RenderStream video decode error";
|
||||
// qDebug() << "DATVideoRender::RenderStream video decode error";
|
||||
}
|
||||
}
|
||||
// Audio channel
|
||||
@ -722,19 +722,19 @@ bool DATVideoRender::CloseStream(QIODevice *device)
|
||||
|
||||
if (!device)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::CloseStream QIODevice is nullptr";
|
||||
qDebug() << "DATVideoRender::CloseStream QIODevice is nullptr";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_isOpen)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::CloseStream Stream not open";
|
||||
qDebug() << "DATVideoRender::CloseStream Stream not open";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_formatCtx)
|
||||
{
|
||||
qDebug() << "DATVideoProcess::CloseStream FFMEG Context is not initialized";
|
||||
qDebug() << "DATVideoRender::CloseStream FFMEG Context is not initialized";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
58
plugins/channelrx/demoddatv/datvudpstream.cpp
Normal file
58
plugins/channelrx/demoddatv/datvudpstream.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2019 F4EXB //
|
||||
// written by Edouard Griffiths //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <algorithm>
|
||||
#include "datvudpstream.h"
|
||||
|
||||
const int DATVUDPStream::m_tsBlocksPerFrame = 7; // The usual value
|
||||
|
||||
DATVUDPStream::DATVUDPStream(int tsBlockSize) :
|
||||
m_active(false),
|
||||
m_address(QHostAddress::LocalHost),
|
||||
m_port(8882),
|
||||
m_tsBlockSize(tsBlockSize),
|
||||
m_tsBlockIndex(0)
|
||||
{
|
||||
m_tsBuffer = new char[m_tsBlocksPerFrame*m_tsBlockSize];
|
||||
}
|
||||
|
||||
DATVUDPStream::~DATVUDPStream()
|
||||
{
|
||||
delete[] m_tsBuffer;
|
||||
}
|
||||
|
||||
void DATVUDPStream::pushData(const char *chrData, int nbTSBlocks)
|
||||
{
|
||||
if (!m_active) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nbTSBlocks; i++)
|
||||
{
|
||||
if (m_tsBlockIndex < m_tsBlocksPerFrame)
|
||||
{
|
||||
std::copy(chrData + i*m_tsBlockSize, chrData + (i+1)*m_tsBlockSize, m_tsBuffer + m_tsBlockIndex*m_tsBlockSize);
|
||||
m_tsBlockIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_udpSocket.writeDatagram(m_tsBuffer, m_tsBlocksPerFrame*m_tsBlockSize, m_address, m_port);
|
||||
m_tsBlockIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
51
plugins/channelrx/demoddatv/datvudpstream.h
Normal file
51
plugins/channelrx/demoddatv/datvudpstream.h
Normal file
@ -0,0 +1,51 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2019 F4EXB //
|
||||
// written by Edouard Griffiths //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef DATVUDPSTREAM_H
|
||||
#define DATVUDPSTREAM_H
|
||||
|
||||
#include <QUdpSocket>
|
||||
#include <QHostAddress>
|
||||
#include <QString>
|
||||
|
||||
class QString;
|
||||
|
||||
class DATVUDPStream
|
||||
{
|
||||
public:
|
||||
DATVUDPStream(int tsBlockSize);
|
||||
~DATVUDPStream();
|
||||
|
||||
void pushData(const char *chrData, int nbTSBlocks);
|
||||
void setActive(bool active) { m_active = active; }
|
||||
bool setAddress(const QString& address) { return m_address.setAddress(address); }
|
||||
void setPort(quint16 port) { m_port = port; }
|
||||
|
||||
static const int m_tsBlocksPerFrame;
|
||||
|
||||
private:
|
||||
bool m_active;
|
||||
QUdpSocket m_udpSocket;
|
||||
QHostAddress m_address;
|
||||
quint16 m_port;
|
||||
int m_tsBlockSize;
|
||||
int m_tsBlockIndex;
|
||||
char *m_tsBuffer;
|
||||
};
|
||||
|
||||
#endif // DATVUDPSTREAM_H
|
@ -21,14 +21,22 @@
|
||||
|
||||
#include "leansdr/framework.h"
|
||||
#include "datvideostream.h"
|
||||
#include "datvudpstream.h"
|
||||
|
||||
namespace leansdr
|
||||
{
|
||||
|
||||
template<typename T> struct datvvideoplayer: runnable
|
||||
{
|
||||
datvvideoplayer(scheduler *sch, pipebuf<T> &_in, DATVideostream * objVideoStream) :
|
||||
runnable(sch, _in.name), in(_in), m_objVideoStream(objVideoStream)
|
||||
datvvideoplayer(
|
||||
scheduler *sch,
|
||||
pipebuf<T> &_in,
|
||||
DATVideostream *objVideoStream,
|
||||
DATVUDPStream *udpStream) :
|
||||
runnable(sch, _in.name),
|
||||
in(_in),
|
||||
m_objVideoStream(objVideoStream),
|
||||
m_udpStream(udpStream)
|
||||
{
|
||||
}
|
||||
|
||||
@ -40,6 +48,7 @@ template<typename T> struct datvvideoplayer: runnable
|
||||
return;
|
||||
}
|
||||
|
||||
m_udpStream->pushData((const char *) in.rd(), in.readable());
|
||||
int nw = m_objVideoStream->pushData((const char *) in.rd(), size);
|
||||
|
||||
if (!nw)
|
||||
@ -60,12 +69,17 @@ template<typename T> struct datvvideoplayer: runnable
|
||||
return;
|
||||
}
|
||||
|
||||
if (nw != size) {
|
||||
fprintf(stderr, "leansdr::datvvideoplayer::run: nw: %d size: %d\n", nw, size);
|
||||
}
|
||||
|
||||
in.read(nw / sizeof(T));
|
||||
}
|
||||
|
||||
private:
|
||||
pipereader<T> in;
|
||||
DATVideostream * m_objVideoStream;
|
||||
DATVideostream *m_objVideoStream;
|
||||
DATVUDPStream *m_udpStream;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user