v1.5.t10
Somewhere in the code is causing an infinite loop, root cause still undermined. added more logging statements to help me find misbehavior. imgDiff() will now handle empty frames on the parameters more gracefully. enforceMaxClips() will no longer assume all video clips are accompanied by html and jpg files but will now instead "delete if exists."
This commit is contained in:
parent
a5ee164b4e
commit
d969b1779d
|
@ -111,20 +111,20 @@ void enforceMaxDays(const string &dirPath, shared_t *share)
|
||||||
|
|
||||||
void enforceMaxClips(const string &dirPath, shared_t *share)
|
void enforceMaxClips(const string &dirPath, shared_t *share)
|
||||||
{
|
{
|
||||||
auto names = lsDirsInDir(dirPath);
|
auto names = lsDirsInDir(dirPath, "." + share->vidExt);
|
||||||
|
|
||||||
// note: this function assumes all video clips are accompanied by
|
while (names.size() > share->maxClips)
|
||||||
// .html and .jpg files of the same name, hence why it *3
|
|
||||||
// the max names in the directory and *3 the file deletion.
|
|
||||||
|
|
||||||
while (names.size() > ((share->maxClips - 1) * 3))
|
|
||||||
{
|
{
|
||||||
remove(string(cleanDir(dirPath) + "/" + names[0]).c_str());
|
// removes the video file extension.
|
||||||
remove(string(cleanDir(dirPath) + "/" + names[1]).c_str());
|
auto nameOnly = names[0].substr(0, names[0].size() - (share->vidExt.size() + 1));
|
||||||
remove(string(cleanDir(dirPath) + "/" + names[2]).c_str());
|
auto imgFile = cleanDir(dirPath) + "/" + nameOnly + ".jpg";
|
||||||
|
auto webFile = cleanDir(dirPath) + "/" + nameOnly + ".html"
|
||||||
|
|
||||||
|
remove(cleanDir(dirPath) + "/" + names[0]);
|
||||||
|
|
||||||
|
if (exists(imgFile)) remove(imgFile);
|
||||||
|
if (exists(webFile)) remove(webFile);
|
||||||
|
|
||||||
names.erase(names.begin());
|
|
||||||
names.erase(names.begin());
|
|
||||||
names.erase(names.begin());
|
names.erase(names.begin());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,12 +191,12 @@ bool rdConf(shared_t *share)
|
||||||
|
|
||||||
share->retCode = 0;
|
share->retCode = 0;
|
||||||
share->frameGap = 10;
|
share->frameGap = 10;
|
||||||
share->pixThresh = 30;
|
share->pixThresh = 150;
|
||||||
share->imgThresh = 512;
|
share->imgThresh = 1024;
|
||||||
share->secs = 60;
|
share->secs = 60;
|
||||||
share->maxDays = 15;
|
share->maxDays = 15;
|
||||||
share->maxClips = 30;
|
share->maxClips = 30;
|
||||||
share->maxLogSize = 10000;
|
share->maxLogSize = 50000;
|
||||||
share->camName = path(share->conf.c_str()).filename();
|
share->camName = path(share->conf.c_str()).filename();
|
||||||
share->webRoot = "/var/www/html";
|
share->webRoot = "/var/www/html";
|
||||||
share->vidExt = "mp4";
|
share->vidExt = "mp4";
|
||||||
|
|
|
@ -35,7 +35,7 @@ using namespace cv;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace std::filesystem;
|
using namespace std::filesystem;
|
||||||
|
|
||||||
#define APP_VER "1.5.t9"
|
#define APP_VER "1.5.t10"
|
||||||
#define APP_NAME "Motion Watch"
|
#define APP_NAME "Motion Watch"
|
||||||
|
|
||||||
struct shared_t
|
struct shared_t
|
||||||
|
|
41
src/main.cpp
41
src/main.cpp
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
void detectLoop(shared_t *share)
|
void detectLoop(shared_t *share)
|
||||||
{
|
{
|
||||||
detLog("detectLoop() -- start", share);
|
detLog("detect_loop() -- start", share);
|
||||||
|
|
||||||
vector<string> bufFiles;
|
vector<string> bufFiles;
|
||||||
auto waitingForFiles = 0;
|
auto waitingForFiles = 0;
|
||||||
|
@ -32,26 +32,19 @@ void detectLoop(shared_t *share)
|
||||||
if ((bufFiles.size() >= 2) || (share->recLoopWait && !bufFiles.empty()))
|
if ((bufFiles.size() >= 2) || (share->recLoopWait && !bufFiles.empty()))
|
||||||
{
|
{
|
||||||
auto fullPath = cleanDir(share->buffDir) + "/" + bufFiles[0];
|
auto fullPath = cleanDir(share->buffDir) + "/" + bufFiles[0];
|
||||||
|
|
||||||
Mat thumbNail;
|
Mat thumbNail;
|
||||||
|
|
||||||
if (moDetect(fullPath, thumbNail, share))
|
if (moDetect(fullPath, thumbNail, share))
|
||||||
{
|
{
|
||||||
share->skipCmd = true;
|
share->skipCmd = true;
|
||||||
|
|
||||||
detLog("motion detected in file: " + fullPath, share);
|
|
||||||
wrOut(fullPath, thumbNail, share);
|
wrOut(fullPath, thumbNail, share);
|
||||||
}
|
}
|
||||||
else
|
else if (exists(fullPath))
|
||||||
{
|
|
||||||
detLog("no motion detected in file: " + fullPath + " removing it.", share);
|
|
||||||
|
|
||||||
if (exists(fullPath))
|
|
||||||
{
|
{
|
||||||
remove(fullPath);
|
remove(fullPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (waitingForFiles >= share->secs)
|
if (waitingForFiles >= share->secs)
|
||||||
|
@ -60,19 +53,25 @@ void detectLoop(shared_t *share)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
detLog(to_string(bufFiles.size()) + " buff file(s) found, waiting for more.", share);
|
||||||
|
}
|
||||||
|
|
||||||
sleep(1); waitingForFiles++;
|
sleep(5); waitingForFiles += 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (!bufFiles.empty() && !share->recLoopWait);
|
while (!share->recLoopWait || !bufFiles.empty());
|
||||||
|
|
||||||
detLog("detectLoop() -- finished", share);
|
detLog("detect_loop() -- finished", share);
|
||||||
}
|
}
|
||||||
|
|
||||||
void recLoop(shared_t *share)
|
void recLoop(shared_t *share)
|
||||||
{
|
{
|
||||||
while (rdConf(share))
|
while (rdConf(share))
|
||||||
{
|
{
|
||||||
|
recLog("rec_loop() -- start", share);
|
||||||
|
|
||||||
enforceMaxLogSize(share->recLogPath, share);
|
enforceMaxLogSize(share->recLogPath, share);
|
||||||
enforceMaxLogSize(share->detLogPath, share);
|
enforceMaxLogSize(share->detLogPath, share);
|
||||||
|
|
||||||
|
@ -81,28 +80,24 @@ void recLoop(shared_t *share)
|
||||||
|
|
||||||
initLogFrontPages(share);
|
initLogFrontPages(share);
|
||||||
|
|
||||||
recLog("recLoop() -- start", share);
|
|
||||||
|
|
||||||
if (!exists("/tmp/mow-lock"))
|
if (!exists("/tmp/mow-lock"))
|
||||||
{
|
{
|
||||||
recLog("/tmp/mow-lock not found, assuming it is safe to update the webroot page.", share);
|
|
||||||
recLog("webroot page = " + cleanDir(share->webRoot) + "/index.html", share);
|
|
||||||
|
|
||||||
system("touch /tmp/mow-lock");
|
system("touch /tmp/mow-lock");
|
||||||
|
|
||||||
genCSS(share);
|
genCSS(share);
|
||||||
genHTMLul(share->webRoot, string(APP_NAME) + " " + string(APP_VER), share);
|
genHTMLul(share->webRoot, string(APP_NAME) + " " + string(APP_VER), share);
|
||||||
|
|
||||||
remove("/tmp/mow-lock");
|
remove("/tmp/mow-lock");
|
||||||
|
recLog("webroot page updated: " + cleanDir(share->webRoot) + "/index.html", share);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
recLog("/tmp/mow-lock pesent, skipping update of the webroot page.", share);
|
recLog("skipping update of the webroot page, it is busy.", share);
|
||||||
}
|
}
|
||||||
|
|
||||||
genHTMLul(share->outDir, share->camName, share);
|
genHTMLul(share->outDir, share->camName, share);
|
||||||
|
|
||||||
recLog("camera specific webroot page updated. page = " + share->outDir + "/index.html", share);
|
recLog("camera specific webroot page updated: " + share->outDir + "/index.html", share);
|
||||||
|
|
||||||
auto bufPath = cleanDir(share->buffDir) + "/%03d." + share->vidExt;
|
auto bufPath = cleanDir(share->buffDir) + "/%03d." + share->vidExt;
|
||||||
auto secs = to_string(share->secs);
|
auto secs = to_string(share->secs);
|
||||||
|
@ -111,7 +106,7 @@ void recLoop(shared_t *share)
|
||||||
|
|
||||||
thread th2(detectLoop, share);
|
thread th2(detectLoop, share);
|
||||||
|
|
||||||
recLog("detectLoop() -- started in a seperate thread.", share);
|
recLog("detect_loop() -- started in a seperate thread.", share);
|
||||||
recLog("ffmpeg_run: " + cmd, share);
|
recLog("ffmpeg_run: " + cmd, share);
|
||||||
|
|
||||||
auto retCode = system(cmd.c_str());
|
auto retCode = system(cmd.c_str());
|
||||||
|
@ -122,6 +117,8 @@ void recLoop(shared_t *share)
|
||||||
|
|
||||||
th2.join();
|
th2.join();
|
||||||
|
|
||||||
|
recLog("detect_loop() -- thread finished.", share);
|
||||||
|
|
||||||
if (!share->skipCmd)
|
if (!share->skipCmd)
|
||||||
{
|
{
|
||||||
recLog("motion not detected by the detection loop.", share);
|
recLog("motion not detected by the detection loop.", share);
|
||||||
|
@ -132,7 +129,7 @@ void recLoop(shared_t *share)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
recLog("running post command = " + share->postCmd, share);
|
recLog("running post command: " + share->postCmd, share);
|
||||||
system(share->postCmd.c_str());
|
system(share->postCmd.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,7 +138,7 @@ void recLoop(shared_t *share)
|
||||||
recLog("motion detected by the detection loop, skipping the post command.", share);
|
recLog("motion detected by the detection loop, skipping the post command.", share);
|
||||||
}
|
}
|
||||||
|
|
||||||
recLog("recLoop() -- finished", share);
|
recLog("rec_loop() -- finished", share);
|
||||||
|
|
||||||
if (share->retCode != 0)
|
if (share->retCode != 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,6 +13,15 @@
|
||||||
#include "mo_detect.h"
|
#include "mo_detect.h"
|
||||||
|
|
||||||
bool imgDiff(const Mat &prev, const Mat &next, int &diffScore, shared_t *share)
|
bool imgDiff(const Mat &prev, const Mat &next, int &diffScore, shared_t *share)
|
||||||
|
{
|
||||||
|
auto ret = false;
|
||||||
|
|
||||||
|
detLog("img_diff() -- start()", share);
|
||||||
|
|
||||||
|
if (prev.empty()) detLog("prev_frame is empty -- this should never happen (opencv to blame).", share);
|
||||||
|
if (next.empty()) detLog("next_frame is empty -- EOF assumed.", share);
|
||||||
|
|
||||||
|
if (!prev.empty() && !next.empty())
|
||||||
{
|
{
|
||||||
Mat diff;
|
Mat diff;
|
||||||
|
|
||||||
|
@ -21,7 +30,14 @@ bool imgDiff(const Mat &prev, const Mat &next, int &diffScore, shared_t *share)
|
||||||
|
|
||||||
diffScore = countNonZero(diff);
|
diffScore = countNonZero(diff);
|
||||||
|
|
||||||
return diffScore >= share->imgThresh;
|
detLog("diff_score: " + to_string(diffScore), share);
|
||||||
|
|
||||||
|
ret = diffScore >= share->imgThresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
detLog("img_diff() -- finished()", share);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mat frameFF(VideoCapture *cap, int gap)
|
Mat frameFF(VideoCapture *cap, int gap)
|
||||||
|
@ -47,6 +63,9 @@ Mat frameFF(VideoCapture *cap, int gap)
|
||||||
|
|
||||||
void wrOut(const string &buffFile, const Mat &vidThumb, shared_t *share)
|
void wrOut(const string &buffFile, const Mat &vidThumb, shared_t *share)
|
||||||
{
|
{
|
||||||
|
detLog("wr_out() -- start()", share);
|
||||||
|
detLog("buff_file: " + buffFile, share);
|
||||||
|
|
||||||
auto dayStr = genTimeStr("%Y-%m-%d");
|
auto dayStr = genTimeStr("%Y-%m-%d");
|
||||||
auto timStr = genTimeStr("%H%M%S");
|
auto timStr = genTimeStr("%H%M%S");
|
||||||
auto outDir = cleanDir(share->outDir) + "/" + dayStr;
|
auto outDir = cleanDir(share->outDir) + "/" + dayStr;
|
||||||
|
@ -61,7 +80,6 @@ void wrOut(const string &buffFile, const Mat &vidThumb, shared_t *share)
|
||||||
|
|
||||||
detLog("write_out_vid: " + vidOut, share);
|
detLog("write_out_vid: " + vidOut, share);
|
||||||
detLog("write_out_img: " + imgOut, share);
|
detLog("write_out_img: " + imgOut, share);
|
||||||
detLog("remove_file: " + buffFile, share);
|
|
||||||
|
|
||||||
enforceMaxClips(outDir, share);
|
enforceMaxClips(outDir, share);
|
||||||
|
|
||||||
|
@ -73,10 +91,15 @@ void wrOut(const string &buffFile, const Mat &vidThumb, shared_t *share)
|
||||||
genHTMLvid(vidOut, share);
|
genHTMLvid(vidOut, share);
|
||||||
genHTMLul(outDir, share->camName + ": " + dayStr, share);
|
genHTMLul(outDir, share->camName + ": " + dayStr, share);
|
||||||
genHTMLul(share->outDir, share->camName, share);
|
genHTMLul(share->outDir, share->camName, share);
|
||||||
|
|
||||||
|
detLog("wr_out() -- finished()", share);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool moDetect(const string &buffFile, Mat &vidThumb, shared_t *share)
|
bool moDetect(const string &buffFile, Mat &vidThumb, shared_t *share)
|
||||||
{
|
{
|
||||||
|
detLog("mo_detect() -- start()", share);
|
||||||
|
detLog("buff_file: " + buffFile, share);
|
||||||
|
|
||||||
auto mod = false;
|
auto mod = false;
|
||||||
|
|
||||||
VideoCapture capture(buffFile.c_str());
|
VideoCapture capture(buffFile.c_str());
|
||||||
|
@ -100,24 +123,21 @@ bool moDetect(const string &buffFile, Mat &vidThumb, shared_t *share)
|
||||||
{
|
{
|
||||||
resize(next, vidThumb, Size(1280, 720), INTER_LINEAR);
|
resize(next, vidThumb, Size(1280, 720), INTER_LINEAR);
|
||||||
|
|
||||||
if (diff > maxDiff)
|
mod = true;
|
||||||
{
|
|
||||||
maxDiff = diff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mod = true; break;
|
frameGaps += share->frameGap;
|
||||||
}
|
|
||||||
|
|
||||||
frameGaps++;
|
detLog("frame_gap: " + to_string(frameGaps), share);
|
||||||
}
|
}
|
||||||
while (!prev.empty() && !next.empty());
|
while (!prev.empty() && !next.empty() && !mod);
|
||||||
|
|
||||||
detLog("scanned_buff_file = " + buffFile + " max_score = " + to_string(maxDiff) + " frame_gaps = " + to_string(frameGaps), share);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
detLog("failed to open buff file: " + buffFile + " for reading. check permissions and/or opencv's video-io support (gstreamer/ffmpeg).", share);
|
detLog("failed to open the buff file for reading. check permissions and/or opencv's video-io support (gstreamer/ffmpeg).", share);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
detLog("mo_detect() -- finished()", share);
|
||||||
|
|
||||||
return mod;
|
return mod;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user