From b3ff1a4dab858fcd49de00b0cc662e6881e8b77a Mon Sep 17 00:00:00 2001 From: kallaballa Date: Tue, 26 Sep 2023 19:56:31 +0200 Subject: [PATCH] implement async and threadsafe mode for source --- .../opencv2/v4d/detail/framebuffercontext.hpp | 4 +-- modules/v4d/include/opencv2/v4d/source.hpp | 3 +- modules/v4d/src/detail/framebuffercontext.cpp | 29 +++++++------------ modules/v4d/src/source.cpp | 8 +++-- modules/v4d/src/v4d.cpp | 28 ++++++++++-------- 5 files changed, 37 insertions(+), 35 deletions(-) diff --git a/modules/v4d/include/opencv2/v4d/detail/framebuffercontext.hpp b/modules/v4d/include/opencv2/v4d/detail/framebuffercontext.hpp index ede333480..5ffdc363a 100644 --- a/modules/v4d/include/opencv2/v4d/detail/framebuffercontext.hpp +++ b/modules/v4d/include/opencv2/v4d/detail/framebuffercontext.hpp @@ -111,8 +111,8 @@ class CV_EXPORTS FrameBufferContext { std::map copyTextures_; int index_; - void* current_sync_object_ = 0; - bool first_sync_ = true; + void* currentSyncObject_ = 0; + bool firstSync_ = true; public: /*! * Acquires and releases the framebuffer from and to OpenGL. diff --git a/modules/v4d/include/opencv2/v4d/source.hpp b/modules/v4d/include/opencv2/v4d/source.hpp index 63a926f6c..79503b0c3 100644 --- a/modules/v4d/include/opencv2/v4d/source.hpp +++ b/modules/v4d/include/opencv2/v4d/source.hpp @@ -34,7 +34,7 @@ public: * that it manipulates. This is ultimatively used to provide video data to #cv::viz::V4D * @param fps The fps the Source object provides data with. */ - CV_EXPORTS Source(std::function generator, float fps, bool async = true); + CV_EXPORTS Source(std::function generator, float fps); /*! * Constructs a null Source that is never open or ready. */ @@ -49,6 +49,7 @@ public: */ CV_EXPORTS bool isReady(); CV_EXPORTS bool isAsync(); + CV_EXPORTS void setAsync(bool as); CV_EXPORTS bool isThreadSafe(); CV_EXPORTS void setThreadSafe(bool ts); diff --git a/modules/v4d/src/detail/framebuffercontext.cpp b/modules/v4d/src/detail/framebuffercontext.cpp index 3b6d10cde..2765d9711 100644 --- a/modules/v4d/src/detail/framebuffercontext.cpp +++ b/modules/v4d/src/detail/framebuffercontext.cpp @@ -686,7 +686,7 @@ void FrameBufferContext::blitFrameBufferToFrameBuffer(const cv::Rect& srcViewpor void FrameBufferContext::begin(GLenum framebufferTarget) { this->makeCurrent(); - CV_Assert(this->wait() == true); + CV_Assert(this->wait(1000000000) == true); GL_CHECK(glBindFramebuffer(framebufferTarget, frameBufferID_)); GL_CHECK(glBindTexture(GL_TEXTURE_2D, textureID_)); GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, renderBufferID_)); @@ -876,29 +876,22 @@ void FrameBufferContext::fence() { } bool FrameBufferContext::wait(const uint64_t& timeout) { - if(first_sync_) { + if(firstSync_) { currentSyncObject_ = 0; - first_sync_ = false; + firstSync_ = false; return true; } CV_Assert(currentSyncObject_ != 0); - if (timeout > 0) { - GLuint ret = glClientWaitSync(static_cast(currentSyncObject_), - GL_SYNC_FLUSH_COMMANDS_BIT, timeout); - GL_CHECK(); - CV_Assert(GL_ALREADY_SIGNALED != ret); - CV_Assert(GL_WAIT_FAILED != ret); - if(GL_CONDITION_SATISFIED == ret) { - currentSyncObject_ = 0; - return true; - } else { - currentSyncObject_ = 0; - return false; - } - } else { - GL_CHECK(glWaitSync(static_cast(currentSyncObject_), 0, GL_TIMEOUT_IGNORED)); + GLuint ret = glClientWaitSync(static_cast(currentSyncObject_), + GL_SYNC_FLUSH_COMMANDS_BIT, timeout); + GL_CHECK(); + CV_Assert(GL_WAIT_FAILED != ret); + if(GL_CONDITION_SATISFIED == ret || GL_ALREADY_SIGNALED == ret) { currentSyncObject_ = 0; return true; + } else { + currentSyncObject_ = 0; + return false; } } } diff --git a/modules/v4d/src/source.cpp b/modules/v4d/src/source.cpp index 9442985e8..52c7a621c 100644 --- a/modules/v4d/src/source.cpp +++ b/modules/v4d/src/source.cpp @@ -8,8 +8,8 @@ namespace cv { namespace v4d { -Source::Source(std::function generator, float fps, bool async) : - generator_(generator), fps_(fps), async_(async) { +Source::Source(std::function generator, float fps) : + generator_(generator), fps_(fps) { } Source::Source() : @@ -34,6 +34,10 @@ bool Source::isAsync() { return async_; } +void Source::setAsync(bool as) { + async_ = as; +} + bool Source::isThreadSafe() { return threadSafe_; } diff --git a/modules/v4d/src/v4d.cpp b/modules/v4d/src/v4d.cpp index 7d88ccd96..93df66163 100644 --- a/modules/v4d/src/v4d.cpp +++ b/modules/v4d/src/v4d.cpp @@ -300,8 +300,8 @@ cv::_InputArray V4D::fetch() { } bool V4D::capture() { - if(source_) { - if(source_->isAsync()) { + if (source_) { + if (source_->isAsync()) { return this->capture([this](cv::UMat& videoFrame) { if (source_->isReady()) { auto p = source_->operator()(); @@ -310,17 +310,21 @@ bool V4D::capture() { } }); } else { - if(source_->fps() > 0) { - fb([this](cv::UMat& frameBuffer){ - if (source_->isReady()) { - auto p = source_->operator()(); - currentSeqNr_ = p.first; - p.second.copyTo(frameBuffer); - } - }); + if (source_->isReady()) { + if (source_->fps() > 0) { + auto p = source_->operator()(); + currentSeqNr_ = p.first; + feed(p.second); + } else { + auto p = source_->operator()(); + currentSeqNr_ = p.first; + } } else { - auto p = source_->operator()(); - currentSeqNr_ = p.first; +#ifndef __EMSCRIPTEN__ + return false; +#else + return true; +#endif } return true;