From c153fdcd21ab592f8bc3e48dd5787d668d39393d Mon Sep 17 00:00:00 2001 From: Maurice ONeal Date: Fri, 16 Dec 2022 18:24:18 -0500 Subject: [PATCH] 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." --- src/common.cpp | 30 +++++++++++++------------- src/common.h | 2 +- src/main.cpp | 45 ++++++++++++++++++--------------------- src/mo_detect.cpp | 54 ++++++++++++++++++++++++++++++++--------------- 4 files changed, 74 insertions(+), 57 deletions(-) diff --git a/src/common.cpp b/src/common.cpp index 71d5f70..6a6e51c 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -111,20 +111,20 @@ void enforceMaxDays(const string &dirPath, shared_t *share) void enforceMaxClips(const string &dirPath, shared_t *share) { - auto names = lsDirsInDir(dirPath); + auto names = lsFilesInDir(dirPath, "." + share->vidExt); - // note: this function assumes all video clips are accompanied by - // .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)) + while (names.size() > share->maxClips) { - remove(string(cleanDir(dirPath) + "/" + names[0]).c_str()); - remove(string(cleanDir(dirPath) + "/" + names[1]).c_str()); - remove(string(cleanDir(dirPath) + "/" + names[2]).c_str()); + // removes the video file extension. + auto nameOnly = names[0].substr(0, names[0].size() - (share->vidExt.size() + 1)); + 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()); } } @@ -191,12 +191,12 @@ bool rdConf(shared_t *share) share->retCode = 0; share->frameGap = 10; - share->pixThresh = 30; - share->imgThresh = 512; + share->pixThresh = 150; + share->imgThresh = 1024; share->secs = 60; share->maxDays = 15; share->maxClips = 30; - share->maxLogSize = 10000; + share->maxLogSize = 50000; share->camName = path(share->conf.c_str()).filename(); share->webRoot = "/var/www/html"; share->vidExt = "mp4"; @@ -242,7 +242,7 @@ bool rdConf(shared_t *share) { remove_all(share->buffDir); } - + share->init = false; } diff --git a/src/common.h b/src/common.h index d673bfc..dec0cb8 100644 --- a/src/common.h +++ b/src/common.h @@ -35,7 +35,7 @@ using namespace cv; using namespace std; using namespace std::filesystem; -#define APP_VER "1.5.t9" +#define APP_VER "1.5.t10" #define APP_NAME "Motion Watch" struct shared_t diff --git a/src/main.cpp b/src/main.cpp index 4113479..abb1a3e 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,7 +15,7 @@ void detectLoop(shared_t *share) { - detLog("detectLoop() -- start", share); + detLog("detect_loop() -- start", share); vector bufFiles; auto waitingForFiles = 0; @@ -32,24 +32,17 @@ void detectLoop(shared_t *share) if ((bufFiles.size() >= 2) || (share->recLoopWait && !bufFiles.empty())) { auto fullPath = cleanDir(share->buffDir) + "/" + bufFiles[0]; - - Mat thumbNail; + Mat thumbNail; if (moDetect(fullPath, thumbNail, share)) { share->skipCmd = true; - detLog("motion detected in file: " + fullPath, 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 @@ -60,19 +53,25 @@ void detectLoop(shared_t *share) 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) { while (rdConf(share)) { + recLog("rec_loop() -- start", share); + enforceMaxLogSize(share->recLogPath, share); enforceMaxLogSize(share->detLogPath, share); @@ -81,28 +80,24 @@ void recLoop(shared_t *share) initLogFrontPages(share); - recLog("recLoop() -- start", share); - 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"); genCSS(share); genHTMLul(share->webRoot, string(APP_NAME) + " " + string(APP_VER), share); remove("/tmp/mow-lock"); + recLog("webroot page updated: " + cleanDir(share->webRoot) + "/index.html", share); } 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); - 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 secs = to_string(share->secs); @@ -111,7 +106,7 @@ void recLoop(shared_t *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); auto retCode = system(cmd.c_str()); @@ -122,6 +117,8 @@ void recLoop(shared_t *share) th2.join(); + recLog("detect_loop() -- thread finished.", share); + if (!share->skipCmd) { recLog("motion not detected by the detection loop.", share); @@ -132,7 +129,7 @@ void recLoop(shared_t *share) } else { - recLog("running post command = " + share->postCmd, share); + recLog("running post command: " + share->postCmd, share); 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("recLoop() -- finished", share); + recLog("rec_loop() -- finished", share); if (share->retCode != 0) { diff --git a/src/mo_detect.cpp b/src/mo_detect.cpp index 37df853..9b70338 100644 --- a/src/mo_detect.cpp +++ b/src/mo_detect.cpp @@ -14,14 +14,30 @@ bool imgDiff(const Mat &prev, const Mat &next, int &diffScore, shared_t *share) { - Mat diff; + auto ret = false; - absdiff(prev, next, diff); - threshold(diff, diff, share->pixThresh, 255, THRESH_BINARY); + detLog("img_diff() -- start()", share); - diffScore = countNonZero(diff); + 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); - return diffScore >= share->imgThresh; + if (!prev.empty() && !next.empty()) + { + Mat diff; + + absdiff(prev, next, diff); + threshold(diff, diff, share->pixThresh, 255, THRESH_BINARY); + + diffScore = countNonZero(diff); + + detLog("diff_score: " + to_string(diffScore), share); + + ret = diffScore >= share->imgThresh; + } + + detLog("img_diff() -- finished()", share); + + return ret; } 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) { + detLog("wr_out() -- start()", share); + detLog("buff_file: " + buffFile, share); + auto dayStr = genTimeStr("%Y-%m-%d"); auto timStr = genTimeStr("%H%M%S"); 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_img: " + imgOut, share); - detLog("remove_file: " + buffFile, share); enforceMaxClips(outDir, share); @@ -73,10 +91,15 @@ void wrOut(const string &buffFile, const Mat &vidThumb, shared_t *share) genHTMLvid(vidOut, share); genHTMLul(outDir, share->camName + ": " + dayStr, share); genHTMLul(share->outDir, share->camName, share); + + detLog("wr_out() -- finished()", share); } bool moDetect(const string &buffFile, Mat &vidThumb, shared_t *share) { + detLog("mo_detect() -- start()", share); + detLog("buff_file: " + buffFile, share); + auto mod = false; 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); - if (diff > maxDiff) - { - maxDiff = diff; - } - - mod = true; break; + mod = true; } - frameGaps++; - } - while (!prev.empty() && !next.empty()); + frameGaps += share->frameGap; - detLog("scanned_buff_file = " + buffFile + " max_score = " + to_string(maxDiff) + " frame_gaps = " + to_string(frameGaps), share); + detLog("frame_gap: " + to_string(frameGaps), share); + } + while (!prev.empty() && !next.empty() && !mod); } 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; }