From 9210ff6603d2bf565b259f36b8f7f63e8343bdcb Mon Sep 17 00:00:00 2001 From: kallaballa Date: Mon, 6 Nov 2023 07:05:21 +0100 Subject: [PATCH] implemented graceful program termination and proper error reporting --- modules/v4d/include/opencv2/v4d/util.hpp | 20 +++++++++++++++----- modules/v4d/include/opencv2/v4d/v4d.hpp | 20 ++++++-------------- modules/v4d/src/detail/sourcecontext.cpp | 4 ++-- modules/v4d/src/v4d.cpp | 16 +++++++++++----- 4 files changed, 34 insertions(+), 26 deletions(-) diff --git a/modules/v4d/include/opencv2/v4d/util.hpp b/modules/v4d/include/opencv2/v4d/util.hpp index 127130e9b..d9d32e8c2 100644 --- a/modules/v4d/include/opencv2/v4d/util.hpp +++ b/modules/v4d/include/opencv2/v4d/util.hpp @@ -57,7 +57,8 @@ class CV_EXPORTS Global { inline static std::thread::id main_thread_id_; inline static thread_local bool is_main_; inline static size_t workers_ready_ = 0; - inline static size_t workers_running_ = 0; + inline static size_t workers_started_ = 0; + inline static size_t next_worker_idx_ = 0; public: CV_EXPORTS static std::mutex& mutex() { return mtx_; @@ -86,6 +87,7 @@ public: CV_EXPORTS static const std::thread::id& default_id() { return default_thread_id_; } + CV_EXPORTS static std::thread::id& main_id() { return main_thread_id_; } @@ -95,12 +97,20 @@ public: return is_main_; } - CV_EXPORTS static size_t& workers_ready() { - return workers_ready_; + CV_EXPORTS static size_t& workers_started() { + return workers_started_; + } + + CV_EXPORTS static size_t next_worker_ready() { + static std::mutex mtx; + std::unique_lock lock(mtx); + return ++workers_ready_; } - CV_EXPORTS static size_t& workers_running() { - return workers_running_; + CV_EXPORTS static size_t next_worker_idx() { + static std::mutex mtx; + std::unique_lock lock(mtx); + return next_worker_idx_++; } }; diff --git a/modules/v4d/include/opencv2/v4d/v4d.hpp b/modules/v4d/include/opencv2/v4d/v4d.hpp index e8a94a0d0..15ab0cac3 100644 --- a/modules/v4d/include/opencv2/v4d/v4d.hpp +++ b/modules/v4d/include/opencv2/v4d/v4d.hpp @@ -576,6 +576,7 @@ public: bool debug = this->debug_; auto src = this->getSource(); auto sink = this->getSink(); + Global::workers_started() = workers; for (size_t i = 0; i < workers; ++i) { threads.push_back( new std::thread( @@ -596,15 +597,6 @@ public: ) ); } - - - for (int32_t i = 0; i < workers; ++i) { - CV_Assert(i >= 0); - if(!threads[i]->joinable()) { - --i; - std::this_thread::sleep_for(1ms); - } - } } } @@ -620,18 +612,18 @@ public: this->makePlan(); this->runPlan(); this->clearPlan(); - if(!Global::is_main() && Global::workers_running() == Global::workers_ready()) { + if(!Global::is_main() && Global::workers_started() == Global::next_worker_ready()) { cv::utils::logging::setLogLevel(cv::utils::logging::LOG_LEVEL_INFO); } } catch(std::exception& ex) { - CV_Error_(cv::Error::StsError, ("Setup plan failed: %s", ex.what())); + CV_Error_(cv::Error::StsError, ("pipeline setup failed: %s", ex.what())); } if(Global::is_main()) { try { plan->gui(self()); } catch(std::exception& ex) { - CV_Error_(cv::Error::StsError, ("GUI failed: %s", ex.what())); + CV_Error_(cv::Error::StsError, ("GUI setup failed: %s", ex.what())); } } @@ -665,7 +657,7 @@ public: } catch(std::exception& ex) { requestFinish(); reseq.finish(); - CV_Error_(cv::Error::StsError, ("Run plan failed: %s", ex.what())); + CV_LOG_WARNING(nullptr, "-> pipeline terminated: " << ex.what()); } this->clearPlan(); @@ -676,7 +668,7 @@ public: this->runPlan(); this->clearPlan(); } catch(std::exception& ex) { - CV_Error_(cv::Error::StsError, ("Tear-down plan failed: %s", ex.what())); + CV_Error_(cv::Error::StsError, ("pipeline tear-down failed: %s", ex.what())); } if(Global::is_main()) { diff --git a/modules/v4d/src/detail/sourcecontext.cpp b/modules/v4d/src/detail/sourcecontext.cpp index 2a90c25ff..b876305af 100644 --- a/modules/v4d/src/detail/sourcecontext.cpp +++ b/modules/v4d/src/detail/sourcecontext.cpp @@ -25,7 +25,7 @@ void SourceContext::execute(std::function fn) { currentSeqNr_ = p.first; if(p.second.empty()) { - throw std::runtime_error("End of stream"); + CV_Error(cv::Error::StsError, "End of stream"); } resizePreserveAspectRatio(p.second, captureBufferRGB_, mainFbContext_->size()); @@ -42,7 +42,7 @@ void SourceContext::execute(std::function fn) { currentSeqNr_ = p.first; if(p.second.empty()) { - throw std::runtime_error("End of stream"); + CV_Error(cv::Error::StsError, "End of stream"); } resizePreserveAspectRatio(p.second, captureBufferRGB_, mainFbContext_->size()); cv::cvtColor(captureBufferRGB_, sourceBuffer(), cv::COLOR_RGB2BGRA); diff --git a/modules/v4d/src/v4d.cpp b/modules/v4d/src/v4d.cpp index dacb28c57..7b3eded5a 100644 --- a/modules/v4d/src/v4d.cpp +++ b/modules/v4d/src/v4d.cpp @@ -55,7 +55,7 @@ V4D::V4D(const cv::Size& size, const cv::Size& fbsize, const string& title, Allo V4D::V4D(const V4D& other, const string& title) : initialSize_(other.initialSize_), debug_(other.debug_), viewport_(0, 0, other.fbSize().width, other.fbSize().height), stretching_(other.stretching_), samples_(other.samples_) { - workerIdx_ = Global::workers_running()++; + workerIdx_ = Global::next_worker_idx(); self_ = cv::Ptr(this); mainFbContext_ = new detail::FrameBufferContext(*this, other.fbSize(), !other.debug_, title, 3, 2, other.samples_, other.debug_, other.fbCtx()->rootWindow_, other.fbCtx(), true); @@ -81,7 +81,7 @@ const int32_t& V4D::workerIndex() const { } size_t V4D::workers_running() { - return Global::workers_running(); + return Global::workers_started(); } cv::ogl::Texture2D& V4D::texture() { @@ -371,10 +371,16 @@ bool V4D::display() { if (Global::is_main()) { auto start = Global::start_time(); auto now = get_epoch_nanos(); + auto diff = now - start; + double diffSeconds = diff / 1000000000.0; + + if(Global::fps() > 0 && diffSeconds > 1.0) { + Global::start_time() += (diff / 2.0); + Global::frame_cnt() /= 2.0; + } else { + Global::fps() = (Global::fps() * 3.0 + (Global::frame_cnt() / diffSeconds)) / 4.0; + } - double diff_seconds = (now - start) / 1000000000.0; - - Global::fps() = (Global::frame_cnt()) / diff_seconds; if(getPrintFPS()) cerr << "\rFPS:" << Global::fps() << endl; {