From c75c35acad703dc92f8967d78b9de1c808942297 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sat, 11 Jul 2020 06:45:16 +0200 Subject: [PATCH] File Input: refactored FileInputThread to FileInputWorker object moved to thread (contribution from Vort). Fixes #562 --- plugins/samplesource/fileinput/CMakeLists.txt | 4 +- plugins/samplesource/fileinput/fileinput.cpp | 64 ++++++++++++------- plugins/samplesource/fileinput/fileinput.h | 9 ++- ...ileinputthread.cpp => fileinputworker.cpp} | 42 ++++-------- .../{fileinputthread.h => fileinputworker.h} | 18 ++---- 5 files changed, 67 insertions(+), 70 deletions(-) rename plugins/samplesource/fileinput/{fileinputthread.cpp => fileinputworker.cpp} (88%) rename plugins/samplesource/fileinput/{fileinputthread.h => fileinputworker.h} (90%) diff --git a/plugins/samplesource/fileinput/CMakeLists.txt b/plugins/samplesource/fileinput/CMakeLists.txt index 4d0436e5b..5f8dffa05 100644 --- a/plugins/samplesource/fileinput/CMakeLists.txt +++ b/plugins/samplesource/fileinput/CMakeLists.txt @@ -3,7 +3,7 @@ project(fileinput) set(fileinput_SOURCES fileinput.cpp fileinputplugin.cpp - fileinputthread.cpp + fileinputworker.cpp fileinputsettings.cpp fileinputwebapiadapter.cpp ) @@ -11,7 +11,7 @@ set(fileinput_SOURCES set(fileinput_HEADERS fileinput.h fileinputplugin.h - fileinputthread.h + fileinputworker.h fileinputsettings.h fileinputwebapiadapter.h ) diff --git a/plugins/samplesource/fileinput/fileinput.cpp b/plugins/samplesource/fileinput/fileinput.cpp index 2eafef0e8..3b6ee7688 100644 --- a/plugins/samplesource/fileinput/fileinput.cpp +++ b/plugins/samplesource/fileinput/fileinput.cpp @@ -35,7 +35,7 @@ #include "device/deviceapi.h" #include "fileinput.h" -#include "fileinputthread.h" +#include "fileinputworker.h" MESSAGE_CLASS_DEFINITION(FileInput::MsgConfigureFileInput, Message) MESSAGE_CLASS_DEFINITION(FileInput::MsgConfigureFileSourceName, Message) @@ -52,7 +52,7 @@ MESSAGE_CLASS_DEFINITION(FileInput::MsgReportHeaderCRC, Message) FileInput::FileInput(DeviceAPI *deviceAPI) : m_deviceAPI(deviceAPI), m_settings(), - m_fileInputThread(nullptr), + m_fileInputWorker(nullptr), m_deviceDescription(), m_fileName("..."), m_sampleRate(0), @@ -157,10 +157,10 @@ void FileInput::seekFileStream(int seekMillis) { QMutexLocker mutexLocker(&m_mutex); - if ((m_ifstream.is_open()) && m_fileInputThread && !m_fileInputThread->isRunning()) + if ((m_ifstream.is_open()) && m_fileInputWorker && !m_fileInputWorker->isRunning()) { quint64 seekPoint = ((m_recordLength * seekMillis) / 1000) * m_sampleRate; - m_fileInputThread->setSamplesCount(seekPoint); + m_fileInputWorker->setSamplesCount(seekPoint); seekPoint *= (m_sampleSize == 24 ? 8 : 4); // + sizeof(FileSink::Header) m_ifstream.clear(); m_ifstream.seekg(seekPoint + sizeof(FileRecord::Header), std::ios::beg); @@ -194,9 +194,11 @@ bool FileInput::start() return false; } - m_fileInputThread = new FileInputThread(&m_ifstream, &m_sampleFifo, m_masterTimer, &m_inputMessageQueue); - m_fileInputThread->setSampleRateAndSize(m_settings.m_accelerationFactor * m_sampleRate, m_sampleSize); // Fast Forward: 1 corresponds to live. 1/2 is half speed, 2 is double speed - m_fileInputThread->startWork(); + m_fileInputWorker = new FileInputWorker(&m_ifstream, &m_sampleFifo, m_masterTimer, &m_inputMessageQueue); + m_fileInputWorker->moveToThread(&m_fileInputWorkerThread); + m_fileInputWorker->setSampleRateAndSize(m_settings.m_accelerationFactor * m_sampleRate, m_sampleSize); // Fast Forward: 1 corresponds to live. 1/2 is half speed, 2 is double speed + startWorker(); + m_deviceDescription = "FileInput"; mutexLocker.unlock(); @@ -215,11 +217,11 @@ void FileInput::stop() qDebug() << "FileInput::stop"; QMutexLocker mutexLocker(&m_mutex); - if (m_fileInputThread) + if (m_fileInputWorker) { - m_fileInputThread->stopWork(); - delete m_fileInputThread; - m_fileInputThread = nullptr; + stopWorker(); + delete m_fileInputWorker; + m_fileInputWorker = nullptr; } m_deviceDescription.clear(); @@ -230,6 +232,20 @@ void FileInput::stop() } } +void FileInput::startWorker() +{ + m_fileInputWorker->startWork(); + m_fileInputWorkerThread.start(); +} + +void FileInput::stopWorker() +{ + m_fileInputWorker->stopWork(); + m_fileInputWorkerThread.quit(); + m_fileInputWorkerThread.wait(); +} + + QByteArray FileInput::serialize() const { return m_settings.serialize(); @@ -313,12 +329,12 @@ bool FileInput::handleMessage(const Message& message) MsgConfigureFileInputWork& conf = (MsgConfigureFileInputWork&) message; bool working = conf.isWorking(); - if (m_fileInputThread != 0) + if (m_fileInputWorker != 0) { if (working) { - m_fileInputThread->startWork(); + startWorker(); } else { - m_fileInputThread->stopWork(); + stopWorker(); } } @@ -336,11 +352,11 @@ bool FileInput::handleMessage(const Message& message) { MsgReportFileInputStreamTiming *report; - if (m_fileInputThread != 0) + if (m_fileInputWorker != 0) { if (getMessageQueueToGUI()) { - report = MsgReportFileInputStreamTiming::create(m_fileInputThread->getSamplesCount()); + report = MsgReportFileInputStreamTiming::create(m_fileInputWorker->getSamplesCount()); getMessageQueueToGUI()->push(report); } } @@ -370,21 +386,21 @@ bool FileInput::handleMessage(const Message& message) return true; } - else if (FileInputThread::MsgReportEOF::match(message)) + else if (FileInputWorker::MsgReportEOF::match(message)) { qDebug() << "FileInput::handleMessage: MsgReportEOF"; - m_fileInputThread->stopWork(); + stopWorker(); if (getMessageQueueToGUI()) { - MsgReportFileInputStreamTiming *report = MsgReportFileInputStreamTiming::create(m_fileInputThread->getSamplesCount()); + MsgReportFileInputStreamTiming *report = MsgReportFileInputStreamTiming::create(m_fileInputWorker->getSamplesCount()); getMessageQueueToGUI()->push(report); } if (m_settings.m_loop) { seekFileStream(0); - m_fileInputThread->startWork(); + startWorker(); } else { @@ -415,14 +431,14 @@ bool FileInput::applySettings(const FileInputSettings& settings, bool force) { reverseAPIKeys.append("accelerationFactor"); - if (m_fileInputThread) + if (m_fileInputWorker) { QMutexLocker mutexLocker(&m_mutex); if (!m_sampleFifo.setSize(m_settings.m_accelerationFactor * m_sampleRate * sizeof(Sample))) { qCritical("FileInput::applySettings: could not reallocate sample FIFO size to %lu", m_settings.m_accelerationFactor * m_sampleRate * sizeof(Sample)); } - m_fileInputThread->setSampleRateAndSize(settings.m_accelerationFactor * m_sampleRate, m_sampleSize); // Fast Forward: 1 corresponds to live. 1/2 is half speed, 2 is double speed + m_fileInputWorker->setSampleRateAndSize(settings.m_accelerationFactor * m_sampleRate, m_sampleSize); // Fast Forward: 1 corresponds to live. 1/2 is half speed, 2 is double speed } } @@ -571,8 +587,8 @@ void FileInput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response) qint64 t_msec = 0; quint64 samplesCount = 0; - if (m_fileInputThread) { - samplesCount = m_fileInputThread->getSamplesCount(); + if (m_fileInputWorker) { + samplesCount = m_fileInputWorker->getSamplesCount(); } if (m_sampleRate > 0) diff --git a/plugins/samplesource/fileinput/fileinput.h b/plugins/samplesource/fileinput/fileinput.h index 4f9802166..3c739bdda 100644 --- a/plugins/samplesource/fileinput/fileinput.h +++ b/plugins/samplesource/fileinput/fileinput.h @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include "dsp/devicesamplesource.h" @@ -32,7 +34,7 @@ class QNetworkAccessManager; class QNetworkReply; -class FileInputThread; +class FileInputWorker; class DeviceAPI; class FileInput : public DeviceSampleSource { @@ -333,7 +335,8 @@ public: QMutex m_mutex; FileInputSettings m_settings; std::ifstream m_ifstream; - FileInputThread* m_fileInputThread; + FileInputWorker* m_fileInputWorker; + QThread m_fileInputWorkerThread; QString m_deviceDescription; QString m_fileName; int m_sampleRate; @@ -345,6 +348,8 @@ public: QNetworkAccessManager *m_networkManager; QNetworkRequest m_networkRequest; + void startWorker(); + void stopWorker(); void openFileStream(); void seekFileStream(int seekMillis); bool applySettings(const FileInputSettings& settings, bool force = false); diff --git a/plugins/samplesource/fileinput/fileinputthread.cpp b/plugins/samplesource/fileinput/fileinputworker.cpp similarity index 88% rename from plugins/samplesource/fileinput/fileinputthread.cpp rename to plugins/samplesource/fileinput/fileinputworker.cpp index 95842e44d..a6c2c1eea 100644 --- a/plugins/samplesource/fileinput/fileinputthread.cpp +++ b/plugins/samplesource/fileinput/fileinputworker.cpp @@ -21,18 +21,18 @@ #include #include "dsp/filerecord.h" -#include "fileinputthread.h" +#include "fileinputworker.h" #include "dsp/samplesinkfifo.h" #include "util/messagequeue.h" -MESSAGE_CLASS_DEFINITION(FileInputThread::MsgReportEOF, Message) +MESSAGE_CLASS_DEFINITION(FileInputWorker::MsgReportEOF, Message) -FileInputThread::FileInputThread(std::ifstream *samplesStream, +FileInputWorker::FileInputWorker(std::ifstream *samplesStream, SampleSinkFifo* sampleFifo, const QTimer& timer, MessageQueue *fileInputMessageQueue, QObject* parent) : - QThread(parent), + QObject(parent), m_running(false), m_ifstream(samplesStream), m_fileBuf(0), @@ -52,7 +52,7 @@ FileInputThread::FileInputThread(std::ifstream *samplesStream, assert(m_ifstream != 0); } -FileInputThread::~FileInputThread() +FileInputWorker::~FileInputWorker() { if (m_running) { stopWork(); @@ -67,20 +67,16 @@ FileInputThread::~FileInputThread() } } -void FileInputThread::startWork() +void FileInputWorker::startWork() { qDebug() << "FileInputThread::startWork: "; if (m_ifstream->is_open()) { qDebug() << "FileInputThread::startWork: file stream open, starting..."; - m_startWaitMutex.lock(); m_elapsedTimer.start(); - start(); - while(!m_running) - m_startWaiter.wait(&m_startWaitMutex, 100); - m_startWaitMutex.unlock(); connect(&m_timer, SIGNAL(timeout()), this, SLOT(tick())); + m_running = true; } else { @@ -88,15 +84,14 @@ void FileInputThread::startWork() } } -void FileInputThread::stopWork() +void FileInputWorker::stopWork() { qDebug() << "FileInputThread::stopWork"; disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(tick())); m_running = false; - wait(); } -void FileInputThread::setSampleRateAndSize(int samplerate, quint32 samplesize) +void FileInputWorker::setSampleRateAndSize(int samplerate, quint32 samplesize) { qDebug() << "FileInputThread::setSampleRateAndSize:" << " new rate:" << samplerate @@ -121,7 +116,7 @@ void FileInputThread::setSampleRateAndSize(int samplerate, quint32 samplesize) //m_samplerate = samplerate; } -void FileInputThread::setBuffers(std::size_t chunksize) +void FileInputWorker::setBuffers(std::size_t chunksize) { if (chunksize > m_bufsize) { @@ -159,20 +154,7 @@ void FileInputThread::setBuffers(std::size_t chunksize) } } -void FileInputThread::run() -{ - m_running = true; - m_startWaiter.wakeAll(); - - while(m_running) // actual work is in the tick() function - { - sleep(1); - } - - m_running = false; -} - -void FileInputThread::tick() +void FileInputWorker::tick() { if (m_running) { @@ -203,7 +185,7 @@ void FileInputThread::tick() } } -void FileInputThread::writeToSampleFifo(const quint8* buf, qint32 nbBytes) +void FileInputWorker::writeToSampleFifo(const quint8* buf, qint32 nbBytes) { if (m_samplesize == 16) { diff --git a/plugins/samplesource/fileinput/fileinputthread.h b/plugins/samplesource/fileinput/fileinputworker.h similarity index 90% rename from plugins/samplesource/fileinput/fileinputthread.h rename to plugins/samplesource/fileinput/fileinputworker.h index c1cefefd6..c81fc635a 100644 --- a/plugins/samplesource/fileinput/fileinputthread.h +++ b/plugins/samplesource/fileinput/fileinputworker.h @@ -15,12 +15,9 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#ifndef INCLUDE_FILEINPUTTHREAD_H -#define INCLUDE_FILEINPUTTHREAD_H +#ifndef INCLUDE_FILEINPUTWORKER_H +#define INCLUDE_FILEINPUTWORKER_H -#include -#include -#include #include #include #include @@ -35,7 +32,7 @@ class SampleSinkFifo; class MessageQueue; -class FileInputThread : public QThread { +class FileInputWorker : public QObject { Q_OBJECT public: @@ -53,12 +50,12 @@ public: { } }; - FileInputThread(std::ifstream *samplesStream, + FileInputWorker(std::ifstream *samplesStream, SampleSinkFifo* sampleFifo, const QTimer& timer, MessageQueue *fileInputMessageQueue, QObject* parent = NULL); - ~FileInputThread(); + ~FileInputWorker(); void startWork(); void stopWork(); @@ -69,8 +66,6 @@ public: void setSamplesCount(quint64 samplesCount) { m_samplesCount = samplesCount; } private: - QMutex m_startWaitMutex; - QWaitCondition m_startWaiter; volatile bool m_running; std::ifstream* m_ifstream; @@ -90,7 +85,6 @@ private: QElapsedTimer m_elapsedTimer; bool m_throttleToggle; - void run(); //void decimate1(SampleVector::iterator* it, const qint16* buf, qint32 len); void writeToSampleFifo(const quint8* buf, qint32 nbBytes); @@ -98,4 +92,4 @@ private slots: void tick(); }; -#endif // INCLUDE_FILEINPUTTHREAD_H +#endif // INCLUDE_FILEINPUTWORKER_H