diff --git a/src/common.cpp b/src/common.cpp index a555219..654e6ff 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -202,7 +202,6 @@ bool rdConf(shared_t *share) share->buffDir = "/tmp"; share->vidExt = "mp4"; share->vidCodec = "copy"; - share->recLoopWait = false; share->skipCmd = false; share->webBg = "#485564"; share->webTxt = "#dee5ee"; @@ -284,3 +283,13 @@ string parseForParam(const string &arg, int argc, char** argv, bool argOnly) return string(); } + +void waitForDetThreads(shared_t *share) +{ + for (auto &&thr : share->detThreads) + { + thr.join(); + } + + share->detThreads.clear(); +} diff --git a/src/common.h b/src/common.h index b347b3a..95f22c7 100644 --- a/src/common.h +++ b/src/common.h @@ -35,40 +35,38 @@ using namespace cv; using namespace std; using namespace std::filesystem; -#define APP_VER "1.5.t15" +#define APP_VER "1.5.t16" #define APP_NAME "Motion Watch" struct shared_t { - - ofstream recLogFile; - ofstream detLogFile; - string recLogPath; - string detLogPath; - string recordUrl; - string outDir; - string postCmd; - string conf; - string buffDir; - string vidExt; - string vidCodec; - string camName; - string webBg; - string webTxt; - string webFont; - string webRoot; - bool init; - bool recLoopWait; - bool logRun; - bool skipCmd; - int frameGap; - int pixThresh; - int imgThresh; - int secs; - int maxDays; - int maxClips; - int maxLogSize; - int retCode; + vector detThreads; + ofstream recLogFile; + ofstream detLogFile; + string recLogPath; + string detLogPath; + string recordUrl; + string outDir; + string postCmd; + string conf; + string buffDir; + string vidExt; + string vidCodec; + string camName; + string webBg; + string webTxt; + string webFont; + string webRoot; + bool init; + bool skipCmd; + int frameGap; + int pixThresh; + int imgThresh; + int secs; + int maxDays; + int maxClips; + int maxLogSize; + int retCode; }; string genDstFile(const string &dirOut, const char *fmt, const string &ext); @@ -82,6 +80,7 @@ void enforceMaxClips(const string &dirPath, shared_t *share); void rdLine(const string ¶m, const string &line, string *value); void rdLine(const string ¶m, const string &line, int *value); void statOut(shared_t *share); +void waitForDetThreads(shared_t *share); bool rdConf(shared_t *share); vector lsFilesInDir(const string &path, const string &ext = string()); vector lsDirsInDir(const string &path); diff --git a/src/main.cpp b/src/main.cpp index ea53f73..9cff0f6 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,57 +13,24 @@ #include "mo_detect.h" #include "logger.h" -void detectLoop(shared_t *share) +void detectMoInFile(const string &bufPath, shared_t *share) { - detLog("detect_loop() -- start", share); + detLog("detect_mo_in_file() -- start", share); - vector bufFiles; - auto waitingForFiles = 0; + Mat thumbNail; - do + if (moDetect(bufPath, thumbNail, share)) { - bufFiles = lsFilesInDir(share->buffDir, "." + share->vidExt); + share->skipCmd = true; - // this loop will not process the last buffile while recLoop is still actively - // pulling footage from ffmpeg. it is assumed the last file is not finished. - // share->recLoopWait is used to detect if the recloop is still pulling. if not - // then the last file is finally processed. - - if ((bufFiles.size() >= 2) || (share->recLoopWait && !bufFiles.empty())) - { - auto fullPath = cleanDir(share->buffDir) + "/" + bufFiles[0]; - Mat thumbNail; - - if (moDetect(fullPath, thumbNail, share)) - { - share->skipCmd = true; - - wrOut(fullPath, thumbNail, share); - } - else if (exists(fullPath)) - { - remove(fullPath); - } - } - else - { - if (waitingForFiles >= share->secs) - { - detLog("timed out waiting for buff files from ffmpeg, did it fail?", share); - - break; - } - else - { - detLog(to_string(bufFiles.size()) + " buff file(s) found, waiting for more.", share); - } - - sleep(5); waitingForFiles += 5; - } + wrOut(bufPath, thumbNail, share); + } + else if (exists(bufPath)) + { + remove(bufPath); } - while (!share->recLoopWait || !bufFiles.empty()); - detLog("detect_loop() -- finished", share); + detLog("detect_mo_in_file() -- finished", share); } void recLoop(shared_t *share) @@ -99,29 +66,39 @@ void recLoop(shared_t *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); - auto limSecs = to_string(share->secs + 3); - auto cmd = "timeout -k 1 " + limSecs + " ffmpeg -hide_banner -i " + share->recordUrl + " -y -vcodec " + share->vidCodec + " -movflags faststart -map 0 -segment_time 00:00:10 -f segment -t " + secs + " " + bufPath; + for (auto i = 0; i < share->secs; i += 10) + { + auto bufPath = cleanDir(share->buffDir) + "/" + to_string(i) + "." + share->vidExt; + auto cmd = "ffmpeg -hide_banner -i " + share->recordUrl + " -y vcodec " + share->vidCodec + " -movflags faststart -t 10 " + bufPath; - thread th2(detectLoop, share); + recLog("ffmpeg_run: " + cmd, share); - recLog("detect_loop() -- started in a seperate thread.", share); - recLog("ffmpeg_run: " + cmd, share); + auto retCode = system(cmd.c_str()); - auto retCode = system(cmd.c_str()); + recLog("ffmpeg_retcode: " + to_string(retCode), share); - recLog("ffmpeg_retcode: " + to_string(retCode), share); + if (retCode == 0) + { + recLog("detect_mo_in_file() -- started in a seperate thread.", share); - share->recLoopWait = true; + share->detThreads.push_back(thread(detectMoInFile, bufPath, share)); + } + else + { + recLog("ffmpeg returned non zero, indicating failure. please check stderr output.", share); - th2.join(); + if (exists(bufPath)) + { + remove(bufPath); + } + } + } - recLog("detect_loop() -- thread finished.", share); + waitForDetThreads(share); if (!share->skipCmd) { - recLog("motion not detected by the detection loop.", share); + recLog("no motion detected", share); if (share->postCmd.empty()) { @@ -135,7 +112,7 @@ void recLoop(shared_t *share) } else { - recLog("motion detected by the detection loop, skipping the post command.", share); + recLog("motion detected, skipping the post command.", share); } recLog("rec_loop() -- finished", share); @@ -171,11 +148,9 @@ int main(int argc, char** argv) } else { - sharedRes.retCode = 0; - sharedRes.recLoopWait = false; - sharedRes.skipCmd = false; - sharedRes.init = true; - sharedRes.logRun = true; + sharedRes.retCode = 0; + sharedRes.skipCmd = false; + sharedRes.init = true; recLoop(&sharedRes); diff --git a/src/mo_detect.cpp b/src/mo_detect.cpp index 86b0b83..44201ee 100644 --- a/src/mo_detect.cpp +++ b/src/mo_detect.cpp @@ -123,7 +123,7 @@ bool moDetect(const string &buffFile, Mat &vidThumb, shared_t *share) if (imgDiff(prev, next, share)) { - resize(next, vidThumb, Size(1280, 720), INTER_LINEAR); + resize(next, vidThumb, Size(720, 480), INTER_LINEAR); mod = true; break; }