From 1c20855f29274068d9d0570b2df776ac423445ea Mon Sep 17 00:00:00 2001 From: Kees-V Date: Wed, 22 Oct 2014 14:08:55 +0200 Subject: [PATCH 1/9] Only lock when needed. --- src/video/videobuffer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video/videobuffer.cpp b/src/video/videobuffer.cpp index d9daa35..5a17391 100644 --- a/src/video/videobuffer.cpp +++ b/src/video/videobuffer.cpp @@ -154,7 +154,6 @@ void getALPRImages(cv::VideoCapture cap, VideoDispatcher* dispatcher) while (dispatcher->active) { - dispatcher->mMutex.lock(); bool hasImage = false; try { @@ -162,15 +161,16 @@ void getALPRImages(cv::VideoCapture cap, VideoDispatcher* dispatcher) // Double check the image to make sure it's valid. if (!frame.data || frame.empty()) { - dispatcher->mMutex.unlock(); std::stringstream ss; ss << "Stream " << dispatcher->mjpeg_url << " received invalid frame"; dispatcher->log_error(ss.str()); return; } + dispatcher->mMutex.lock(); dispatcher->setLatestFrame(&frame); - } + dispatcher->mMutex.unlock(); + } catch (const std::runtime_error& error) { // Error occured while trying to gather image. Retry, don't exit. From eebc707f2b662698b97782024db235d4f2e2cf24 Mon Sep 17 00:00:00 2001 From: Kees-V Date: Wed, 22 Oct 2014 14:23:50 +0200 Subject: [PATCH 2/9] Status information when connecting to stream --- src/video/videobuffer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/video/videobuffer.cpp b/src/video/videobuffer.cpp index 5a17391..cdaec56 100644 --- a/src/video/videobuffer.cpp +++ b/src/video/videobuffer.cpp @@ -105,11 +105,13 @@ void imageCollectionThread(void* arg) try { cv::VideoCapture cap=cv::VideoCapture(); - cap.open(dispatcher->mjpeg_url); + std::cout << "Connecting..." << std::endl; + cap.open(dispatcher->mjpeg_url); if (cap.isOpened()) { - getALPRImages(cap, dispatcher); + std::cout << "Connected" << std::endl; + getALPRImages(cap, dispatcher); } else { From 752e9acc6f6d040ed15f42ac6550de103a0d4993 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Wed, 22 Oct 2014 21:14:06 -0400 Subject: [PATCH 3/9] Moved output messages to log handler --- src/video/videobuffer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/videobuffer.cpp b/src/video/videobuffer.cpp index cdaec56..301c621 100644 --- a/src/video/videobuffer.cpp +++ b/src/video/videobuffer.cpp @@ -105,13 +105,13 @@ void imageCollectionThread(void* arg) try { cv::VideoCapture cap=cv::VideoCapture(); - std::cout << "Connecting..." << std::endl; - cap.open(dispatcher->mjpeg_url); + dispatcher->log_info("Video stream connecting..."); + cap.open(dispatcher->mjpeg_url); if (cap.isOpened()) { - std::cout << "Connected" << std::endl; - getALPRImages(cap, dispatcher); + dispatcher->log_info("Video stream connected"); + getALPRImages(cap, dispatcher); } else { From 686743484cd903b60e4f508577704b0200ad28b3 Mon Sep 17 00:00:00 2001 From: Kees-V Date: Sat, 25 Oct 2014 14:22:50 +0200 Subject: [PATCH 4/9] Revert "Only lock when needed." This reverts commit 1c20855f29274068d9d0570b2df776ac423445ea. --- src/video/videobuffer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video/videobuffer.cpp b/src/video/videobuffer.cpp index cdaec56..9994874 100644 --- a/src/video/videobuffer.cpp +++ b/src/video/videobuffer.cpp @@ -156,6 +156,7 @@ void getALPRImages(cv::VideoCapture cap, VideoDispatcher* dispatcher) while (dispatcher->active) { + dispatcher->mMutex.lock(); bool hasImage = false; try { @@ -163,16 +164,15 @@ void getALPRImages(cv::VideoCapture cap, VideoDispatcher* dispatcher) // Double check the image to make sure it's valid. if (!frame.data || frame.empty()) { + dispatcher->mMutex.unlock(); std::stringstream ss; ss << "Stream " << dispatcher->mjpeg_url << " received invalid frame"; dispatcher->log_error(ss.str()); return; } - dispatcher->mMutex.lock(); dispatcher->setLatestFrame(&frame); - dispatcher->mMutex.unlock(); - } + } catch (const std::runtime_error& error) { // Error occured while trying to gather image. Retry, don't exit. From 528b548b11a8467068c214e4dff32a2bdbb1023d Mon Sep 17 00:00:00 2001 From: Kees-V Date: Sun, 26 Oct 2014 10:56:09 +0100 Subject: [PATCH 5/9] Enhancement to video stream input thread --- src/video/videobuffer.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/video/videobuffer.cpp b/src/video/videobuffer.cpp index 9994874..aeff204 100644 --- a/src/video/videobuffer.cpp +++ b/src/video/videobuffer.cpp @@ -149,30 +149,36 @@ void imageCollectionThread(void* arg) // it returns so that the video capture can be recreated. void getALPRImages(cv::VideoCapture cap, VideoDispatcher* dispatcher) { - cv::Mat frame; - + cv::Mat frame1; + cv::Mat frame2; + cv::Mat* receiveframe; + BOOLEAN receiveframeisframe1 = TRUE; + while (dispatcher->active) { while (dispatcher->active) { - dispatcher->mMutex.lock(); bool hasImage = false; try { - hasImage = cap.read(frame); - // Double check the image to make sure it's valid. - if (!frame.data || frame.empty()) + if (receiveframeisframe1) receiveframe = &frame1; + else receiveframe = &frame2; + hasImage = cap.read(*receiveframe); + // Double check the image to make sure it's valid. + if (!(*receiveframe).data || (*receiveframe).empty()) { - dispatcher->mMutex.unlock(); std::stringstream ss; ss << "Stream " << dispatcher->mjpeg_url << " received invalid frame"; dispatcher->log_error(ss.str()); return; } - dispatcher->setLatestFrame(&frame); - } + dispatcher->mMutex.lock(); + dispatcher->setLatestFrame(receiveframe); + dispatcher->mMutex.unlock(); + receiveframeisframe1 = !receiveframeisframe1; + } catch (const std::runtime_error& error) { // Error occured while trying to gather image. Retry, don't exit. From f1e5e7932ccbe3f962ee02714368f8a8d06f4361 Mon Sep 17 00:00:00 2001 From: Kees-V Date: Sun, 26 Oct 2014 11:13:14 +0100 Subject: [PATCH 6/9] Changed BOOLEAN to bool --- src/video/videobuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/videobuffer.cpp b/src/video/videobuffer.cpp index aeff204..831a85c 100644 --- a/src/video/videobuffer.cpp +++ b/src/video/videobuffer.cpp @@ -152,7 +152,7 @@ void getALPRImages(cv::VideoCapture cap, VideoDispatcher* dispatcher) cv::Mat frame1; cv::Mat frame2; cv::Mat* receiveframe; - BOOLEAN receiveframeisframe1 = TRUE; + bool receiveframeisframe1 = TRUE; while (dispatcher->active) { From 77e308904cf075eb6ad9b963ed6263fe689c3095 Mon Sep 17 00:00:00 2001 From: Kees-V Date: Sun, 26 Oct 2014 11:22:29 +0100 Subject: [PATCH 7/9] Travis Cl build: changed TRUE to true --- src/video/videobuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/videobuffer.cpp b/src/video/videobuffer.cpp index 831a85c..2b256ee 100644 --- a/src/video/videobuffer.cpp +++ b/src/video/videobuffer.cpp @@ -152,7 +152,7 @@ void getALPRImages(cv::VideoCapture cap, VideoDispatcher* dispatcher) cv::Mat frame1; cv::Mat frame2; cv::Mat* receiveframe; - bool receiveframeisframe1 = TRUE; + bool receiveframeisframe1 = true; while (dispatcher->active) { From 2e95b0dd9e3d89a5b9f0c8b6ff6b3c5f6abe6c42 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Sun, 26 Oct 2014 20:36:49 -0400 Subject: [PATCH 8/9] Tweaked videobuffer to support using video files (for testing) --- src/video/videobuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/videobuffer.cpp b/src/video/videobuffer.cpp index d5363be..17c47c6 100644 --- a/src/video/videobuffer.cpp +++ b/src/video/videobuffer.cpp @@ -46,7 +46,7 @@ VideoDispatcher* VideoBuffer::createDispatcher(std::string mjpeg_url, int fps) void VideoBuffer::connect(std::string mjpeg_url, int fps) { - if (hasEnding(mjpeg_url, ".mjpg") == false) + if (startsWith(mjpeg_url, "http") && hasEnding(mjpeg_url, ".mjpg") == false) { // The filename doesn't end with ".mjpg" so the downstream processing may not treat it as such // OpenCV doesn't have a way to force the rendering, other than via URL path. So, let's add it to the URL From 9ccb8d7a8ebac1c5b98f93f4bf43ffb3074cceb3 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Sun, 26 Oct 2014 20:37:15 -0400 Subject: [PATCH 9/9] Simplified videobuffer usage by copying all the buffer data -- reduces chances of memory issues across threads. --- src/video/videobuffer.cpp | 16 +++++----------- src/video/videobuffer.h | 15 +++++++-------- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/video/videobuffer.cpp b/src/video/videobuffer.cpp index 17c47c6..8dc13c0 100644 --- a/src/video/videobuffer.cpp +++ b/src/video/videobuffer.cpp @@ -149,10 +149,6 @@ void imageCollectionThread(void* arg) // it returns so that the video capture can be recreated. void getALPRImages(cv::VideoCapture cap, VideoDispatcher* dispatcher) { - cv::Mat frame1; - cv::Mat frame2; - cv::Mat* receiveframe; - bool receiveframeisframe1 = true; while (dispatcher->active) { @@ -162,11 +158,10 @@ void getALPRImages(cv::VideoCapture cap, VideoDispatcher* dispatcher) bool hasImage = false; try { - if (receiveframeisframe1) receiveframe = &frame1; - else receiveframe = &frame2; - hasImage = cap.read(*receiveframe); + cv::Mat frame; + hasImage = cap.read(frame); // Double check the image to make sure it's valid. - if (!(*receiveframe).data || (*receiveframe).empty()) + if (!frame.data || frame.empty()) { std::stringstream ss; ss << "Stream " << dispatcher->mjpeg_url << " received invalid frame"; @@ -175,10 +170,9 @@ void getALPRImages(cv::VideoCapture cap, VideoDispatcher* dispatcher) } dispatcher->mMutex.lock(); - dispatcher->setLatestFrame(receiveframe); + dispatcher->setLatestFrame(frame); dispatcher->mMutex.unlock(); - receiveframeisframe1 = !receiveframeisframe1; - } + } catch (const std::runtime_error& error) { // Error occured while trying to gather image. Retry, don't exit. diff --git a/src/video/videobuffer.h b/src/video/videobuffer.h index c5afbc0..4954f52 100644 --- a/src/video/videobuffer.h +++ b/src/video/videobuffer.h @@ -31,10 +31,10 @@ class VideoDispatcher tthread::lock_guard guard(mMutex); if (latestFrameNumber == lastFrameRead) - return -1; + return -1; - frame->create(latestFrame->size(), latestFrame->type()); - latestFrame->copyTo(*frame); + frame->create(latestFrame.size(), latestFrame.type()); + latestFrame.copyTo(*frame); this->lastFrameRead = this->latestFrameNumber; @@ -45,11 +45,10 @@ class VideoDispatcher return this->lastFrameRead; } - void setLatestFrame(cv::Mat* frame) + void setLatestFrame(cv::Mat frame) { - //tthread::lock_guard guard(mMutex); - this->latestFrame = frame; - this->latestRegionsOfInterest = calculateRegionsOfInterest(frame); + frame.copyTo(this->latestFrame); + this->latestRegionsOfInterest = calculateRegionsOfInterest(&this->latestFrame); this->latestFrameNumber++; } @@ -83,7 +82,7 @@ class VideoDispatcher tthread::mutex mMutex; private: - cv::Mat* latestFrame; + cv::Mat latestFrame; std::vector latestRegionsOfInterest; };