diff --git a/plugins/channelrx/demoddatv/CMakeLists.txt b/plugins/channelrx/demoddatv/CMakeLists.txt index fa7308d6a..67570c885 100644 --- a/plugins/channelrx/demoddatv/CMakeLists.txt +++ b/plugins/channelrx/demoddatv/CMakeLists.txt @@ -25,6 +25,7 @@ set(datv_SOURCES set(ldpc_SOURCES ldpctool/tables_handler.cpp + ldpctool/ldpcworker.cpp ) set(datv_HEADERS @@ -55,6 +56,7 @@ set(ldpc_HEADERS ldpctool/dvb_s2_tables.h ldpctool/dvb_s2x_tables.h ldpctool/dvb_t2_tables.h + ldpctool/ldpcworker.h ) include_directories( @@ -69,16 +71,10 @@ include_directories( set(TARGET_NAME demoddatv) set(INSTALL_FOLDER ${INSTALL_PLUGINS_DIR}) -if (LINUX) - add_library(${TARGET_NAME} SHARED - ${datv_SOURCES} - ${ldpc_SOURCES} - ) -else() - add_library(${TARGET_NAME} SHARED - ${datv_SOURCES} - ) -endif() +add_library(${TARGET_NAME} SHARED + ${datv_SOURCES} + ${ldpc_SOURCES} +) target_link_libraries(${TARGET_NAME} Qt5::Core @@ -94,13 +90,11 @@ target_link_libraries(${TARGET_NAME} ${SWRESAMPLE_LIBRARIES} ) -if (LINUX) - add_executable(ldpctool - ldpctool/ldpc_tool.cpp - ldpctool/tables_handler.cpp - ) - install(TARGETS ldpctool DESTINATION ${INSTALL_BIN_DIR}) -endif() +add_executable(ldpctool + ldpctool/ldpc_tool.cpp + ldpctool/tables_handler.cpp +) +install(TARGETS ldpctool DESTINATION ${INSTALL_BIN_DIR}) if(FFMPEG_EXTERNAL) add_dependencies(${TARGET_NAME} ffmpeg) diff --git a/plugins/channelrx/demoddatv/datvdemodgui.cpp b/plugins/channelrx/demoddatv/datvdemodgui.cpp index 921200494..2c4a4f1fe 100644 --- a/plugins/channelrx/demoddatv/datvdemodgui.cpp +++ b/plugins/channelrx/demoddatv/datvdemodgui.cpp @@ -300,13 +300,8 @@ DATVDemodGUI::DATVDemodGUI(PluginAPI* objPluginAPI, DeviceUISet *deviceUISet, Ba CRightClickEnabler *audioMuteRightClickEnabler = new CRightClickEnabler(ui->audioMute); connect(audioMuteRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(audioSelect())); -#ifdef LINUX CRightClickEnabler *ldpcToolRightClickEnabler = new CRightClickEnabler(ui->softLDPC); connect(ldpcToolRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(ldpcToolSelect())); -#else - ui->softLDPC->setEnabled(false); - ui->softLDPC->setStyleSheet("QCheckBox { color: gray }"); -#endif ui->playerIndicator->setStyleSheet("QLabel { background-color: gray; border-radius: 8px; }"); ui->udpIndicator->setStyleSheet("QLabel { background-color: gray; border-radius: 8px; }"); @@ -377,7 +372,6 @@ void DATVDemodGUI::displaySettings() ui->maxBitflipsLabel->setStyleSheet("QLabel { color: white }"); } -#ifdef LINUX if (m_settings.m_standard == DATVDemodSettings::dvb_version::DVB_S) { ui->softLDPC->setEnabled(false); @@ -388,7 +382,6 @@ void DATVDemodGUI::displaySettings() ui->softLDPC->setEnabled(true); ui->softLDPC->setStyleSheet("QCheckBox { color: white }"); } -#endif if (m_settings.m_standard == DATVDemodSettings::dvb_version::DVB_S) { @@ -658,7 +651,6 @@ void DATVDemodGUI::on_cmbStandard_currentIndexChanged(int index) ui->maxBitflipsLabel->setStyleSheet("QLabel { color: white }"); } -#ifdef LINUX if (m_settings.m_standard == DATVDemodSettings::dvb_version::DVB_S) { ui->softLDPC->setEnabled(false); @@ -669,7 +661,6 @@ void DATVDemodGUI::on_cmbStandard_currentIndexChanged(int index) ui->softLDPC->setEnabled(true); ui->softLDPC->setStyleSheet("QCheckBox { color: white }"); } -#endif if (m_settings.m_standard == DATVDemodSettings::dvb_version::DVB_S) { @@ -710,18 +701,14 @@ void DATVDemodGUI::on_cmbFEC_currentIndexChanged(int arg1) void DATVDemodGUI::on_softLDPC_clicked() { -#ifdef LINUX m_settings.m_softLDPC = ui->softLDPC->isChecked(); applySettings(); -#endif } void DATVDemodGUI::on_maxBitflips_valueChanged(int value) { -#ifdef LINUX m_settings.m_maxBitflips = value; applySettings(); -#endif } void DATVDemodGUI::on_chkViterbi_clicked() diff --git a/plugins/channelrx/demoddatv/datvdemodsettings.cpp b/plugins/channelrx/demoddatv/datvdemodsettings.cpp index da1d9773b..26f548226 100644 --- a/plugins/channelrx/demoddatv/datvdemodsettings.cpp +++ b/plugins/channelrx/demoddatv/datvdemodsettings.cpp @@ -27,6 +27,12 @@ #include "datvdemodsettings.h" +#ifdef _MSC_VER +#define DEFAULT_LDPCTOOLPATH "C:/Program Files/SDRangel/ldpctool.exe" +#else +#define DEFAULT_LDPCTOOLPATH "/opt/install/sdrangel/bin/ldpctool" +#endif + DATVDemodSettings::DATVDemodSettings() : m_channelMarker(nullptr), m_rollupState(nullptr) @@ -44,7 +50,7 @@ void DATVDemodSettings::resetToDefaults() m_modulation = BPSK; m_fec = FEC12; m_softLDPC = false; - m_softLDPCToolPath = "/opt/install/sdrangel/bin/ldpctool"; + m_softLDPCToolPath = DEFAULT_LDPCTOOLPATH; m_softLDPCMaxTrials = 8; m_maxBitflips = 0; m_symbolRate = 250000; @@ -208,7 +214,7 @@ bool DATVDemodSettings::deserialize(const QByteArray& data) d.readBool(32, &m_softLDPC, false); d.readS32(33, &m_maxBitflips, 0); - d.readString(34, &m_softLDPCToolPath, "/opt/install/sdrangel/bin/ldpctool"); + d.readString(34, &m_softLDPCToolPath, DEFAULT_LDPCTOOLPATH); d.readS32(35, &tmp, 8); m_softLDPCMaxTrials = tmp < 1 ? 1 : tmp > m_softLDPCMaxMaxTrials ? m_softLDPCMaxMaxTrials : tmp; d.readBool(36, &m_playerEnable, true); diff --git a/plugins/channelrx/demoddatv/datvdemodsink.cpp b/plugins/channelrx/demoddatv/datvdemodsink.cpp index f0f584128..5847547bd 100644 --- a/plugins/channelrx/demoddatv/datvdemodsink.cpp +++ b/plugins/channelrx/demoddatv/datvdemodsink.cpp @@ -397,7 +397,6 @@ void DATVDemodSink::CleanUpDATVFramework() delete (leansdr::s2_fecdec*) r_fecdec; } -#ifdef LINUX if (r_fecdecsoft != nullptr) { delete (leansdr::s2_fecdec_soft*) r_fecdecsoft; } @@ -405,7 +404,6 @@ void DATVDemodSink::CleanUpDATVFramework() if (r_fecdechelper != nullptr) { delete (leansdr::s2_fecdec_helper*) r_fecdechelper; } -#endif if (p_deframer != nullptr) { delete (leansdr::s2_deframer*) p_deframer; @@ -515,10 +513,8 @@ void DATVDemodSink::ResetDATVFrameworkPointers() p_bbframes = nullptr; p_s2_deinterleaver = nullptr; r_fecdec = nullptr; -#ifdef LINUX r_fecdecsoft = nullptr; r_fecdechelper = nullptr; -#endif p_deframer = nullptr; r_scope_symbols_dvbs2 = nullptr; } @@ -1101,7 +1097,6 @@ void DATVDemodSink::InitDATVS2Framework() p_vbitcount= new leansdr::pipebuf(m_objScheduler, "Bits processed", BUF_S2PACKETS); p_verrcount = new leansdr::pipebuf(m_objScheduler, "Bits corrected", BUF_S2PACKETS); -#ifdef LINUX bool commandFileValid = false; if (QFileInfo::exists(m_settings.m_softLDPCToolPath)) @@ -1110,7 +1105,7 @@ void DATVDemodSink::InitDATVS2Framework() commandFileValid = fileInfo.isExecutable(); } - if (m_settings.m_softLDPC && commandFileValid) + if (m_settings.m_softLDPC /*&& commandFileValid*/) { #if 0 // Doesn't work... @@ -1178,25 +1173,6 @@ void DATVDemodSink::InitDATVS2Framework() leansdr::s2_fecdec *fecdec = (leansdr::s2_fecdec * ) r_fecdec; fecdec->bitflips=m_settings.m_maxBitflips; } -#else - // Bit-flipping mode. - // Deinterleave into hard bits. - p_fecframes = new leansdr::pipebuf< leansdr::fecframe >(m_objScheduler, "FEC frames", BUF_FRAMES); - p_s2_deinterleaver = new leansdr::s2_deinterleaver( - m_objScheduler, - *(leansdr::pipebuf< leansdr::plslot > *) p_slots_dvbs2, - *(leansdr::pipebuf< leansdr::fecframe > * ) p_fecframes - ); - r_fecdec = new leansdr::s2_fecdec( - m_objScheduler, - *(leansdr::pipebuf< leansdr::fecframe > * ) p_fecframes, - *(leansdr::pipebuf *) p_bbframes, - p_vbitcount, - p_verrcount - ); - leansdr::s2_fecdec *fecdec = (leansdr::s2_fecdec * ) r_fecdec; - fecdec->bitflips=m_settings.m_maxBitflips; -#endif // Deframe BB frames to TS packets p_lock = new leansdr::pipebuf (m_objScheduler, "lock", BUF_SLOW); diff --git a/plugins/channelrx/demoddatv/datvdvbs2ldpcdialog.cpp b/plugins/channelrx/demoddatv/datvdvbs2ldpcdialog.cpp index 6b9e5fd2d..7a77b5ed2 100644 --- a/plugins/channelrx/demoddatv/datvdvbs2ldpcdialog.cpp +++ b/plugins/channelrx/demoddatv/datvdvbs2ldpcdialog.cpp @@ -58,7 +58,11 @@ void DatvDvbS2LdpcDialog::on_showFileDialog_clicked(bool checked) QFileDialog fileDialog(this, "Select LDPC tool"); fileDialog.setOption(QFileDialog::DontUseNativeDialog, true); +#ifdef _MSC_VER + fileDialog.setNameFilter("*.exe"); +#else fileDialog.setFilter(QDir::Executable | QDir::Files); +#endif fileDialog.selectFile(m_fileName); if (fileDialog.exec() == QDialog::Accepted) diff --git a/plugins/channelrx/demoddatv/ldpctool/layered_decoder.h b/plugins/channelrx/demoddatv/ldpctool/layered_decoder.h index 659d62016..be6e7b09d 100644 --- a/plugins/channelrx/demoddatv/ldpctool/layered_decoder.h +++ b/plugins/channelrx/demoddatv/ldpctool/layered_decoder.h @@ -8,10 +8,39 @@ Copyright 2018 Ahmet Inan #define LAYERED_DECODER_HH #include +#ifdef _MSC_VER +#include +#endif #include "ldpc.h" namespace ldpctool { +class LDPCUtil +{ +public: +#ifndef _MSC_VER + static void *aligned_malloc(size_t alignment, size_t size) + { + return aligned_alloc(alignment, size); + } + + static void aligned_free(void *mem) + { + free(mem); + } +#else + static void *aligned_malloc(size_t alignment, size_t size) + { + return _aligned_malloc(size, alignment); + } + + static void aligned_free(void *mem) + { + _aligned_free(mem); + } +#endif +}; + template class LDPCDecoder { @@ -113,8 +142,8 @@ public: } LT = ldpc->links_total(); delete ldpc; - bnl = reinterpret_cast(aligned_alloc(sizeof(TYPE), sizeof(TYPE) * LT)); - pty = reinterpret_cast(aligned_alloc(sizeof(TYPE), sizeof(TYPE) * R)); + bnl = reinterpret_cast(LDPCUtil::aligned_malloc(sizeof(TYPE), sizeof(TYPE) * LT)); + pty = reinterpret_cast(LDPCUtil::aligned_malloc(sizeof(TYPE), sizeof(TYPE) * R)); uint16_t *tmp = new uint16_t[R * CNL]; for (int i = 0; i < q; ++i) for (int j = 0; j < M; ++j) @@ -139,8 +168,8 @@ public: ~LDPCDecoder() { if (initialized) { - free(bnl); - free(pty); + LDPCUtil::aligned_free(bnl); + LDPCUtil::aligned_free(pty); delete[] cnc; delete[] pos; delete[] inp; diff --git a/plugins/channelrx/demoddatv/ldpctool/ldpc_tool.cpp b/plugins/channelrx/demoddatv/ldpctool/ldpc_tool.cpp index 7fd7cc10c..0846b5d73 100644 --- a/plugins/channelrx/demoddatv/ldpctool/ldpc_tool.cpp +++ b/plugins/channelrx/demoddatv/ldpctool/ldpc_tool.cpp @@ -7,7 +7,14 @@ Copyright 2019 */ #include +#ifndef _MSC_VER #include +#else +#include +typedef SSIZE_T ssize_t; +#include +#include +#endif #include #include #include @@ -21,6 +28,7 @@ Copyright 2019 #include "algorithms.h" #include "ldpc.h" + #if 0 #include "flooding_decoder.h" static const int DEFAULT_TRIALS = 50; @@ -129,7 +137,7 @@ int main(int argc, char **argv) int BLOCKS = batch_size; ldpctool::code_type *code = new ldpctool::code_type[BLOCKS * CODE_LEN]; - void *aligned_buffer = aligned_alloc(sizeof(ldpctool::simd_type), sizeof(ldpctool::simd_type) * CODE_LEN); + void *aligned_buffer = ldpctool::LDPCUtil::aligned_malloc(sizeof(ldpctool::simd_type), sizeof(ldpctool::simd_type) * CODE_LEN); ldpctool::simd_type *simd = reinterpret_cast(aligned_buffer); // Expect LLR values in int8_t format. @@ -212,7 +220,7 @@ int main(int argc, char **argv) delete ldpc; - free(aligned_buffer); + ldpctool::LDPCUtil::aligned_free(aligned_buffer); delete[] code; return 0; diff --git a/plugins/channelrx/demoddatv/ldpctool/testbench.h b/plugins/channelrx/demoddatv/ldpctool/testbench.h index dc555452c..fabe75b43 100644 --- a/plugins/channelrx/demoddatv/ldpctool/testbench.h +++ b/plugins/channelrx/demoddatv/ldpctool/testbench.h @@ -4,6 +4,8 @@ LDPC testbench Copyright 2018 Ahmet Inan */ +#pragma once + #include #include #include "simd.h" diff --git a/plugins/channelrx/demoddatv/leansdr/dvbs2.h b/plugins/channelrx/demoddatv/leansdr/dvbs2.h index 185090db8..210c2b380 100644 --- a/plugins/channelrx/demoddatv/leansdr/dvbs2.h +++ b/plugins/channelrx/demoddatv/leansdr/dvbs2.h @@ -54,13 +54,18 @@ #include "ldpc.h" #include "sdr.h" -#ifdef LINUX #include +#ifdef LINUX #include +#endif +#ifdef _MSC_VER +#include +typedef SSIZE_T ssize_t; +#endif #include "ldpctool/layered_decoder.h" #include "ldpctool/testbench.h" #include "ldpctool/algorithms.h" -#endif +#include "ldpctool/ldpcworker.h" namespace leansdr { @@ -3041,8 +3046,6 @@ struct s2_fecdec : runnable pipewriter *bitcount, *errcount; }; // s2_fecdec -#ifdef LINUX - // Soft LDPC decoder // Internally implemented LDPC tool. Replaces external LDPC decoder @@ -3230,6 +3233,8 @@ private: T q[SIZE]; }; +#if defined(USE_LDPC_TOOL) && !defined(_MSC_VER) + template struct s2_fecdec_helper : runnable { @@ -3610,7 +3615,280 @@ struct s2_fecdec_helper : runnable std::deque errcount_q; pipewriter *bitcount, *errcount; }; // s2_fecdec_helper + +#else // USE_LDPC_TOOL + +template +struct s2_fecdec_helper : runnable +{ + int batch_size; + int nhelpers; + bool must_buffer; + int max_trials; + + s2_fecdec_helper( + scheduler *sch, + pipebuf> &_in, + pipebuf &_out, + const char *_command, + pipebuf *_bitcount = nullptr, + pipebuf *_errcount = nullptr + ) : + runnable(sch, "S2 fecdec io"), + batch_size(16), + nhelpers(1), + must_buffer(false), + max_trials(8), + in(_in), + out(_out), + bitcount(opt_writer(_bitcount, 1)), + errcount(opt_writer(_errcount, 1)) + { + command = strdup(_command); + + for (int mc = 0; mc < 32; ++mc) { + for (int sf = 0; sf < 2; ++sf) { + pools[mc][sf].procs = nullptr; + } + } + } + + ~s2_fecdec_helper() + { + free(command); + killall(); // also deletes pools[mc][sf].procs if necessary + } + + void run() + { + // Send work until all helpers block. + while (in.readable() >= 1 && !jobs.full()) + { + if ((bbframe_q.size() != 0) && (out.writable() >= 1)) + { + bbframe *pout = out.wr(); + pout->pls = bbframe_q.front().pls; + std::copy(bbframe_q.front().bytes, bbframe_q.front().bytes + (58192 / 8), pout->bytes); + bbframe_q.pop_front(); + out.written(1); + } + + if ((bitcount_q.size() != 0) && opt_writable(bitcount, 1)) + { + opt_write(bitcount, bitcount_q.front()); + bitcount_q.pop_front(); + } + + if ((errcount_q.size() != 0) && opt_writable(errcount, 1)) + { + opt_write(errcount, errcount_q.front()); + errcount_q.pop_front(); + } + + if (!jobs.empty() && jobs.peek()->h->b_out) { + receive_frame(jobs.get()); + } + + send_frame(in.rd()); + in.read(1); + } + } + + private: + struct helper_instance + { + QThread *m_thread; + LDPCWorker *m_worker; + int batch_size; + int b_in; // Jobs in input queue + int b_out; // Jobs in output queue + }; + struct pool + { + helper_instance *procs; // nullptr or [nprocs] + int nprocs; + int shift; + } pools[32][2]; // [modcod][sf] + struct helper_job + { + s2_pls pls; + helper_instance *h; + }; + + simplequeue jobs; + + // Try to send a frame. Return false if helper was busy. + bool send_frame(fecframe *pin) + { + pool *p = get_pool(&pin->pls); + + for (int j = 0; j < p->nprocs; ++j) + { + int i = (p->shift + j) % p->nprocs; + helper_instance *h = &p->procs[i]; + int iosize = (pin->pls.framebits() / 8) * sizeof(SOFTBYTE); + + if (h->m_worker->busy()) { + continue; + } + + QByteArray data((char *)pin->bytes, iosize); + QMetaObject::invokeMethod(h->m_worker, "process", Qt::QueuedConnection, Q_ARG(QByteArray, data)); + + p->shift = i; + helper_job *job = jobs.put(); + job->pls = pin->pls; + job->h = h; + ++h->b_in; + + if (h->b_in >= h->batch_size) + { + h->b_in -= h->batch_size; + h->b_out += h->batch_size; + } + + return true; // done sent to worker + } + + fprintf(stderr, "s2_fecdec_helper::send_frame: WARNING: all %d workers were busy: modcod=%d sf=%d)\n", + p->nprocs, pin->pls.modcod, pin->pls.sf); + return false; // all workers were busy + } + + // Return a pool of running helpers for a given modcod. + pool *get_pool(const s2_pls *pls) + { + pool *p = &pools[pls->modcod][pls->sf]; + + if (!p->procs) + { + fprintf(stderr, "s2_fecdec_helper::get_pool: allocate %d workers: modcod=%d sf=%d\n", + nhelpers, pls->modcod, pls->sf); + p->procs = new helper_instance[nhelpers]; + + for (int i = 0; i < nhelpers; ++i) { + spawn_helper(&p->procs[i], pls); + } + + p->nprocs = nhelpers; + p->shift = 0; + } + + return p; + } + + void killall() + { + qDebug() << "s2_fecdec_helper::killall"; + + for (int i = 0; i < 32; i++) // all MODCODs + { + for (int j = 0; j < 2; j++) // long and short frames + { + pool *p = &pools[i][j]; + + if (p->procs) + { + for (int i = 0; i < p->nprocs; ++i) + { + helper_instance *h = &p->procs[i]; + h->m_thread->quit(); + h->m_thread->wait(); + delete h->m_thread; + h->m_thread = nullptr; + delete h->m_worker; + h->m_worker = nullptr; + } + + delete p->procs; + p->procs = nullptr; + p->nprocs = 0; + } + } // long and short frames + } // all MODCODs + } + + // Spawn a helper thread. + void spawn_helper(helper_instance *h, const s2_pls *pls) + { + qDebug() << "s2_fecdec_helper: Spawning LDPC thread: modcod=" << pls->modcod << " sf=" << pls->sf; + h->m_thread = new QThread(); + h->m_worker = new LDPCWorker(pls->modcod, max_trials, batch_size, pls->sf); + h->m_worker->moveToThread(h->m_thread); + h->batch_size = batch_size; + h->b_in = h->b_out = 0; + h->m_thread->start(); + } + + // Receive a finished job. + void receive_frame(const helper_job *job) + { + // Read corrected frame from helper + const s2_pls *pls = &job->pls; + int iosize = (pls->framebits() / 8) * sizeof(ldpc_buf[0]); + + // Blocking read - do we need to return faster? + // If so, call m_worker->dataAvailable() + QByteArray data = job->h->m_worker->data(); + memcpy(ldpc_buf, data.data(), data.size()); + + --job->h->b_out; + // Decode BCH. + const modcod_info *mcinfo = check_modcod(job->pls.modcod); + const fec_info *fi = &fec_infos[job->pls.sf][mcinfo->rate]; + uint8_t *hardbytes = softbytes_harden(ldpc_buf, fi->kldpc / 8, bch_buf); + size_t cwbytes = fi->kldpc / 8; + //size_t msgbytes = fi->Kbch / 8; + //size_t chkbytes = cwbytes - msgbytes; + bch_interface *bch = s2bch.bchs[job->pls.sf][mcinfo->rate]; + int ncorr = bch->decode(hardbytes, cwbytes); + + if (sch->debug2) { + fprintf(stderr, "BCHCORR = %d\n", ncorr); + } + + bool corrupted = (ncorr < 0); + // Report VBER + bitcount_q.push_back(fi->Kbch); + //opt_write(bitcount, fi->Kbch); + errcount_q.push_front((ncorr >= 0) ? ncorr : fi->Kbch); + //opt_write(errcount, (ncorr >= 0) ? ncorr : fi->Kbch); +#if 0 + // TBD Some decoders want the bad packets. + if ( corrupted ) { + fprintf(stderr, "Passing bad frame\n"); + corrupted = false; + } #endif + if (!corrupted) + { + // Descramble and output + bbframe_q.emplace_back(); + //bbframe *pout = out.wr(); + bbframe_q.back().pls = job->pls; + bbscrambling.transform(hardbytes, fi->Kbch / 8, bbframe_q.back().bytes); + //out.written(1); + } + + if (sch->debug) { + fprintf(stderr, "%c", corrupted ? '!' : ncorr ? '.' : '_'); + } + } + + pipereader> in; + pipewriter out; + char *command; + SOFTBYTE ldpc_buf[64800 / 8]; + uint8_t bch_buf[64800 / 8]; // Temp storage for hardening before BCH + s2_bch_engines s2bch; + s2_bbscrambling bbscrambling; + std::deque bbframe_q; + std::deque bitcount_q; + std::deque errcount_q; + pipewriter *bitcount, *errcount; +}; // s2_fecdec_helper + +#endif // USE_LDPC_TOOL // S2 FRAMER // EN 302 307-1 section 5.1 Mode adaptation @@ -3854,7 +4132,6 @@ private: { handle_ts(data, dfl, syncd, sync); } -#ifdef LINUX else if (streamtype == 1) { if (fd_gse >= 0) @@ -3874,7 +4151,6 @@ private: fprintf(stderr, "Unrecognized bbframe\n"); } } -#endif } void handle_ts(uint8_t *data, uint16_t dfl, uint16_t syncd, uint8_t sync) diff --git a/plugins/channelrx/demoddatv/readme.md b/plugins/channelrx/demoddatv/readme.md index c45c6a376..e616a1706 100644 --- a/plugins/channelrx/demoddatv/readme.md +++ b/plugins/channelrx/demoddatv/readme.md @@ -183,13 +183,11 @@ The controls specific to DVB-S are disabled and greyed out. These are: Fast Lock
B.2b.6: DVB-S2 specific - Soft LDPC decoder
-This is for experimenters only working in Linux. It can be used to decode signals lower that ~10 db MER which is the limit of LDPC hard decoding as explained next (B.2b.7). Video degrades progressively down to about 7.5 dB MER and drops below this limit. - -Runs the `ldpctool` program for soft LDPC decoding. Frames are sent on its standard input and decoded frames retrieved from its standard output. Two processes executing `ldpctool` are spawned but so far it seems that only one is effectively used. +It can be used to decode signals lower that ~10 db MER which is the limit of LDPC hard decoding as explained next (B.2b.7). Video degrades progressively down to about 7.5 dB MER and drops below this limit. Right clicking on this control opens a dialog where you can choose: - - The `ldpctool` executable. You have to use the `ldpctool` binary produced by the build of SDRangel. + - The `ldpctool` executable. Obsolete. - The maximum of retries in LDPC decoding from 1 to 8.
B.2b.7: DVB-S2 specific - LDPC maximum number of bit flips allowed