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;
}
void setMessageQueueToGUI(MessageQueue* queue) override {
void setMessageQueueToGUI(MessageQueue* queue) override
{
ChannelAPI::setMessageQueueToGUI(queue);
m_basebandSink->setMessageQueueToGUI(queue);
}
void SetTVScreen(TVScreen *objScreen) { m_basebandSink->setTVScreen(objScreen); }
void setMERLabel(QLabel *merLabel) { m_basebandSink->setMERLabel(merLabel); }
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 }");
#endif
ui->playerIndicator->setStyleSheet("QLabel { background-color: gray; border-radius: 8px; }");
resetToDefaults(); // does applySettings()
}
@ -547,7 +548,13 @@ void DATVDemodGUI::tick()
m_intPreviousDecodedData = m_intLastDecodedData;
//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;
}

View File

@ -779,6 +779,37 @@
</property>
</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 class="QWidget" name="horizontalLayoutWidget">
<property name="geometry">
@ -911,7 +942,7 @@
</font>
</property>
<property name="toolTip">
<string>SNR estimation</string>
<string>MER estimation</string>
</property>
</widget>
</item>
@ -971,7 +1002,7 @@
</font>
</property>
<property name="toolTip">
<string>SNR estimation</string>
<string>CNR estimation</string>
</property>
</widget>
</item>

View File

@ -176,11 +176,12 @@ bool DATVDemodSink::playVideo()
{
m_objRenderThread->setStreamAndRenderer(m_objRegisteredVideoRender, m_objVideoStream);
m_objVideoStream->MultiThreaded = true;
m_objVideoStream->ThreadTimeOut = 5000; //5000 ms
m_objVideoStream->ThreadTimeOut = DATVideoRenderThread::videoThreadTimeoutMs;
m_objRenderThread->start();
return true;
}
return true;
return false;
}
void DATVDemodSink::CleanUpDATVFramework()
@ -1013,29 +1014,29 @@ void DATVDemodSink::InitDATVS2Framework()
switch (m_objCfg.sampler)
{
case DATVDemodSettings::SAMP_NEAREST:
sampler = new leansdr::nearest_sampler<float>();
break;
sampler = new leansdr::nearest_sampler<float>();
break;
case DATVDemodSettings::SAMP_LINEAR:
sampler = new leansdr::linear_sampler<float>();
break;
sampler = new leansdr::linear_sampler<float>();
break;
case DATVDemodSettings::SAMP_RRC:
{
if (m_objCfg.rrc_steps == 0)
{
// At least 64 discrete sampling points between symbols
m_objCfg.rrc_steps = std::max(1, (int)(64*m_objCfg.Fm / m_objCfg.Fs));
}
if (m_objCfg.rrc_steps == 0)
{
// At least 64 discrete sampling points between symbols
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 transition = (m_objCfg.Fm/2) * m_objCfg.rolloff;
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);
sampler = new leansdr::fir_sampler<float,float>(ncoeffs_sampler, coeffs_sampler, m_objCfg.rrc_steps);
break;
float Frrc = m_objCfg.Fs * m_objCfg.rrc_steps; // Sample freq of the RRC filter
float transition = (m_objCfg.Fm/2) * m_objCfg.rolloff;
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);
sampler = new leansdr::fir_sampler<float,float>(ncoeffs_sampler, coeffs_sampler, m_objCfg.rrc_steps);
break;
}
default:
qCritical("DATVDemodSink::InitDATVS2Framework: Interpolator not implemented");
return;
qCritical("DATVDemodSink::InitDATVS2Framework: Interpolator not implemented");
return;
}
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)
{
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)
{
@ -1297,8 +1298,8 @@ void DATVDemodSink::feed(const SampleVector::const_iterator& begin, const Sample
objRF ++;
if (m_blnDVBInitialized
&& (p_rawiq_writer!=nullptr)
&& (m_objScheduler!=nullptr))
&& (p_rawiq_writer!=nullptr)
&& (m_objScheduler!=nullptr))
{
p_rawiq_writer->write(objIQ);
m_lngReadIQ++;
@ -1321,7 +1322,7 @@ void DATVDemodSink::feed(const SampleVector::const_iterator& begin, const Sample
} // Samples for loop
// 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;
@ -1342,6 +1343,22 @@ void DATVDemodSink::feed(const SampleVector::const_iterator& begin, const Sample
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;

View File

@ -29,8 +29,10 @@ namespace leansdr {
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,
code_rate r)
static inline cstln_lut<llr_ss, 256> * make_dvbs2_constellation(
cstln_lut<llr_ss, 256>::predef c,
code_rate r
)
{
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);
newCstln->m_rateCode = (int) r;
newCstln->m_typeCode = (int) c;
newCstln->m_rateCode = r < code_rate::FEC_COUNT ? r : -1;
newCstln->m_typeCode = c < cstln_lut<llr_ss, 256>::predef::COUNT ? c : -1;
newCstln->m_setByModcod = false;
return newCstln;
}

View File

@ -29,7 +29,8 @@ extern "C"
#include "audio/audiofifo.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);
m_isFullScreen = false;
@ -229,7 +230,7 @@ bool DATVideoRender::PreprocessStream()
avcodec_free_context(&m_videoDecoderCtx);
}
m_videoDecoderCtx = avcodec_alloc_context3(NULL);
m_videoDecoderCtx = avcodec_alloc_context3(nullptr);
avcodec_parameters_to_context(m_videoDecoderCtx, parms);
// 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.OK_VideoStream = true;
QString metaStr;
m_metaData.formatString(metaStr);
qDebug() << "DATVideoRender::PreprocessStream: video: " << metaStr;
emit onMetaDataChanged(new DataTSMetaData2(m_metaData));
// Prepare Audio Codec
@ -704,6 +709,13 @@ bool DATVideoRender::CloseStream(QIODevice *device)
m_videoDecoderCtx = nullptr;
}
if (m_audioDecoderCtx)
{
avcodec_free_context(&m_audioDecoderCtx);
avcodec_close(m_audioDecoderCtx);
m_audioDecoderCtx = nullptr;
}
if (m_frame)
{
av_frame_unref(m_frame);

View File

@ -86,6 +86,20 @@ struct DataTSMetaData2
OK_TransportStream = 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
@ -98,11 +112,11 @@ class DATVideoRender : public TVScreen
void SetFullScreen(bool blnFullScreen);
void setAudioFIFO(AudioFifo *fifo) { m_audioFifo = fifo; }
bool OpenStream(DATVideostream *objDevice);
bool RenderStream();
bool CloseStream(QIODevice *objDevice);
void setAudioFIFO(AudioFifo *fifo) { m_audioFifo = fifo; }
int getVideoStreamIndex() const { return m_videoStreamIndex; }
int getAudioStreamIndex() const { return m_audioStreamIndex; }
@ -114,6 +128,7 @@ class DATVideoRender : public TVScreen
bool getVideoDecodeOK() const { return m_videoDecodeOK; }
private:
struct DataTSMetaData2 m_metaData;
QWidget *m_parentWidget;
Qt::WindowFlags m_originalWindowFlags;
@ -224,6 +239,8 @@ class DATVideoRenderThread : public QThread
m_renderingVideo = false;
}
static const int videoThreadTimeoutMs = 2000;
private:
DATVideoRender *m_renderer;
DATVideostream *m_stream;

View File

@ -769,7 +769,7 @@ struct s2_frame_receiver : runnable
opt_write(state_out, 0);
if (sch->debug) {
fprintf(stderr, "DETECT\n");
fprintf(stderr, "enter_frame_detect\n");
}
if (fastlock || first_run)
@ -960,7 +960,7 @@ struct s2_frame_receiver : runnable
if (plscode_errors >= S2_MAX_ERR_PLSCODE)
{
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());
@ -1040,13 +1040,16 @@ struct s2_frame_receiver : runnable
if (mer < mcinfo->esn0_nf - 1.0f)
{
// 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());
enter_frame_detect();
return;
}
if (pls.sf && mcinfo->rate==FEC910)
if (pls.sf && mcinfo->rate == FEC910)
{ // TBD use fec_infos
fprintf(stderr, "Unsupported or corrupted FEC\n");
in.read(ss.p-in.rd());
@ -1056,19 +1059,19 @@ struct s2_frame_receiver : runnable
// Store current MODCOD info
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) {
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;
// Constellation for data slots.
dcstln = get_cstln(pls.modcod);
cstln = dcstln; // Used by GUI
cstln->m_rateCode = (int) mcinfo->rate;
cstln->m_typeCode = (int) mcinfo->c;
cstln->m_rateCode = mcinfo->rate < code_rate::FEC_COUNT ? mcinfo->rate : -1;
cstln->m_typeCode = mcinfo->c < cstln_base::predef::COUNT ? mcinfo->c : -1;
cstln->m_setByModcod = true;
// Output special slot with PLS information.
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 (sch->debug) {
fprintf(stderr, "Carrier out of bounds\n");
}
fprintf(stderr, "Carrier out of bounds\n");
enter_frame_detect();
}
} // run_frame_probe_locked