DATV demod: added UDP transport stream output

This commit is contained in:
f4exb 2019-07-28 10:54:04 +02:00
parent 1466883c38
commit 2f5b50d206
13 changed files with 358 additions and 83 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View 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

View File

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