implemented graceful program termination and proper error reporting

pull/3471/head
kallaballa 1 year ago
parent 83a63ab17f
commit 9210ff6603
  1. 20
      modules/v4d/include/opencv2/v4d/util.hpp
  2. 20
      modules/v4d/include/opencv2/v4d/v4d.hpp
  3. 4
      modules/v4d/src/detail/sourcecontext.cpp
  4. 16
      modules/v4d/src/v4d.cpp

@ -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<std::mutex> 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<std::mutex> lock(mtx);
return next_worker_idx_++;
}
};

@ -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()) {

@ -25,7 +25,7 @@ void SourceContext::execute(std::function<void()> 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<void()> 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);

@ -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<V4D>(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;
{

Loading…
Cancel
Save