summaryrefslogtreecommitdiff
path: root/src/v4l2/v4l2_camera.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/v4l2/v4l2_camera.cpp')
-rw-r--r--src/v4l2/v4l2_camera.cpp34
1 files changed, 31 insertions, 3 deletions
diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp
index 177b1ea5..f7df9b85 100644
--- a/src/v4l2/v4l2_camera.cpp
+++ b/src/v4l2/v4l2_camera.cpp
@@ -18,7 +18,7 @@ LOG_DECLARE_CATEGORY(V4L2Compat);
V4L2Camera::V4L2Camera(std::shared_ptr<Camera> camera)
: camera_(camera), isRunning_(false), bufferAllocator_(nullptr),
- efd_(-1)
+ efd_(-1), bufferAvailableCount_(0)
{
camera_->requestCompleted.connect(this, &V4L2Camera::requestComplete);
}
@@ -100,7 +100,11 @@ void V4L2Camera::requestComplete(Request *request)
if (ret != sizeof(data))
LOG(V4L2Compat, Error) << "Failed to signal eventfd POLLIN";
- bufferSema_.release();
+ {
+ MutexLocker locker(bufferMutex_);
+ bufferAvailableCount_++;
+ }
+ bufferCV_.notify_all();
}
int V4L2Camera::configure(StreamConfiguration *streamConfigOut,
@@ -192,7 +196,11 @@ int V4L2Camera::streamOff()
if (ret < 0)
return ret == -EACCES ? -EBUSY : ret;
- isRunning_ = false;
+ {
+ MutexLocker locker(bufferMutex_);
+ isRunning_ = false;
+ }
+ bufferCV_.notify_all();
return 0;
}
@@ -228,6 +236,26 @@ int V4L2Camera::qbuf(unsigned int index)
return 0;
}
+void V4L2Camera::waitForBufferAvailable()
+{
+ MutexLocker locker(bufferMutex_);
+ bufferCV_.wait(locker, [&] {
+ return bufferAvailableCount_ >= 1 || !isRunning_;
+ });
+ if (isRunning_)
+ bufferAvailableCount_--;
+}
+
+bool V4L2Camera::isBufferAvailable()
+{
+ MutexLocker locker(bufferMutex_);
+ if (bufferAvailableCount_ < 1)
+ return false;
+
+ bufferAvailableCount_--;
+ return true;
+}
+
bool V4L2Camera::isRunning()
{
return isRunning_;