1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-09-28 07:46:37 -04:00

DATV: fixes to improve stability (1)

This commit is contained in:
f4exb 2021-03-28 18:40:43 +02:00
parent e3e8249987
commit 29506a1d65
8 changed files with 134 additions and 46 deletions

View File

@ -66,10 +66,12 @@ public:
return m_settings.m_centerFrequency; return m_settings.m_centerFrequency;
} }
void setMessageQueueToGUI(MessageQueue* queue) override { void setMessageQueueToGUI(MessageQueue* queue) override
{
ChannelAPI::setMessageQueueToGUI(queue); ChannelAPI::setMessageQueueToGUI(queue);
m_basebandSink->setMessageQueueToGUI(queue); m_basebandSink->setMessageQueueToGUI(queue);
} }
void SetTVScreen(TVScreen *objScreen) { m_basebandSink->setTVScreen(objScreen); } void SetTVScreen(TVScreen *objScreen) { m_basebandSink->setTVScreen(objScreen); }
void setMERLabel(QLabel *merLabel) { m_basebandSink->setMERLabel(merLabel); } void setMERLabel(QLabel *merLabel) { m_basebandSink->setMERLabel(merLabel); }
void setCNRLabel(QLabel *cnrLabel) { m_basebandSink->setCNRLabel(cnrLabel); } void setCNRLabel(QLabel *cnrLabel) { m_basebandSink->setCNRLabel(cnrLabel); }

View File

@ -261,6 +261,7 @@ DATVDemodGUI::DATVDemodGUI(PluginAPI* objPluginAPI, DeviceUISet *deviceUISet, Ba
ui->softLDPC->setStyleSheet("QCheckBox { color: gray }"); ui->softLDPC->setStyleSheet("QCheckBox { color: gray }");
#endif #endif
ui->playerIndicator->setStyleSheet("QLabel { background-color: gray; border-radius: 8px; }");
resetToDefaults(); // does applySettings() resetToDefaults(); // does applySettings()
} }
@ -547,7 +548,13 @@ void DATVDemodGUI::tick()
m_intPreviousDecodedData = m_intLastDecodedData; m_intPreviousDecodedData = m_intLastDecodedData;
//Try to start video rendering //Try to start video rendering
m_objDATVDemod->playVideo(); bool success = m_objDATVDemod->playVideo();
if (success) {
ui->playerIndicator->setStyleSheet("QLabel { background-color: rgb(85, 232, 85); border-radius: 8px; }"); // green
} else {
ui->playerIndicator->setStyleSheet("QLabel { background-color: gray; border-radius: 8px; }");
}
return; return;
} }

View File

@ -779,6 +779,37 @@
</property> </property>
</widget> </widget>
</widget> </widget>
<widget class="QLabel" name="playerIndicator">
<property name="geometry">
<rect>
<x>10</x>
<y>250</y>
<width>16</width>
<height>16</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="toolTip">
<string>Player thread running indicator</string>
</property>
<property name="styleSheet">
<string notr="true">QLabel { background-color: gray; border-radius: 8px; }</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</widget> </widget>
<widget class="QWidget" name="horizontalLayoutWidget"> <widget class="QWidget" name="horizontalLayoutWidget">
<property name="geometry"> <property name="geometry">
@ -911,7 +942,7 @@
</font> </font>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>SNR estimation</string> <string>MER estimation</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -971,7 +1002,7 @@
</font> </font>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>SNR estimation</string> <string>CNR estimation</string>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -176,11 +176,12 @@ bool DATVDemodSink::playVideo()
{ {
m_objRenderThread->setStreamAndRenderer(m_objRegisteredVideoRender, m_objVideoStream); m_objRenderThread->setStreamAndRenderer(m_objRegisteredVideoRender, m_objVideoStream);
m_objVideoStream->MultiThreaded = true; m_objVideoStream->MultiThreaded = true;
m_objVideoStream->ThreadTimeOut = 5000; //5000 ms m_objVideoStream->ThreadTimeOut = DATVideoRenderThread::videoThreadTimeoutMs;
m_objRenderThread->start(); m_objRenderThread->start();
return true;
} }
return true; return false;
} }
void DATVDemodSink::CleanUpDATVFramework() void DATVDemodSink::CleanUpDATVFramework()
@ -1013,29 +1014,29 @@ void DATVDemodSink::InitDATVS2Framework()
switch (m_objCfg.sampler) switch (m_objCfg.sampler)
{ {
case DATVDemodSettings::SAMP_NEAREST: case DATVDemodSettings::SAMP_NEAREST:
sampler = new leansdr::nearest_sampler<float>(); sampler = new leansdr::nearest_sampler<float>();
break; break;
case DATVDemodSettings::SAMP_LINEAR: case DATVDemodSettings::SAMP_LINEAR:
sampler = new leansdr::linear_sampler<float>(); sampler = new leansdr::linear_sampler<float>();
break; break;
case DATVDemodSettings::SAMP_RRC: case DATVDemodSettings::SAMP_RRC:
{ {
if (m_objCfg.rrc_steps == 0) if (m_objCfg.rrc_steps == 0)
{ {
// At least 64 discrete sampling points between symbols // At least 64 discrete sampling points between symbols
m_objCfg.rrc_steps = std::max(1, (int)(64*m_objCfg.Fm / m_objCfg.Fs)); m_objCfg.rrc_steps = std::max(1, (int)(64*m_objCfg.Fm / m_objCfg.Fs));
} }
float Frrc = m_objCfg.Fs * m_objCfg.rrc_steps; // Sample freq of the RRC filter float Frrc = m_objCfg.Fs * m_objCfg.rrc_steps; // Sample freq of the RRC filter
float transition = (m_objCfg.Fm/2) * m_objCfg.rolloff; float transition = (m_objCfg.Fm/2) * m_objCfg.rolloff;
int order = m_objCfg.rrc_rej * Frrc / (22*transition); int order = m_objCfg.rrc_rej * Frrc / (22*transition);
ncoeffs_sampler = leansdr::filtergen::root_raised_cosine(order, m_objCfg.Fm/Frrc, m_objCfg.rolloff, &coeffs_sampler); ncoeffs_sampler = leansdr::filtergen::root_raised_cosine(order, m_objCfg.Fm/Frrc, m_objCfg.rolloff, &coeffs_sampler);
sampler = new leansdr::fir_sampler<float,float>(ncoeffs_sampler, coeffs_sampler, m_objCfg.rrc_steps); sampler = new leansdr::fir_sampler<float,float>(ncoeffs_sampler, coeffs_sampler, m_objCfg.rrc_steps);
break; break;
} }
default: default:
qCritical("DATVDemodSink::InitDATVS2Framework: Interpolator not implemented"); qCritical("DATVDemodSink::InitDATVS2Framework: Interpolator not implemented");
return; return;
} }
p_slots_dvbs2 = new leansdr::pipebuf< leansdr::plslot<leansdr::llr_ss> > (m_objScheduler, "PL slots", BUF_SLOTS); p_slots_dvbs2 = new leansdr::pipebuf< leansdr::plslot<leansdr::llr_ss> > (m_objScheduler, "PL slots", BUF_SLOTS);
@ -1268,7 +1269,7 @@ void DATVDemodSink::feed(const SampleVector::const_iterator& begin, const Sample
if (m_blnNeedConfigUpdate) if (m_blnNeedConfigUpdate)
{ {
qDebug("DATVDemodSink::feed: Settings applied. Standard : %d...", m_settings.m_standard); qDebug("DATVDemodSink::feed: Settings applied. Standard : %d...", m_settings.m_standard);
m_blnNeedConfigUpdate=false; m_blnNeedConfigUpdate = false;
if(m_settings.m_standard==DATVDemodSettings::DVB_S2) if(m_settings.m_standard==DATVDemodSettings::DVB_S2)
{ {
@ -1297,8 +1298,8 @@ void DATVDemodSink::feed(const SampleVector::const_iterator& begin, const Sample
objRF ++; objRF ++;
if (m_blnDVBInitialized if (m_blnDVBInitialized
&& (p_rawiq_writer!=nullptr) && (p_rawiq_writer!=nullptr)
&& (m_objScheduler!=nullptr)) && (m_objScheduler!=nullptr))
{ {
p_rawiq_writer->write(objIQ); p_rawiq_writer->write(objIQ);
m_lngReadIQ++; m_lngReadIQ++;
@ -1321,7 +1322,7 @@ void DATVDemodSink::feed(const SampleVector::const_iterator& begin, const Sample
} // Samples for loop } // Samples for loop
// DVBS2: Track change of constellation via MODCOD // DVBS2: Track change of constellation via MODCOD
if (m_settings.m_standard==DATVDemodSettings::DVB_S2) if (m_settings.m_standard == DATVDemodSettings::DVB_S2)
{ {
leansdr::s2_frame_receiver<leansdr::f32, leansdr::llr_ss> * objDemodulatorDVBS2 = (leansdr::s2_frame_receiver<leansdr::f32, leansdr::llr_ss> *) m_objDemodulatorDVBS2; leansdr::s2_frame_receiver<leansdr::f32, leansdr::llr_ss> * objDemodulatorDVBS2 = (leansdr::s2_frame_receiver<leansdr::f32, leansdr::llr_ss> *) m_objDemodulatorDVBS2;
@ -1342,6 +1343,22 @@ void DATVDemodSink::feed(const SampleVector::const_iterator& begin, const Sample
getMessageQueueToGUI()->push(msg); getMessageQueueToGUI()->push(msg);
} }
if (
(
(m_modcodModulation != objDemodulatorDVBS2->m_modcodType) &&
(m_modcodModulation >= 0) &&
(objDemodulatorDVBS2->m_modcodType >= 0)
) ||
(
(m_modcodCodeRate != objDemodulatorDVBS2->m_modcodRate) &&
(m_modcodCodeRate >= 0) &&
(objDemodulatorDVBS2->m_modcodRate >= 0)
)
)
{
m_blnNeedConfigUpdate = true;
}
} }
m_cstlnSetByModcod = objDemodulatorDVBS2->cstln->m_setByModcod; m_cstlnSetByModcod = objDemodulatorDVBS2->cstln->m_setByModcod;

View File

@ -29,8 +29,10 @@ namespace leansdr {
static const int DEFAULT_GUI_DVBS2_DECIMATION = 64; static const int DEFAULT_GUI_DVBS2_DECIMATION = 64;
static inline cstln_lut<llr_ss, 256> * make_dvbs2_constellation(cstln_lut<llr_ss, 256>::predef c, static inline cstln_lut<llr_ss, 256> * make_dvbs2_constellation(
code_rate r) cstln_lut<llr_ss, 256>::predef c,
code_rate r
)
{ {
float gamma1 = 1, gamma2 = 1, gamma3 = 1; float gamma1 = 1, gamma2 = 1, gamma3 = 1;
@ -104,8 +106,8 @@ static inline cstln_lut<llr_ss, 256> * make_dvbs2_constellation(cstln_lut<llr_ss
} }
cstln_lut<llr_ss, 256> *newCstln = new cstln_lut<llr_ss, 256>(c, 10, gamma1, gamma2, gamma3); cstln_lut<llr_ss, 256> *newCstln = new cstln_lut<llr_ss, 256>(c, 10, gamma1, gamma2, gamma3);
newCstln->m_rateCode = (int) r; newCstln->m_rateCode = r < code_rate::FEC_COUNT ? r : -1;
newCstln->m_typeCode = (int) c; newCstln->m_typeCode = c < cstln_lut<llr_ss, 256>::predef::COUNT ? c : -1;
newCstln->m_setByModcod = false; newCstln->m_setByModcod = false;
return newCstln; return newCstln;
} }

View File

@ -29,7 +29,8 @@ extern "C"
#include "audio/audiofifo.h" #include "audio/audiofifo.h"
#include "datvideorender.h" #include "datvideorender.h"
DATVideoRender::DATVideoRender(QWidget *parent) : TVScreen(true, parent), m_parentWidget(parent) DATVideoRender::DATVideoRender(QWidget *parent) :
TVScreen(true, parent), m_parentWidget(parent)
{ {
installEventFilter(this); installEventFilter(this);
m_isFullScreen = false; m_isFullScreen = false;
@ -229,7 +230,7 @@ bool DATVideoRender::PreprocessStream()
avcodec_free_context(&m_videoDecoderCtx); avcodec_free_context(&m_videoDecoderCtx);
} }
m_videoDecoderCtx = avcodec_alloc_context3(NULL); m_videoDecoderCtx = avcodec_alloc_context3(nullptr);
avcodec_parameters_to_context(m_videoDecoderCtx, parms); avcodec_parameters_to_context(m_videoDecoderCtx, parms);
// m_videoDecoderCtx = m_formatCtx->streams[m_videoStreamIndex]->codec; // old style // m_videoDecoderCtx = m_formatCtx->streams[m_videoStreamIndex]->codec; // old style
@ -311,6 +312,10 @@ bool DATVideoRender::PreprocessStream()
m_metaData.CodecDescription = QString("%1").arg(videoCodec->long_name); m_metaData.CodecDescription = QString("%1").arg(videoCodec->long_name);
m_metaData.OK_VideoStream = true; m_metaData.OK_VideoStream = true;
QString metaStr;
m_metaData.formatString(metaStr);
qDebug() << "DATVideoRender::PreprocessStream: video: " << metaStr;
emit onMetaDataChanged(new DataTSMetaData2(m_metaData)); emit onMetaDataChanged(new DataTSMetaData2(m_metaData));
// Prepare Audio Codec // Prepare Audio Codec
@ -704,6 +709,13 @@ bool DATVideoRender::CloseStream(QIODevice *device)
m_videoDecoderCtx = nullptr; m_videoDecoderCtx = nullptr;
} }
if (m_audioDecoderCtx)
{
avcodec_free_context(&m_audioDecoderCtx);
avcodec_close(m_audioDecoderCtx);
m_audioDecoderCtx = nullptr;
}
if (m_frame) if (m_frame)
{ {
av_frame_unref(m_frame); av_frame_unref(m_frame);

View File

@ -86,6 +86,20 @@ struct DataTSMetaData2
OK_TransportStream = false; OK_TransportStream = false;
OK_VideoStream = false; OK_VideoStream = false;
} }
void formatString(QString &s)
{
QTextStream out(&s);
out << " CodecID:" << CodecID
<< " PID:" << PID
<< " Program:" << Program
<< " Stream:" << Stream
<< " Width:" << Width
<< " Height:" << Height
<< " BitRate:" << BitRate
<< " Channels:" << Channels
<< " CodecDescription:" << CodecDescription;
}
}; };
class DATVideoRender : public TVScreen class DATVideoRender : public TVScreen
@ -98,11 +112,11 @@ class DATVideoRender : public TVScreen
void SetFullScreen(bool blnFullScreen); void SetFullScreen(bool blnFullScreen);
void setAudioFIFO(AudioFifo *fifo) { m_audioFifo = fifo; }
bool OpenStream(DATVideostream *objDevice); bool OpenStream(DATVideostream *objDevice);
bool RenderStream(); bool RenderStream();
bool CloseStream(QIODevice *objDevice); bool CloseStream(QIODevice *objDevice);
void setAudioFIFO(AudioFifo *fifo) { m_audioFifo = fifo; }
int getVideoStreamIndex() const { return m_videoStreamIndex; } int getVideoStreamIndex() const { return m_videoStreamIndex; }
int getAudioStreamIndex() const { return m_audioStreamIndex; } int getAudioStreamIndex() const { return m_audioStreamIndex; }
@ -114,6 +128,7 @@ class DATVideoRender : public TVScreen
bool getVideoDecodeOK() const { return m_videoDecodeOK; } bool getVideoDecodeOK() const { return m_videoDecodeOK; }
private: private:
struct DataTSMetaData2 m_metaData; struct DataTSMetaData2 m_metaData;
QWidget *m_parentWidget; QWidget *m_parentWidget;
Qt::WindowFlags m_originalWindowFlags; Qt::WindowFlags m_originalWindowFlags;
@ -224,6 +239,8 @@ class DATVideoRenderThread : public QThread
m_renderingVideo = false; m_renderingVideo = false;
} }
static const int videoThreadTimeoutMs = 2000;
private: private:
DATVideoRender *m_renderer; DATVideoRender *m_renderer;
DATVideostream *m_stream; DATVideostream *m_stream;

View File

@ -769,7 +769,7 @@ struct s2_frame_receiver : runnable
opt_write(state_out, 0); opt_write(state_out, 0);
if (sch->debug) { if (sch->debug) {
fprintf(stderr, "DETECT\n"); fprintf(stderr, "enter_frame_detect\n");
} }
if (fastlock || first_run) if (fastlock || first_run)
@ -960,7 +960,7 @@ struct s2_frame_receiver : runnable
if (plscode_errors >= S2_MAX_ERR_PLSCODE) if (plscode_errors >= S2_MAX_ERR_PLSCODE)
{ {
if (sch->debug2) { if (sch->debug2) {
fprintf(stderr, "Too many errors in plscode (%u)\n", plscode_errors); fprintf(stderr, "Too many errors in plscode (%u/%lu)\n", plscode_errors, S2_MAX_ERR_PLSCODE);
} }
in.read(ss.p-in.rd()); in.read(ss.p-in.rd());
@ -1040,13 +1040,16 @@ struct s2_frame_receiver : runnable
if (mer < mcinfo->esn0_nf - 1.0f) if (mer < mcinfo->esn0_nf - 1.0f)
{ {
// False positive from PLHEADER detection. // False positive from PLHEADER detection.
if ( sch->debug ) fprintf(stderr, "Insufficient MER\n"); if (sch->debug) {
fprintf(stderr, "Insufficient MER (%f/%f)\n", mer, mcinfo->esn0_nf - 1.0f);
}
in.read(ss.p-in.rd()); in.read(ss.p-in.rd());
enter_frame_detect(); enter_frame_detect();
return; return;
} }
if (pls.sf && mcinfo->rate==FEC910) if (pls.sf && mcinfo->rate == FEC910)
{ // TBD use fec_infos { // TBD use fec_infos
fprintf(stderr, "Unsupported or corrupted FEC\n"); fprintf(stderr, "Unsupported or corrupted FEC\n");
in.read(ss.p-in.rd()); in.read(ss.p-in.rd());
@ -1056,19 +1059,19 @@ struct s2_frame_receiver : runnable
// Store current MODCOD info // Store current MODCOD info
if (mcinfo->c != m_modcodType) { if (mcinfo->c != m_modcodType) {
m_modcodType = mcinfo->c; m_modcodType = mcinfo->c < cstln_base::predef::COUNT ? mcinfo->c : -1;
} }
if (mcinfo->rate != m_modcodRate) { if (mcinfo->rate != m_modcodRate) {
m_modcodRate = mcinfo->rate; m_modcodRate = mcinfo->rate < code_rate::FEC_COUNT ? mcinfo->rate : -1;
} }
S = pls.sf ? mcinfo->nslots_nf/4 : mcinfo->nslots_nf; S = pls.sf ? mcinfo->nslots_nf/4 : mcinfo->nslots_nf;
// Constellation for data slots. // Constellation for data slots.
dcstln = get_cstln(pls.modcod); dcstln = get_cstln(pls.modcod);
cstln = dcstln; // Used by GUI cstln = dcstln; // Used by GUI
cstln->m_rateCode = (int) mcinfo->rate; cstln->m_rateCode = mcinfo->rate < code_rate::FEC_COUNT ? mcinfo->rate : -1;
cstln->m_typeCode = (int) mcinfo->c; cstln->m_typeCode = mcinfo->c < cstln_base::predef::COUNT ? mcinfo->c : -1;
cstln->m_setByModcod = true; cstln->m_setByModcod = true;
// Output special slot with PLS information. // Output special slot with PLS information.
pout->is_pls = true; pout->is_pls = true;
@ -1324,10 +1327,7 @@ struct s2_frame_receiver : runnable
if (ss_cache.fw16<min_freqw16 || ss_cache.fw16>max_freqw16) if (ss_cache.fw16<min_freqw16 || ss_cache.fw16>max_freqw16)
{ {
if (sch->debug) { fprintf(stderr, "Carrier out of bounds\n");
fprintf(stderr, "Carrier out of bounds\n");
}
enter_frame_detect(); enter_frame_detect();
} }
} // run_frame_probe_locked } // run_frame_probe_locked