mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-30 12:30:20 -04: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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user