-again reformed the detectloop class to use filesystem monitoring
 instead of timers to pull clips from the live stream.

-removed the loop class after reforming detectloop.
This commit is contained in:
Zii 2023-11-18 18:40:26 -05:00
parent 60a24c9d67
commit 4f0c37b92b
3 changed files with 148 additions and 145 deletions

View File

@ -31,22 +31,22 @@ int Camera::start(const QStringList &args)
return shared.retCode; return shared.retCode;
} }
Loop::Loop(shared_t *sharedRes, QThread *thr, QObject *parent) : QObject(parent) EventLoop::EventLoop(shared_t *sharedRes, QThread *thr, QObject *parent) : QObject(parent)
{ {
shared = sharedRes; shared = sharedRes;
heartBeat = 10; heartBeat = 2;
loopTimer = 0; loopTimer = 0;
connect(thr, &QThread::started, this, &Loop::init); connect(thr, &QThread::started, this, &EventLoop::init);
moveToThread(thr); moveToThread(thr);
} }
void Loop::init() void EventLoop::init()
{ {
loopTimer = new QTimer(this); loopTimer = new QTimer(this);
connect(loopTimer, &QTimer::timeout, this, &Loop::loopSlot); connect(loopTimer, &QTimer::timeout, this, &EventLoop::loopSlot);
loopTimer->setSingleShot(false); loopTimer->setSingleShot(false);
loopTimer->start(heartBeat * 1000); loopTimer->start(heartBeat * 1000);
@ -54,7 +54,7 @@ void Loop::init()
loopSlot(); loopSlot();
} }
void Loop::loopSlot() void EventLoop::loopSlot()
{ {
if (!exec()) if (!exec())
{ {
@ -62,21 +62,6 @@ void Loop::loopSlot()
} }
} }
bool Loop::exec()
{
if (loopTimer->interval() != heartBeat * 1000)
{
loopTimer->start(heartBeat * 1000);
}
return shared->retCode == 0;
}
EventLoop::EventLoop(shared_t *sharedRes, QThread *thr, QObject *parent) : Loop(sharedRes, thr, parent)
{
heartBeat = 2;
}
bool EventLoop::wrOutVod(const evt_t &event) bool EventLoop::wrOutVod(const evt_t &event)
{ {
auto ret = false; auto ret = false;
@ -155,33 +140,74 @@ bool EventLoop::exec()
} }
} }
return Loop::exec(); return shared->retCode == 0;
} }
DetectLoop::DetectLoop(shared_t *sharedRes, QThread *thr, QObject *parent) : Loop(sharedRes, thr, parent) DetectLoop::DetectLoop(shared_t *sharedRes, QThread *thr, QObject *parent) : QFileSystemWatcher(parent)
{ {
pcTimer = 0; pcTimer = 0;
heartBeat = 2; shared = sharedRes;
connect(thr, &QThread::started, this, &DetectLoop::init);
moveToThread(thr);
} }
void DetectLoop::init() void DetectLoop::init()
{ {
pcTimer = new QTimer(this); pcTimer = new QTimer(this);
eventQue.queAge = 0;
eventQue.score = 0;
eventQue.inQue = false;
connect(pcTimer, &QTimer::timeout, this, &DetectLoop::pcBreak); connect(pcTimer, &QTimer::timeout, this, &DetectLoop::pcBreak);
connect(this, &QFileSystemWatcher::directoryChanged, this, &DetectLoop::updated);
resetTimers(); addPath(shared->buffPath + "/live");
Loop::init(); pcTimer->start(shared->postSecs * 1000);
} }
void DetectLoop::resetTimers() void DetectLoop::reset()
{ {
pcTimer->start(shared->postSecs * 1000); vidAPath.clear();
vidBPath.clear();
eventQue.inQue = false;
eventQue.score = 0;
eventQue.queAge = 0;
eventQue.imgPath.clear();
eventQue.vidList.clear();
eventQue.timeStamp.clear();
}
void DetectLoop::updated(const QString &path)
{
auto clips = lsFilesInDir(path, shared->streamExt);
if (clips.isEmpty())
{
thread()->sleep(5); reset();
}
else
{
auto latestPath = path + "/" + clips.last();
if (vidAPath.isEmpty())
{
vidAPath = latestPath;
}
else if (latestPath == vidAPath)
{
thread()->usleep(500);
}
else
{
vidBPath = latestPath;
thread()->sleep(1);
exec();
}
}
} }
void DetectLoop::pcBreak() void DetectLoop::pcBreak()
@ -259,6 +285,8 @@ QStringList DetectLoop::buildSnapArgs(const QString &vidSrc, const QString &imgP
QStringList ret; QStringList ret;
ret.append("-hide_banner"); ret.append("-hide_banner");
ret.append("-loglevel");
ret.append("panic");
ret.append("-y"); ret.append("-y");
ret.append("-i"); ret.append("-i");
ret.append(vidSrc); ret.append(vidSrc);
@ -269,101 +297,87 @@ QStringList DetectLoop::buildSnapArgs(const QString &vidSrc, const QString &imgP
return ret; return ret;
} }
bool DetectLoop::exec() void DetectLoop::exec()
{ {
if (eventQue.inQue) auto imgAPath = shared->buffPath + "/img/" + QFileInfo(vidAPath).baseName() + ".bmp";
{ auto imgBPath = shared->buffPath + "/img/" + QFileInfo(vidBPath).baseName() + ".bmp";
eventQue.queAge += heartBeat; auto snapArgsA = buildSnapArgs(vidAPath, imgAPath);
} auto snapArgsB = buildSnapArgs(vidBPath, imgBPath);
auto compArgs = buildArgs(imgAPath, imgBPath);
auto clips = lsFilesInDir(shared->buffPath + "/live", shared->streamExt); if (compArgs.isEmpty())
if (clips.size() < 2)
{ {
QTextStream(stdout) << "warning: didn't pick up enough clips files from the video stream. number of files: " << QString::number(clips.size()) << Qt::endl; QTextStream(stderr) << "err: could not parse a executable name from img_comp_cmd: " << shared->compCmd << Qt::endl;
QTextStream(stdout) << " will try again on the next loop." << Qt::endl;
} }
else else
{ {
auto vidAPath = shared->buffPath + "/live/" + clips[clips.size() - 2]; QProcess::execute("ffmpeg", snapArgsA);
auto vidBPath = shared->buffPath + "/live/" + clips[clips.size() - 1]; QProcess::execute("ffmpeg", snapArgsB);
auto imgAPath = shared->buffPath + "/img/" + QFileInfo(vidAPath).baseName() + ".bmp";
auto imgBPath = shared->buffPath + "/img/" + QFileInfo(vidBPath).baseName() + ".bmp";
auto snapArgsA = buildSnapArgs(vidAPath, imgAPath);
auto snapArgsB = buildSnapArgs(vidBPath, imgBPath);
auto compArgs = buildArgs(imgAPath, imgBPath);
if (compArgs.isEmpty()) if (QFile::exists(imgAPath) && QFile::exists(imgBPath))
{ {
QTextStream(stderr) << "err: could not parse a executable name from img_comp_cmd: " << shared->compCmd << Qt::endl; QProcess extComp;
extComp.start(compArgs[0], compArgs.mid(1));
extComp.waitForFinished();
float score = 0;
if (shared->outputType == "stdout")
{
score = getFloatFromExe(extComp.readAllStandardOutput());
}
else
{
score = getFloatFromExe(extComp.readAllStandardError());
}
QTextStream(stdout) << compArgs.join(" ") << " --result: " << QString::number(score) << Qt::endl;
if (eventQue.inQue)
{
eventQue.queAge += 4;
if (eventQue.score < score)
{
eventQue.score = score;
eventQue.imgPath = imgBPath;
}
eventQue.vidList.append(vidAPath);
eventQue.vidList.append(vidBPath);
if (eventQue.queAge >= shared->evMaxSecs)
{
eventQue.inQue = false;
shared->recList.append(eventQue);
reset();
}
}
else if (score >= shared->imgThresh)
{
QTextStream(stdout) << "--threshold_meet: " << QString::number(shared->imgThresh) << Qt::endl;
eventQue.score = score;
eventQue.imgPath = imgBPath;
eventQue.inQue = true;
eventQue.queAge = 0;
eventQue.timeStamp = QDateTime::currentDateTime().toString(DATETIME_FMT);
eventQue.vidList.append(vidAPath);
eventQue.vidList.append(vidBPath);
}
} }
else else
{ {
QProcess::execute("ffmpeg", snapArgsA); QTextStream(stdout) << "why?" << Qt::endl;
QProcess::execute("ffmpeg", snapArgsB); QTextStream(stdout) << "imgAPath: " << imgAPath << Qt::endl;
QTextStream(stdout) << "imgBPath: " << imgBPath << Qt::endl;
if (QFile::exists(imgAPath) && QFile::exists(imgBPath))
{
QProcess extComp;
extComp.start(compArgs[0], compArgs.mid(1));
extComp.waitForFinished();
float score = 0;
if (shared->outputType == "stdout")
{
score = getFloatFromExe(extComp.readAllStandardOutput());
}
else
{
score = getFloatFromExe(extComp.readAllStandardError());
}
QTextStream(stdout) << compArgs.join(" ") << " --result: " << QString::number(score) << Qt::endl;
if (eventQue.inQue)
{
if (eventQue.score < score)
{
eventQue.score = score;
eventQue.imgPath = imgBPath;
}
eventQue.vidList.append(vidAPath);
eventQue.vidList.append(vidBPath);
if (eventQue.queAge >= shared->evMaxSecs)
{
eventQue.inQue = false;
shared->recList.append(eventQue);
eventQue.imgPath.clear();
eventQue.vidList.clear();
eventQue.timeStamp.clear();
eventQue.score = 0;
eventQue.queAge = 0;
}
}
else if (score >= shared->imgThresh)
{
QTextStream(stdout) << "--threshold_breached: " << QString::number(shared->imgThresh) << Qt::endl;
eventQue.score = score;
eventQue.imgPath = imgBPath;
eventQue.inQue = true;
eventQue.queAge = 0;
eventQue.timeStamp = QDateTime::currentDateTime().toString(DATETIME_FMT);
eventQue.vidList.clear();
eventQue.vidList.append(vidAPath);
eventQue.vidList.append(vidBPath);
}
}
} }
} }
return Loop::exec(); vidAPath.clear();
vidBPath.clear();
} }

View File

@ -30,37 +30,21 @@ public:
int start(const QStringList &args); int start(const QStringList &args);
}; };
class Loop : public QObject class EventLoop : public QObject
{ {
Q_OBJECT Q_OBJECT
protected: private slots:
void init();
void loopSlot();
private:
shared_t *shared; shared_t *shared;
QTimer *loopTimer; QTimer *loopTimer;
int heartBeat; int heartBeat;
protected slots:
virtual void init();
private slots:
void loopSlot();
public:
explicit Loop(shared_t *shared, QThread *thr, QObject *parent = nullptr);
virtual bool exec();
};
class EventLoop : public Loop
{
Q_OBJECT
private:
bool wrOutVod(const evt_t &event); bool wrOutVod(const evt_t &event);
public: public:
@ -70,16 +54,18 @@ public:
bool exec(); bool exec();
}; };
class DetectLoop : public Loop class DetectLoop : public QFileSystemWatcher
{ {
Q_OBJECT Q_OBJECT
private: private:
QTimer *pcTimer; QString vidAPath;
evt_t eventQue; QString vidBPath;
QTimer *pcTimer;
evt_t eventQue;
shared_t *shared;
void resetTimers();
float getFloatFromExe(const QByteArray &line); float getFloatFromExe(const QByteArray &line);
QStringList buildArgs(const QString &prev, const QString &next); QStringList buildArgs(const QString &prev, const QString &next);
QStringList buildSnapArgs(const QString &vidSrc, const QString &imgPath); QStringList buildSnapArgs(const QString &vidSrc, const QString &imgPath);
@ -87,13 +73,15 @@ private:
private slots: private slots:
void init(); void init();
void reset();
void pcBreak(); void pcBreak();
void updated(const QString &path);
public: public:
explicit DetectLoop(shared_t *shared, QThread *thr, QObject *parent = nullptr); explicit DetectLoop(shared_t *shared, QThread *thr, QObject *parent = nullptr);
bool exec(); void exec();
}; };
#endif // CAMERA_H #endif // CAMERA_H

View File

@ -25,11 +25,12 @@
#include <QStringList> #include <QStringList>
#include <QMutex> #include <QMutex>
#include <QRegularExpression> #include <QRegularExpression>
#include <QFileSystemWatcher>
#include <iostream> #include <iostream>
using namespace std; using namespace std;
#define APP_VER "3.3.t4" #define APP_VER "3.3.t5"
#define APP_NAME "Motion Watch" #define APP_NAME "Motion Watch"
#define APP_BIN "mow" #define APP_BIN "mow"
#define DATETIME_FMT "yyyyMMddhhmmss" #define DATETIME_FMT "yyyyMMddhhmmss"