Use the newly introduced InvocationTypeBlocking message type to replace the blocking message delivery implemented with the ThreadRPC class in the Android camera HAL. Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
180 lines
4.4 KiB
C++
180 lines
4.4 KiB
C++
/* 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 <libcamera/object.h>
|
|
|
|
#include "log.h"
|
|
#include "message.h"
|
|
#include "utils.h"
|
|
|
|
#include "camera_device.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, const 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()
|
|
{
|
|
cameraDevice_->invokeMethod(&CameraDevice::close,
|
|
ConnectionTypeBlocking);
|
|
}
|
|
|
|
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)
|
|
{
|
|
cameraDevice_->invokeMethod(&CameraDevice::processCaptureRequest,
|
|
ConnectionTypeBlocking, request);
|
|
|
|
return 0;
|
|
}
|