From 3d4b7b0059116f5f151dec5090ec0e18bd401f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Tue, 27 Oct 2020 01:08:23 +0100 Subject: libcamera: delayed_controls: Add helper for controls that apply with a delay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some sensor controls take effect with a delay as the sensor needs time to adjust, for example exposure. Add an optional helper DelayedControls to help pipelines deal with such controls. The idea is to provide a queue of controls towards the V4L2 device and apply individual controls with the specified delay with the aim to get predictable and retrievable control values for any given frame. To do this the queue of controls needs to be at least as deep as the control with the largest delay. The DelayedControls needs to be informed of every start of exposure. This can be emulated but the helper is designed to be used with this event being provide by the kernel through V4L2 events. This helper is based on StaggeredCtrl from the Raspberry Pi pipeline handler but expands on its API. This helpers aims to replace the Raspberry Pi implementations and mimics it behavior perfectly. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Reviewed-by: Naushir Patuck --- include/libcamera/internal/delayed_controls.h | 81 +++++++++++++++++++++++++++ include/libcamera/internal/meson.build | 1 + 2 files changed, 82 insertions(+) create mode 100644 include/libcamera/internal/delayed_controls.h (limited to 'include/libcamera') diff --git a/include/libcamera/internal/delayed_controls.h b/include/libcamera/internal/delayed_controls.h new file mode 100644 index 00000000..dc447a88 --- /dev/null +++ b/include/libcamera/internal/delayed_controls.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Raspberry Pi (Trading) Ltd. + * + * delayed_controls.h - Helper to deal with controls that take effect with a delay + */ +#ifndef __LIBCAMERA_INTERNAL_DELAYED_CONTROLS_H__ +#define __LIBCAMERA_INTERNAL_DELAYED_CONTROLS_H__ + +#include +#include + +#include + +namespace libcamera { + +class V4L2Device; + +class DelayedControls +{ +public: + DelayedControls(V4L2Device *device, + const std::unordered_map &delays); + + void reset(); + + bool push(const ControlList &controls); + ControlList get(uint32_t sequence); + + void applyControls(uint32_t sequence); + +private: + class Info : public ControlValue + { + public: + Info() + : updated(false) + { + } + + Info(const ControlValue &v) + : ControlValue(v), updated(true) + { + } + + bool updated; + }; + + /* \todo: Make the listSize configurable at instance creation time. */ + static constexpr int listSize = 16; + class ControlRingBuffer : public std::array + { + public: + Info &operator[](unsigned int index) + { + return std::array::operator[](index % listSize); + } + + const Info &operator[](unsigned int index) const + { + return std::array::operator[](index % listSize); + } + }; + + V4L2Device *device_; + /* \todo Evaluate if we should index on ControlId * or unsigned int */ + std::unordered_map delays_; + unsigned int maxDelay_; + + bool running_; + uint32_t firstSequence_; + + uint32_t queueCount_; + uint32_t writeCount_; + /* \todo Evaluate if we should index on ControlId * or unsigned int */ + std::unordered_map values_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_INTERNAL_DELAYED_CONTROLS_H__ */ diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build index 1b1bdc77..e67a359f 100644 --- a/include/libcamera/internal/meson.build +++ b/include/libcamera/internal/meson.build @@ -17,6 +17,7 @@ libcamera_internal_headers = files([ 'camera_sensor.h', 'control_serializer.h', 'control_validator.h', + 'delayed_controls.h', 'device_enumerator.h', 'device_enumerator_sysfs.h', 'device_enumerator_udev.h', -- cgit v1.2.1