diff options
author | Jacopo Mondi <jacopo@jmondi.org> | 2019-05-10 17:40:02 +0200 |
---|---|---|
committer | Jacopo Mondi <jacopo@jmondi.org> | 2019-08-12 11:55:46 +0200 |
commit | 667d8ea8fd4bda35e8888792d2b6c055fdb4be18 (patch) | |
tree | 786462c9f8dfce3d3d05d69dc8befcd67e94db07 /src/android/camera_hal_manager.cpp | |
parent | 6bed34da161bb8c4e86821116dcff2205e29c58a (diff) |
android: hal: Add Camera3 HAL
Add libcamera Android Camera HALv3 implementation.
The initial camera HAL implementation supports the LIMITED hardware
level and uses statically defined metadata and camera characteristics.
Add a build option named 'android' and adjust the build system to
selectively compile the Android camera HAL and link it against the
required Android libraries.
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Diffstat (limited to 'src/android/camera_hal_manager.cpp')
-rw-r--r-- | src/android/camera_hal_manager.cpp | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp new file mode 100644 index 00000000..08c759df --- /dev/null +++ b/src/android/camera_hal_manager.cpp @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * camera_hal_manager.cpp - libcamera Android Camera Manager + */ + +#include "camera_hal_manager.h" + +#include <libcamera/camera.h> + +#include "log.h" + +#include "camera_device.h" +#include "camera_proxy.h" + +using namespace libcamera; + +LOG_DECLARE_CATEGORY(HAL); + +/* + * \class CameraHalManager + * + * The HAL camera manager is initializated at camera_module_t 'hal_init()' time + * and spawns its own thread where libcamera related events are dispatched to. + * It wraps the libcamera CameraManager operations and provides helpers for the + * camera_module_t operations, to retrieve the number of cameras in the system, + * their static information and to open and close camera devices. + */ + +int CameraHalManager::init() +{ + /* + * Start the camera HAL manager thread and wait until its + * initialisation completes to be fully operational before + * receiving calls from the camera stack. + */ + start(); + + MutexLocker locker(mutex_); + cv_.wait(locker); + + return 0; +} + +void CameraHalManager::run() +{ + /* + * All the libcamera components must be initialised here, in + * order to bind them to the camera HAL manager thread that + * executes the event dispatcher. + */ + cameraManager_ = libcamera::CameraManager::instance(); + + int ret = cameraManager_->start(); + if (ret) { + LOG(HAL, Error) << "Failed to start camera manager: " + << strerror(-ret); + return; + } + + /* + * For each Camera registered in the system, a CameraProxy + * gets created here to wraps a camera device. + * + * \todo Support camera hotplug. + */ + unsigned int index = 0; + for (auto &camera : cameraManager_->cameras()) { + CameraProxy *proxy = new CameraProxy(index, camera); + proxies_.emplace_back(proxy); + + ++index; + } + + /* + * libcamera has been initialized. Unlock the init() caller + * as we're now ready to handle calls from the framework. + */ + cv_.notify_one(); + + /* Now start processing events and messages. */ + exec(); +} + +CameraProxy *CameraHalManager::open(unsigned int id, + const hw_module_t *hardwareModule) +{ + if (id < 0 || id >= numCameras()) { + LOG(HAL, Error) << "Invalid camera id '" << id << "'"; + return nullptr; + } + + CameraProxy *proxy = proxies_[id].get(); + if (proxy->open(hardwareModule)) + return nullptr; + + LOG(HAL, Info) << "Open camera '" << id << "'"; + + return proxy; +} + +int CameraHalManager::close(CameraProxy *proxy) +{ + proxy->close(); + LOG(HAL, Info) << "Close camera '" << proxy->id() << "'"; + + return 0; +} + +unsigned int CameraHalManager::numCameras() const +{ + return cameraManager_->cameras().size(); +} + +int CameraHalManager::getCameraInfo(int id, struct camera_info *info) +{ + if (!info) + return -EINVAL; + + if (id >= numCameras() || id < 0) { + LOG(HAL, Error) << "Invalid camera id '" << id << "'"; + return -EINVAL; + } + + CameraProxy *proxy = proxies_[id].get(); + + /* \todo Get these info dynamically inspecting the camera module. */ + info->facing = id ? CAMERA_FACING_FRONT : CAMERA_FACING_BACK; + info->orientation = 0; + info->device_version = 0; + info->resource_cost = 0; + info->static_camera_characteristics = proxy->getStaticMetadata(); + info->conflicting_devices = nullptr; + info->conflicting_devices_length = 0; + + return 0; +} |