v3.3.t5
-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:
parent
60a24c9d67
commit
4f0c37b92b
246
src/camera.cpp
246
src/camera.cpp
|
@ -31,22 +31,22 @@ int Camera::start(const QStringList &args)
|
|||
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;
|
||||
heartBeat = 10;
|
||||
heartBeat = 2;
|
||||
loopTimer = 0;
|
||||
|
||||
connect(thr, &QThread::started, this, &Loop::init);
|
||||
connect(thr, &QThread::started, this, &EventLoop::init);
|
||||
|
||||
moveToThread(thr);
|
||||
}
|
||||
|
||||
void Loop::init()
|
||||
void EventLoop::init()
|
||||
{
|
||||
loopTimer = new QTimer(this);
|
||||
|
||||
connect(loopTimer, &QTimer::timeout, this, &Loop::loopSlot);
|
||||
connect(loopTimer, &QTimer::timeout, this, &EventLoop::loopSlot);
|
||||
|
||||
loopTimer->setSingleShot(false);
|
||||
loopTimer->start(heartBeat * 1000);
|
||||
|
@ -54,7 +54,7 @@ void Loop::init()
|
|||
loopSlot();
|
||||
}
|
||||
|
||||
void Loop::loopSlot()
|
||||
void EventLoop::loopSlot()
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
heartBeat = 2;
|
||||
pcTimer = 0;
|
||||
shared = sharedRes;
|
||||
|
||||
connect(thr, &QThread::started, this, &DetectLoop::init);
|
||||
|
||||
moveToThread(thr);
|
||||
}
|
||||
|
||||
void DetectLoop::init()
|
||||
{
|
||||
pcTimer = new QTimer(this);
|
||||
|
||||
eventQue.queAge = 0;
|
||||
eventQue.score = 0;
|
||||
eventQue.inQue = false;
|
||||
|
||||
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()
|
||||
|
@ -259,6 +285,8 @@ QStringList DetectLoop::buildSnapArgs(const QString &vidSrc, const QString &imgP
|
|||
QStringList ret;
|
||||
|
||||
ret.append("-hide_banner");
|
||||
ret.append("-loglevel");
|
||||
ret.append("panic");
|
||||
ret.append("-y");
|
||||
ret.append("-i");
|
||||
ret.append(vidSrc);
|
||||
|
@ -269,101 +297,87 @@ QStringList DetectLoop::buildSnapArgs(const QString &vidSrc, const QString &imgP
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool DetectLoop::exec()
|
||||
void DetectLoop::exec()
|
||||
{
|
||||
if (eventQue.inQue)
|
||||
{
|
||||
eventQue.queAge += heartBeat;
|
||||
}
|
||||
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);
|
||||
|
||||
auto clips = lsFilesInDir(shared->buffPath + "/live", shared->streamExt);
|
||||
|
||||
if (clips.size() < 2)
|
||||
if (compArgs.isEmpty())
|
||||
{
|
||||
QTextStream(stdout) << "warning: didn't pick up enough clips files from the video stream. number of files: " << QString::number(clips.size()) << Qt::endl;
|
||||
QTextStream(stdout) << " will try again on the next loop." << Qt::endl;
|
||||
QTextStream(stderr) << "err: could not parse a executable name from img_comp_cmd: " << shared->compCmd << Qt::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto vidAPath = shared->buffPath + "/live/" + clips[clips.size() - 2];
|
||||
auto vidBPath = shared->buffPath + "/live/" + clips[clips.size() - 1];
|
||||
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);
|
||||
QProcess::execute("ffmpeg", snapArgsA);
|
||||
QProcess::execute("ffmpeg", snapArgsB);
|
||||
|
||||
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
|
||||
{
|
||||
QProcess::execute("ffmpeg", snapArgsA);
|
||||
QProcess::execute("ffmpeg", snapArgsB);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
QTextStream(stdout) << "why?" << Qt::endl;
|
||||
QTextStream(stdout) << "imgAPath: " << imgAPath << Qt::endl;
|
||||
QTextStream(stdout) << "imgBPath: " << imgBPath << Qt::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return Loop::exec();
|
||||
vidAPath.clear();
|
||||
vidBPath.clear();
|
||||
}
|
||||
|
|
44
src/camera.h
44
src/camera.h
|
@ -30,37 +30,21 @@ public:
|
|||
int start(const QStringList &args);
|
||||
};
|
||||
|
||||
class Loop : public QObject
|
||||
class EventLoop : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
private slots:
|
||||
|
||||
void init();
|
||||
void loopSlot();
|
||||
|
||||
private:
|
||||
|
||||
shared_t *shared;
|
||||
QTimer *loopTimer;
|
||||
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);
|
||||
|
||||
public:
|
||||
|
@ -70,16 +54,18 @@ public:
|
|||
bool exec();
|
||||
};
|
||||
|
||||
class DetectLoop : public Loop
|
||||
class DetectLoop : public QFileSystemWatcher
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
|
||||
QTimer *pcTimer;
|
||||
evt_t eventQue;
|
||||
QString vidAPath;
|
||||
QString vidBPath;
|
||||
QTimer *pcTimer;
|
||||
evt_t eventQue;
|
||||
shared_t *shared;
|
||||
|
||||
void resetTimers();
|
||||
float getFloatFromExe(const QByteArray &line);
|
||||
QStringList buildArgs(const QString &prev, const QString &next);
|
||||
QStringList buildSnapArgs(const QString &vidSrc, const QString &imgPath);
|
||||
|
@ -87,13 +73,15 @@ private:
|
|||
private slots:
|
||||
|
||||
void init();
|
||||
void reset();
|
||||
void pcBreak();
|
||||
void updated(const QString &path);
|
||||
|
||||
public:
|
||||
|
||||
explicit DetectLoop(shared_t *shared, QThread *thr, QObject *parent = nullptr);
|
||||
|
||||
bool exec();
|
||||
void exec();
|
||||
};
|
||||
|
||||
#endif // CAMERA_H
|
||||
|
|
|
@ -25,11 +25,12 @@
|
|||
#include <QStringList>
|
||||
#include <QMutex>
|
||||
#include <QRegularExpression>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define APP_VER "3.3.t4"
|
||||
#define APP_VER "3.3.t5"
|
||||
#define APP_NAME "Motion Watch"
|
||||
#define APP_BIN "mow"
|
||||
#define DATETIME_FMT "yyyyMMddhhmmss"
|
||||
|
|
Loading…
Reference in New Issue
Block a user