summaryrefslogtreecommitdiff
path: root/src/android/camera_proxy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/camera_proxy.cpp')
-rw-r--r--src/android/camera_proxy.cpp194
1 files changed, 194 insertions, 0 deletions
diff --git a/src/android/camera_proxy.cpp b/src/android/camera_proxy.cpp
new file mode 100644
index 00000000..f0cacac8
--- /dev/null
+++ b/src/android/camera_proxy.cpp
@@ -0,0 +1,194 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * camera_proxy.cpp - Proxy to camera devices
+ */
+
+#include "camera_proxy.h"
+
+#include <system/camera_metadata.h>
+
+#include "log.h"
+#include "message.h"
+#include "utils.h"
+
+#include "camera_device.h"
+#include "thread_rpc.h"
+
+using namespace libcamera;
+
+LOG_DECLARE_CATEGORY(HAL);
+
+/*
+ * \class CameraProxy
+ *
+ * The CameraProxy wraps a CameraDevice and implements the camera3_device_t
+ * API, bridging calls received from the camera framework to the CameraDevice.
+ *
+ * Bridging operation calls between the framework and the CameraDevice is
+ * required as the two run in two different threads and certain operations,
+ * such as queueing a new capture request to the camera, shall be called in
+ * the thread that dispatches events. Other operations do not require any
+ * bridging and resolve to direct function calls on the CameraDevice instance
+ * instead.
+ */
+
+static int hal_dev_initialize(const struct camera3_device *dev,
+ const camera3_callback_ops_t *callback_ops)
+{
+ if (!dev)
+ return -EINVAL;
+
+ CameraProxy *proxy = reinterpret_cast<CameraProxy *>(dev->priv);
+ proxy->initialize(callback_ops);
+
+ return 0;
+}
+
+static int hal_dev_configure_streams(const struct camera3_device *dev,
+ camera3_stream_configuration_t *stream_list)
+{
+ if (!dev)
+ return -EINVAL;
+
+ CameraProxy *proxy = reinterpret_cast<CameraProxy *>(dev->priv);
+ return proxy->configureStreams(stream_list);
+}
+
+static const camera_metadata_t *
+hal_dev_construct_default_request_settings(const struct camera3_device *dev,
+ int type)
+{
+ if (!dev)
+ return nullptr;
+
+ CameraProxy *proxy = reinterpret_cast<CameraProxy *>(dev->priv);
+ return proxy->constructDefaultRequestSettings(type);
+}
+
+static int hal_dev_process_capture_request(const struct camera3_device *dev,
+ camera3_capture_request_t *request)
+{
+ if (!dev)
+ return -EINVAL;
+
+ CameraProxy *proxy = reinterpret_cast<CameraProxy *>(dev->priv);
+ return proxy->processCaptureRequest(request);
+}
+
+static void hal_dev_dump(const struct camera3_device *dev, int fd)
+{
+}
+
+static int hal_dev_flush(const struct camera3_device *dev)
+{
+ return 0;
+}
+
+static int hal_dev_close(hw_device_t *hw_device)
+{
+ if (!hw_device)
+ return -EINVAL;
+
+ camera3_device_t *dev = reinterpret_cast<camera3_device_t *>(hw_device);
+ CameraProxy *proxy = reinterpret_cast<CameraProxy *>(dev->priv);
+
+ proxy->close();
+
+ return 0;
+}
+
+static camera3_device_ops hal_dev_ops = {
+ .initialize = hal_dev_initialize,
+ .configure_streams = hal_dev_configure_streams,
+ .register_stream_buffers = nullptr,
+ .construct_default_request_settings = hal_dev_construct_default_request_settings,
+ .process_capture_request = hal_dev_process_capture_request,
+ .get_metadata_vendor_tag_ops = nullptr,
+ .dump = hal_dev_dump,
+ .flush = hal_dev_flush,
+ .reserved = { nullptr },
+};
+
+CameraProxy::CameraProxy(unsigned int id, std::shared_ptr<Camera> camera)
+ : id_(id)
+{
+ cameraDevice_ = new CameraDevice(id, camera);
+}
+
+CameraProxy::~CameraProxy()
+{
+ delete cameraDevice_;
+}
+
+int CameraProxy::open(const hw_module_t *hardwareModule)
+{
+ int ret = cameraDevice_->open();
+ if (ret)
+ return ret;
+
+ /* Initialize the hw_device_t in the instance camera3_module_t. */
+ camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
+ camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
+ camera3Device_.common.module = (hw_module_t *)hardwareModule;
+ camera3Device_.common.close = hal_dev_close;
+
+ /*
+ * The camera device operations. These actually implement
+ * the Android Camera HALv3 interface.
+ */
+ camera3Device_.ops = &hal_dev_ops;
+ camera3Device_.priv = this;
+
+ return 0;
+}
+
+void CameraProxy::close()
+{
+ ThreadRpc rpcRequest;
+ rpcRequest.tag = ThreadRpc::Close;
+
+ threadRpcCall(rpcRequest);
+}
+
+void CameraProxy::initialize(const camera3_callback_ops_t *callbacks)
+{
+ cameraDevice_->setCallbacks(callbacks);
+}
+
+const camera_metadata_t *CameraProxy::getStaticMetadata()
+{
+ return cameraDevice_->getStaticMetadata();
+}
+
+const camera_metadata_t *CameraProxy::constructDefaultRequestSettings(int type)
+{
+ return cameraDevice_->constructDefaultRequestSettings(type);
+}
+
+int CameraProxy::configureStreams(camera3_stream_configuration_t *stream_list)
+{
+ return cameraDevice_->configureStreams(stream_list);
+}
+
+int CameraProxy::processCaptureRequest(camera3_capture_request_t *request)
+{
+ ThreadRpc rpcRequest;
+ rpcRequest.tag = ThreadRpc::ProcessCaptureRequest;
+ rpcRequest.request = request;
+
+ threadRpcCall(rpcRequest);
+
+ return 0;
+}
+
+void CameraProxy::threadRpcCall(ThreadRpc &rpcRequest)
+{
+ std::unique_ptr<ThreadRpcMessage> message =
+ utils::make_unique<ThreadRpcMessage>();
+ message->rpc = &rpcRequest;
+
+ cameraDevice_->postMessage(std::move(message));
+ rpcRequest.waitDelivery();
+}