[libcamera-devel] [RFC 1/2] android: camera_worker: Introduce CameraWorker
Jacopo Mondi
jacopo at jmondi.org
Tue Oct 6 18:06:36 CEST 2020
The CameraWork class creates a Worker instance and runs on an internal
thread. The worker waits on a set of fences before queueing a capture
requests to the the libcamera::Camera.
Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
---
src/android/camera_worker.cpp | 67 +++++++++++++++++++++++++++++++
src/android/camera_worker.h | 75 +++++++++++++++++++++++++++++++++++
src/android/meson.build | 1 +
3 files changed, 143 insertions(+)
create mode 100644 src/android/camera_worker.cpp
create mode 100644 src/android/camera_worker.h
diff --git a/src/android/camera_worker.cpp b/src/android/camera_worker.cpp
new file mode 100644
index 000000000000..2bb94775a195
--- /dev/null
+++ b/src/android/camera_worker.cpp
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2020, Google Inc.
+ *
+ * camera_worker.cpp - Process capture request on behalf of the Camera HAL
+ */
+
+#include "camera_worker.h"
+
+#include <errno.h>
+#include <sys/poll.h>
+
+#include "camera_device.h"
+
+using namespace libcamera;
+
+CameraWorker::CameraWorker(const std::shared_ptr<Camera> &camera)
+ : camera_(camera), worker_(camera_.get())
+{
+ worker_.moveToThread(&thread_);
+ thread_.start();
+}
+
+void CameraWorker::queueRequest(std::unique_ptr<CaptureRequest> request)
+{
+ CaptureRequest *req = request.release();
+ worker_.invokeMethod(&Worker::processRequest, ConnectionTypeQueued, req);
+}
+
+int CameraWorker::Worker::waitFence(int fence)
+{
+ struct pollfd fds = { fence, POLLIN, 0 };
+ constexpr unsigned int timeoutMs = 300;
+ int ret;
+
+ do {
+ ret = poll(&fds, 1, timeoutMs);
+ if (ret == 0)
+ return -ETIME;
+
+ if (ret > 0) {
+ if (fds.revents & (POLLERR | POLLNVAL))
+ return -EINVAL;
+
+ return 0;
+ }
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ return ret;
+}
+
+void CameraWorker::Worker::processRequest(CaptureRequest *request)
+{
+ for (int fence : request->acquireFences_) {
+ if (fence == -1)
+ continue;
+
+ int ret = waitFence(fence);
+ if (ret < 0)
+ return;
+
+ close(fence);
+ }
+
+ camera_->queueRequest(request->request_);
+ delete request;
+}
diff --git a/src/android/camera_worker.h b/src/android/camera_worker.h
new file mode 100644
index 000000000000..24b176d6269c
--- /dev/null
+++ b/src/android/camera_worker.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2020, Google Inc.
+ *
+ * camera_worker.h - Process capture request on behalf of the Camera HAL
+ */
+#ifndef __ANDROID_CAMERA_WORKER_H__
+#define __ANDROID_CAMERA_WORKER_H__
+
+#include <memory>
+
+#include <libcamera/buffer.h>
+#include <libcamera/camera.h>
+#include <libcamera/object.h>
+#include <libcamera/request.h>
+#include <libcamera/stream.h>
+
+#include "libcamera/internal/thread.h"
+
+class CameraDevice;
+
+struct CaptureRequest {
+ CaptureRequest(libcamera::Request *request)
+ : request_(request)
+ {
+ }
+
+ void addBuffer(libcamera::Stream *stream,
+ libcamera::FrameBuffer *buffer, int fence)
+ {
+ request_->addBuffer(stream, buffer);
+ acquireFences_.push_back(fence);
+ }
+
+private:
+ friend class CameraWorker;
+
+ std::vector<int> acquireFences_;
+ libcamera::Request *request_;
+};
+
+class CameraWorker
+{
+public:
+ CameraWorker(const std::shared_ptr<libcamera::Camera> &camera);
+
+ void queueRequest(std::unique_ptr<CaptureRequest> request);
+
+private:
+ class Worker : public libcamera::Object
+ {
+ public:
+ Worker(libcamera::Camera *camera)
+ : camera_(camera)
+ {
+ }
+ ~Worker()
+ {
+ }
+
+ void processRequest(CaptureRequest *request);
+
+ private:
+ int waitFence(int fence);
+
+ libcamera::Camera *camera_;
+ };
+
+ std::shared_ptr<libcamera::Camera> camera_;
+
+ Worker worker_;
+ libcamera::Thread thread_;
+};
+
+#endif /* __ANDROID_CAMERA_WORKER_H__ */
diff --git a/src/android/meson.build b/src/android/meson.build
index 802bb89afe57..b2b2293cf62d 100644
--- a/src/android/meson.build
+++ b/src/android/meson.build
@@ -21,6 +21,7 @@ android_hal_sources = files([
'camera_metadata.cpp',
'camera_ops.cpp',
'camera_stream.cpp',
+ 'camera_worker.cpp',
'jpeg/encoder_libjpeg.cpp',
'jpeg/exif.cpp',
])
--
2.28.0
More information about the libcamera-devel
mailing list