diff options
Diffstat (limited to 'include/libcamera')
101 files changed, 1682 insertions, 387 deletions
diff --git a/include/libcamera/base/backtrace.h b/include/libcamera/base/backtrace.h index 752034d1..699ddd9e 100644 --- a/include/libcamera/base/backtrace.h +++ b/include/libcamera/base/backtrace.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2021, Ideas on Board Oy * - * backtrace.h - Call stack backtraces + * Call stack backtraces */ #pragma once diff --git a/include/libcamera/base/bound_method.h b/include/libcamera/base/bound_method.h index e73a4d98..dd3488ee 100644 --- a/include/libcamera/base/bound_method.h +++ b/include/libcamera/base/bound_method.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * bound_method.h - Method bind and invocation + * Method bind and invocation */ #pragma once @@ -72,7 +72,7 @@ public: } virtual ~BoundMethodBase() = default; - template<typename T, typename std::enable_if_t<!std::is_same<Object, T>::value> * = nullptr> + template<typename T, std::enable_if_t<!std::is_same<Object, T>::value> * = nullptr> bool match(T *obj) { return obj == obj_; } bool match(Object *object) { return object == object_; } diff --git a/include/libcamera/base/class.h b/include/libcamera/base/class.h index 571eecf4..a808422e 100644 --- a/include/libcamera/base/class.h +++ b/include/libcamera/base/class.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2020, Google Inc. * - * class.h - Utilities and helpers for classes + * Utilities and helpers for classes */ #pragma once diff --git a/include/libcamera/base/compiler.h b/include/libcamera/base/compiler.h index 02564f2f..fda8fdfd 100644 --- a/include/libcamera/base/compiler.h +++ b/include/libcamera/base/compiler.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2021, Google Inc. * - * compiler.h - Compiler support + * Compiler support */ #pragma once diff --git a/include/libcamera/base/event_dispatcher.h b/include/libcamera/base/event_dispatcher.h index 184f1b12..e9a09c6e 100644 --- a/include/libcamera/base/event_dispatcher.h +++ b/include/libcamera/base/event_dispatcher.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * event_dispatcher.h - Event dispatcher + * Event dispatcher */ #pragma once diff --git a/include/libcamera/base/event_dispatcher_poll.h b/include/libcamera/base/event_dispatcher_poll.h index b7840309..1f7e05cf 100644 --- a/include/libcamera/base/event_dispatcher_poll.h +++ b/include/libcamera/base/event_dispatcher_poll.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * event_dispatcher_poll.h - Poll-based event dispatcher + * Poll-based event dispatcher */ #pragma once diff --git a/include/libcamera/base/event_notifier.h b/include/libcamera/base/event_notifier.h index e5c0594d..158f2d44 100644 --- a/include/libcamera/base/event_notifier.h +++ b/include/libcamera/base/event_notifier.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * event_notifier.h - File descriptor event notifier + * File descriptor event notifier */ #pragma once diff --git a/include/libcamera/base/file.h b/include/libcamera/base/file.h index 0cdc2ed0..5637934c 100644 --- a/include/libcamera/base/file.h +++ b/include/libcamera/base/file.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2020, Google Inc. * - * file.h - File I/O operations + * File I/O operations */ #pragma once diff --git a/include/libcamera/base/flags.h b/include/libcamera/base/flags.h index bff3b93c..af4f6e35 100644 --- a/include/libcamera/base/flags.h +++ b/include/libcamera/base/flags.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2020, Google Inc. * - * flags.h - Type-safe enum-based bitfields + * Type-safe enum-based bitfields */ #pragma once @@ -147,7 +147,7 @@ struct flags_enable_operators { }; template<typename E> -typename std::enable_if_t<flags_enable_operators<E>::enable, Flags<E>> +std::enable_if_t<flags_enable_operators<E>::enable, Flags<E>> operator|(E lhs, E rhs) { using type = std::underlying_type_t<E>; @@ -155,7 +155,7 @@ operator|(E lhs, E rhs) } template<typename E> -typename std::enable_if_t<flags_enable_operators<E>::enable, Flags<E>> +std::enable_if_t<flags_enable_operators<E>::enable, Flags<E>> operator&(E lhs, E rhs) { using type = std::underlying_type_t<E>; @@ -163,7 +163,7 @@ operator&(E lhs, E rhs) } template<typename E> -typename std::enable_if_t<flags_enable_operators<E>::enable, Flags<E>> +std::enable_if_t<flags_enable_operators<E>::enable, Flags<E>> operator^(E lhs, E rhs) { using type = std::underlying_type_t<E>; @@ -171,7 +171,7 @@ operator^(E lhs, E rhs) } template<typename E> -typename std::enable_if_t<flags_enable_operators<E>::enable, Flags<E>> +std::enable_if_t<flags_enable_operators<E>::enable, Flags<E>> operator~(E rhs) { using type = std::underlying_type_t<E>; diff --git a/include/libcamera/base/log.h b/include/libcamera/base/log.h index 3fc5ced3..b5775e49 100644 --- a/include/libcamera/base/log.h +++ b/include/libcamera/base/log.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2018, Google Inc. * - * log.h - Logging infrastructure + * Logging infrastructure */ #pragma once @@ -29,16 +29,18 @@ enum LogSeverity { class LogCategory { public: - explicit LogCategory(const char *name); + static LogCategory *create(const char *name); - const char *name() const { return name_; } + const std::string &name() const { return name_; } LogSeverity severity() const { return severity_; } void setSeverity(LogSeverity severity); static const LogCategory &defaultCategory(); private: - const char *name_; + explicit LogCategory(const char *name); + + const std::string name_; LogSeverity severity_; }; @@ -49,7 +51,7 @@ extern const LogCategory &_LOG_CATEGORY(name)(); const LogCategory &_LOG_CATEGORY(name)() \ { \ /* The instance will be deleted by the Logger destructor. */ \ - static LogCategory *category = new LogCategory(#name); \ + static LogCategory *category = LogCategory::create(#name); \ return *category; \ } diff --git a/include/libcamera/base/meson.build b/include/libcamera/base/meson.build index 4410aba8..bace25d5 100644 --- a/include/libcamera/base/meson.build +++ b/include/libcamera/base/meson.build @@ -2,31 +2,39 @@ libcamera_base_include_dir = libcamera_include_dir / 'base' -libcamera_base_headers = files([ - 'backtrace.h', +libcamera_base_public_headers = files([ 'bound_method.h', 'class.h', 'compiler.h', + 'flags.h', + 'object.h', + 'shared_fd.h', + 'signal.h', + 'span.h', + 'unique_fd.h', +]) + +libcamera_base_private_headers = files([ + 'backtrace.h', 'event_dispatcher.h', 'event_dispatcher_poll.h', 'event_notifier.h', 'file.h', - 'flags.h', 'log.h', 'message.h', 'mutex.h', - 'object.h', 'private.h', 'semaphore.h', - 'shared_fd.h', - 'signal.h', - 'span.h', 'thread.h', 'thread_annotations.h', 'timer.h', - 'unique_fd.h', 'utils.h', ]) -install_headers(libcamera_base_headers, - subdir: libcamera_base_include_dir) +libcamera_base_headers = [ + libcamera_base_public_headers, + libcamera_base_private_headers, +] + +install_headers(libcamera_base_public_headers, + subdir : libcamera_base_include_dir) diff --git a/include/libcamera/base/message.h b/include/libcamera/base/message.h index 65572c74..4b232031 100644 --- a/include/libcamera/base/message.h +++ b/include/libcamera/base/message.h @@ -2,13 +2,15 @@ /* * Copyright (C) 2019, Google Inc. * - * message.h - Message queue support + * Message queue support */ #pragma once #include <atomic> +#include <libcamera/base/private.h> + #include <libcamera/base/bound_method.h> namespace libcamera { diff --git a/include/libcamera/base/mutex.h b/include/libcamera/base/mutex.h index 2d23e49e..fa9a8d0d 100644 --- a/include/libcamera/base/mutex.h +++ b/include/libcamera/base/mutex.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2021, Google Inc. * - * mutex.h - Mutex classes with clang thread safety annotation + * Mutex classes with clang thread safety annotation */ #pragma once @@ -10,6 +10,8 @@ #include <condition_variable> #include <mutex> +#include <libcamera/base/private.h> + #include <libcamera/base/thread_annotations.h> namespace libcamera { diff --git a/include/libcamera/base/object.h b/include/libcamera/base/object.h index eef1a2c9..508773cd 100644 --- a/include/libcamera/base/object.h +++ b/include/libcamera/base/object.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * object.h - Base object + * Base object */ #pragma once @@ -32,7 +32,7 @@ public: void postMessage(std::unique_ptr<Message> msg); template<typename T, typename R, typename... FuncArgs, typename... Args, - typename std::enable_if_t<std::is_base_of<Object, T>::value> * = nullptr> + std::enable_if_t<std::is_base_of<Object, T>::value> * = nullptr> R invokeMethod(R (T::*func)(FuncArgs...), ConnectionType type, Args&&... args) { @@ -49,6 +49,8 @@ public: protected: virtual void message(Message *msg); + bool assertThreadBound(const char *message); + private: friend class SignalBase; friend class Thread; diff --git a/include/libcamera/base/private.h b/include/libcamera/base/private.h index 163012bf..8670c40b 100644 --- a/include/libcamera/base/private.h +++ b/include/libcamera/base/private.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2021, Google Inc. * - * private.h - Private Header Validation + * Private Header Validation * * A selection of internal libcamera headers are installed as part * of the libcamera package to allow sharing of a select subset of diff --git a/include/libcamera/base/semaphore.h b/include/libcamera/base/semaphore.h index c11e8dd1..59d4aa44 100644 --- a/include/libcamera/base/semaphore.h +++ b/include/libcamera/base/semaphore.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * semaphore.h - General-purpose counting semaphore + * General-purpose counting semaphore */ #pragma once @@ -18,15 +18,15 @@ class Semaphore public: Semaphore(unsigned int n = 0); - unsigned int available(); - void acquire(unsigned int n = 1); - bool tryAcquire(unsigned int n = 1); - void release(unsigned int n = 1); + unsigned int available() LIBCAMERA_TSA_EXCLUDES(mutex_); + void acquire(unsigned int n = 1) LIBCAMERA_TSA_EXCLUDES(mutex_); + bool tryAcquire(unsigned int n = 1) LIBCAMERA_TSA_EXCLUDES(mutex_); + void release(unsigned int n = 1) LIBCAMERA_TSA_EXCLUDES(mutex_); private: Mutex mutex_; ConditionVariable cv_; - unsigned int available_; + unsigned int available_ LIBCAMERA_TSA_GUARDED_BY(mutex_); }; } /* namespace libcamera */ diff --git a/include/libcamera/base/shared_fd.h b/include/libcamera/base/shared_fd.h index e53a8b88..61fe11c1 100644 --- a/include/libcamera/base/shared_fd.h +++ b/include/libcamera/base/shared_fd.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * shared_fd.h - File descriptor wrapper with shared ownership + * File descriptor wrapper with shared ownership */ #pragma once diff --git a/include/libcamera/base/signal.h b/include/libcamera/base/signal.h index 91000d0d..849fbbda 100644 --- a/include/libcamera/base/signal.h +++ b/include/libcamera/base/signal.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * signal.h - Signal & slot implementation + * Signal & slot implementation */ #pragma once @@ -13,10 +13,11 @@ #include <vector> #include <libcamera/base/bound_method.h> -#include <libcamera/base/object.h> namespace libcamera { +class Object; + class SignalBase { public: @@ -44,7 +45,7 @@ public: } #ifndef __DOXYGEN__ - template<typename T, typename R, typename std::enable_if_t<std::is_base_of<Object, T>::value> * = nullptr> + template<typename T, typename R, std::enable_if_t<std::is_base_of<Object, T>::value> * = nullptr> void connect(T *obj, R (T::*func)(Args...), ConnectionType type = ConnectionTypeAuto) { @@ -52,7 +53,7 @@ public: SignalBase::connect(new BoundMethodMember<T, R, Args...>(obj, object, func, type)); } - template<typename T, typename R, typename std::enable_if_t<!std::is_base_of<Object, T>::value> * = nullptr> + template<typename T, typename R, std::enable_if_t<!std::is_base_of<Object, T>::value> * = nullptr> #else template<typename T, typename R> #endif @@ -63,7 +64,11 @@ public: #ifndef __DOXYGEN__ template<typename T, typename Func, - typename std::enable_if_t<std::is_base_of<Object, T>::value> * = nullptr> + std::enable_if_t<std::is_base_of<Object, T>::value +#if __cplusplus >= 201703L + && std::is_invocable_v<Func, Args...> +#endif + > * = nullptr> void connect(T *obj, Func func, ConnectionType type = ConnectionTypeAuto) { Object *object = static_cast<Object *>(obj); @@ -71,7 +76,11 @@ public: } template<typename T, typename Func, - typename std::enable_if_t<!std::is_base_of<Object, T>::value> * = nullptr> + std::enable_if_t<!std::is_base_of<Object, T>::value +#if __cplusplus >= 201703L + && std::is_invocable_v<Func, Args...> +#endif + > * = nullptr> #else template<typename T, typename Func> #endif diff --git a/include/libcamera/base/span.h b/include/libcamera/base/span.h index 88d2e3de..c3e63f69 100644 --- a/include/libcamera/base/span.h +++ b/include/libcamera/base/span.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2020, Google Inc. * - * span.h - C++20 std::span<> implementation for C++11 + * C++20 std::span<> implementation for C++11 */ #pragma once diff --git a/include/libcamera/base/thread.h b/include/libcamera/base/thread.h index 9d00f102..4f33de63 100644 --- a/include/libcamera/base/thread.h +++ b/include/libcamera/base/thread.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * thread.h - Thread support + * Thread support */ #pragma once diff --git a/include/libcamera/base/thread_annotations.h b/include/libcamera/base/thread_annotations.h index e81929f6..81930f08 100644 --- a/include/libcamera/base/thread_annotations.h +++ b/include/libcamera/base/thread_annotations.h @@ -2,11 +2,13 @@ /* * Copyright (C) 2021, Google Inc. * - * thread_annotation.h - Macro of Clang thread safety analysis + * Macro of Clang thread safety analysis */ #pragma once +#include <libcamera/base/private.h> + /* * Enable thread safety attributes only with clang. * The attributes can be safely erased when compiling with other compilers. diff --git a/include/libcamera/base/timer.h b/include/libcamera/base/timer.h index 759b68ad..5ef45959 100644 --- a/include/libcamera/base/timer.h +++ b/include/libcamera/base/timer.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * timer.h - Generic timer + * Generic timer */ #pragma once diff --git a/include/libcamera/base/unique_fd.h b/include/libcamera/base/unique_fd.h index ae4d96b7..c9a3b5d0 100644 --- a/include/libcamera/base/unique_fd.h +++ b/include/libcamera/base/unique_fd.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2021, Google Inc. * - * unique_fd.h - File descriptor wrapper that owns a file descriptor. + * File descriptor wrapper that owns a file descriptor. */ #pragma once diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h index cfff0583..4ae02dc9 100644 --- a/include/libcamera/base/utils.h +++ b/include/libcamera/base/utils.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2018, Google Inc. * - * utils.h - Miscellaneous utility functions + * Miscellaneous utility functions */ #pragma once @@ -170,6 +170,12 @@ public: class iterator { public: + using difference_type = std::size_t; + using value_type = std::string; + using pointer = value_type *; + using reference = value_type &; + using iterator_category = std::input_iterator_tag; + iterator(const StringSplitter *ss, std::string::size_type pos); iterator &operator++(); @@ -361,6 +367,14 @@ decltype(auto) abs_diff(const T &a, const T &b) return a - b; } +double strtod(const char *__restrict nptr, char **__restrict endptr); + +template<class Enum> +constexpr std::underlying_type_t<Enum> to_underlying(Enum e) noexcept +{ + return static_cast<std::underlying_type_t<Enum>>(e); +} + } /* namespace utils */ #ifndef __DOXYGEN__ diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 5bb06584..94cee7bd 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -2,12 +2,14 @@ /* * Copyright (C) 2018, Google Inc. * - * camera.h - Camera object interface + * Camera object interface */ #pragma once +#include <initializer_list> #include <memory> +#include <optional> #include <set> #include <stdint.h> #include <string> @@ -18,9 +20,10 @@ #include <libcamera/base/signal.h> #include <libcamera/controls.h> +#include <libcamera/geometry.h> +#include <libcamera/orientation.h> #include <libcamera/request.h> #include <libcamera/stream.h> -#include <libcamera/transform.h> namespace libcamera { @@ -29,6 +32,30 @@ class FrameBufferAllocator; class PipelineHandler; class Request; +class SensorConfiguration +{ +public: + unsigned int bitDepth = 0; + + Rectangle analogCrop; + + struct { + unsigned int binX = 1; + unsigned int binY = 1; + } binning; + + struct { + unsigned int xOddInc = 1; + unsigned int xEvenInc = 1; + unsigned int yOddInc = 1; + unsigned int yEvenInc = 1; + } skipping; + + Size outputSize; + + bool isValid() const; +}; + class CameraConfiguration { public: @@ -65,7 +92,8 @@ public: bool empty() const; std::size_t size() const; - Transform transform; + std::optional<SensorConfiguration> sensorConfig; + Orientation orientation; protected: CameraConfiguration(); @@ -105,7 +133,16 @@ public: const ControlList &properties() const; const std::set<Stream *> &streams() const; - std::unique_ptr<CameraConfiguration> generateConfiguration(const StreamRoles &roles = {}); + + std::unique_ptr<CameraConfiguration> + generateConfiguration(Span<const StreamRole> roles = {}); + + std::unique_ptr<CameraConfiguration> + generateConfiguration(std::initializer_list<StreamRole> roles) + { + return generateConfiguration(Span(roles.begin(), roles.end())); + } + int configure(CameraConfiguration *config); std::unique_ptr<Request> createRequest(uint64_t cookie = 0); diff --git a/include/libcamera/camera_manager.h b/include/libcamera/camera_manager.h index 7647c2a1..b50df782 100644 --- a/include/libcamera/camera_manager.h +++ b/include/libcamera/camera_manager.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2018, Google Inc. * - * camera_manager.h - Camera management + * Camera management */ #pragma once @@ -31,12 +31,7 @@ public: void stop(); std::vector<std::shared_ptr<Camera>> cameras() const; - std::shared_ptr<Camera> get(const std::string &name); - std::shared_ptr<Camera> get(dev_t devnum); - - void addCamera(std::shared_ptr<Camera> camera, - const std::vector<dev_t> &devnums); - void removeCamera(std::shared_ptr<Camera> camera); + std::shared_ptr<Camera> get(const std::string &id); static const std::string &version() { return version_; } diff --git a/include/libcamera/color_space.h b/include/libcamera/color_space.h index 086c56c1..7b483cd1 100644 --- a/include/libcamera/color_space.h +++ b/include/libcamera/color_space.h @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* - * Copyright (C) 2021, Raspberry Pi (Trading) Limited + * Copyright (C) 2021, Raspberry Pi Ltd * - * color_space.h - color space definitions + * color space definitions */ #pragma once @@ -12,6 +12,8 @@ namespace libcamera { +class PixelFormat; + class ColorSpace { public: @@ -46,8 +48,8 @@ public: } static const ColorSpace Raw; - static const ColorSpace Jpeg; static const ColorSpace Srgb; + static const ColorSpace Sycc; static const ColorSpace Smpte170m; static const ColorSpace Rec709; static const ColorSpace Rec2020; @@ -59,6 +61,10 @@ public: std::string toString() const; static std::string toString(const std::optional<ColorSpace> &colorSpace); + + static std::optional<ColorSpace> fromString(const std::string &str); + + bool adjust(PixelFormat format); }; bool operator==(const ColorSpace &lhs, const ColorSpace &rhs); diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in index 0718a888..293ba966 100644 --- a/include/libcamera/control_ids.h.in +++ b/include/libcamera/control_ids.h.in @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * control_ids.h - Control ID list + * Control ID list * * This file is auto-generated. Do not edit. */ @@ -10,7 +10,9 @@ #pragma once #include <array> +#include <map> #include <stdint.h> +#include <string> #include <libcamera/controls.h> @@ -26,11 +28,7 @@ ${controls} extern const ControlIdMap controls; -namespace draft { - -${draft_controls} - -} /* namespace draft */ +${vendor_controls} } /* namespace controls */ diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 665bcac1..7c2bb287 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -2,12 +2,13 @@ /* * Copyright (C) 2019, Google Inc. * - * controls.h - Control handling + * Control handling */ #pragma once #include <assert.h> +#include <optional> #include <set> #include <stdint.h> #include <string> @@ -98,10 +99,10 @@ public: ControlValue(); #ifndef __DOXYGEN__ - template<typename T, typename std::enable_if_t<!details::is_span<T>::value && - details::control_type<T>::value && - !std::is_same<std::string, std::remove_cv_t<T>>::value, - std::nullptr_t> = nullptr> + template<typename T, std::enable_if_t<!details::is_span<T>::value && + details::control_type<T>::value && + !std::is_same<std::string, std::remove_cv_t<T>>::value, + std::nullptr_t> = nullptr> ControlValue(const T &value) : type_(ControlTypeNone), numElements_(0) { @@ -109,9 +110,9 @@ public: &value, 1, sizeof(T)); } - template<typename T, typename std::enable_if_t<details::is_span<T>::value || - std::is_same<std::string, std::remove_cv_t<T>>::value, - std::nullptr_t> = nullptr> + template<typename T, std::enable_if_t<details::is_span<T>::value || + std::is_same<std::string, std::remove_cv_t<T>>::value, + std::nullptr_t> = nullptr> #else template<typename T> #endif @@ -143,9 +144,9 @@ public: } #ifndef __DOXYGEN__ - template<typename T, typename std::enable_if_t<!details::is_span<T>::value && - !std::is_same<std::string, std::remove_cv_t<T>>::value, - std::nullptr_t> = nullptr> + template<typename T, std::enable_if_t<!details::is_span<T>::value && + !std::is_same<std::string, std::remove_cv_t<T>>::value, + std::nullptr_t> = nullptr> T get() const { assert(type_ == details::control_type<std::remove_cv_t<T>>::value); @@ -154,9 +155,9 @@ public: return *reinterpret_cast<const T *>(data().data()); } - template<typename T, typename std::enable_if_t<details::is_span<T>::value || - std::is_same<std::string, std::remove_cv_t<T>>::value, - std::nullptr_t> = nullptr> + template<typename T, std::enable_if_t<details::is_span<T>::value || + std::is_same<std::string, std::remove_cv_t<T>>::value, + std::nullptr_t> = nullptr> #else template<typename T> #endif @@ -167,22 +168,22 @@ public: using V = typename T::value_type; const V *value = reinterpret_cast<const V *>(data().data()); - return { value, numElements_ }; + return T{ value, numElements_ }; } #ifndef __DOXYGEN__ - template<typename T, typename std::enable_if_t<!details::is_span<T>::value && - !std::is_same<std::string, std::remove_cv_t<T>>::value, - std::nullptr_t> = nullptr> + template<typename T, std::enable_if_t<!details::is_span<T>::value && + !std::is_same<std::string, std::remove_cv_t<T>>::value, + std::nullptr_t> = nullptr> void set(const T &value) { set(details::control_type<std::remove_cv_t<T>>::value, false, reinterpret_cast<const void *>(&value), 1, sizeof(T)); } - template<typename T, typename std::enable_if_t<details::is_span<T>::value || - std::is_same<std::string, std::remove_cv_t<T>>::value, - std::nullptr_t> = nullptr> + template<typename T, std::enable_if_t<details::is_span<T>::value || + std::is_same<std::string, std::remove_cv_t<T>>::value, + std::nullptr_t> = nullptr> #else template<typename T> #endif @@ -267,9 +268,9 @@ private: class ControlInfo { public: - explicit ControlInfo(const ControlValue &min = 0, - const ControlValue &max = 0, - const ControlValue &def = 0); + explicit ControlInfo(const ControlValue &min = {}, + const ControlValue &max = {}, + const ControlValue &def = {}); explicit ControlInfo(Span<const ControlValue> values, const ControlValue &def = {}); explicit ControlInfo(std::set<bool> values, bool def); @@ -351,6 +352,11 @@ private: using ControlListMap = std::unordered_map<unsigned int, ControlValue>; public: + enum class MergePolicy { + KeepExisting = 0, + OverwriteExisting, + }; + ControlList(); ControlList(const ControlIdMap &idmap, const ControlValidator *validator = nullptr); ControlList(const ControlInfoMap &infoMap, const ControlValidator *validator = nullptr); @@ -367,19 +373,19 @@ public: std::size_t size() const { return controls_.size(); } void clear() { controls_.clear(); } - void merge(const ControlList &source); + void merge(const ControlList &source, MergePolicy policy = MergePolicy::KeepExisting); - bool contains(const ControlId &id) const; bool contains(unsigned int id) const; template<typename T> - T get(const Control<T> &ctrl) const + std::optional<T> get(const Control<T> &ctrl) const { - const ControlValue *val = find(ctrl.id()); - if (!val) - return T{}; + const auto entry = controls_.find(ctrl.id()); + if (entry == controls_.end()) + return std::nullopt; - return val->get<T>(); + const ControlValue &val = entry->second; + return val.get<T>(); } template<typename T, typename V> @@ -392,14 +398,14 @@ public: val->set<T>(value); } - template<typename T, typename V> - void set(const Control<T> &ctrl, const std::initializer_list<V> &value) + template<typename T, typename V, size_t Size> + void set(const Control<Span<T, Size>> &ctrl, const std::initializer_list<V> &value) { ControlValue *val = find(ctrl.id()); if (!val) return; - val->set<T>(Span<const typename std::remove_cv_t<V>>{ value.begin(), value.size() }); + val->set(Span<const typename std::remove_cv_t<V>, Size>{ value.begin(), value.size() }); } const ControlValue &get(unsigned int id) const; diff --git a/include/libcamera/fence.h b/include/libcamera/fence.h index c0c916c2..598336cb 100644 --- a/include/libcamera/fence.h +++ b/include/libcamera/fence.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2021, Google Inc. * - * internal/fence.h - Synchronization fence + * Synchronization fence */ #pragma once diff --git a/include/libcamera/formats.h.in b/include/libcamera/formats.h.in index ead5287d..6ae7634f 100644 --- a/include/libcamera/formats.h.in +++ b/include/libcamera/formats.h.in @@ -2,7 +2,7 @@ /* * Copyright (C) 2020, Google Inc. * - * formats.h - Formats + * Formats * * This file is auto-generated. Do not edit. */ diff --git a/include/libcamera/framebuffer.h b/include/libcamera/framebuffer.h index 3b1118d1..5ae2270b 100644 --- a/include/libcamera/framebuffer.h +++ b/include/libcamera/framebuffer.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * framebuffer.h - Frame buffer handling + * Frame buffer handling */ #pragma once @@ -46,7 +46,7 @@ private: std::vector<Plane> planes_; }; -class FrameBuffer final : public Extensible +class FrameBuffer : public Extensible { LIBCAMERA_DECLARE_PRIVATE() @@ -59,28 +59,20 @@ public: }; FrameBuffer(const std::vector<Plane> &planes, unsigned int cookie = 0); - FrameBuffer(std::unique_ptr<Private> d, - const std::vector<Plane> &planes, unsigned int cookie = 0); + FrameBuffer(std::unique_ptr<Private> d); + virtual ~FrameBuffer() {} - const std::vector<Plane> &planes() const { return planes_; } + const std::vector<Plane> &planes() const; Request *request() const; - const FrameMetadata &metadata() const { return metadata_; } + const FrameMetadata &metadata() const; - unsigned int cookie() const { return cookie_; } - void setCookie(unsigned int cookie) { cookie_ = cookie; } + uint64_t cookie() const; + void setCookie(uint64_t cookie); std::unique_ptr<Fence> releaseFence(); private: LIBCAMERA_DISABLE_COPY_AND_MOVE(FrameBuffer) - - friend class V4L2VideoDevice; /* Needed to update metadata_. */ - - std::vector<Plane> planes_; - - FrameMetadata metadata_; - - unsigned int cookie_; }; } /* namespace libcamera */ diff --git a/include/libcamera/framebuffer_allocator.h b/include/libcamera/framebuffer_allocator.h index 45ff232b..f3896bf2 100644 --- a/include/libcamera/framebuffer_allocator.h +++ b/include/libcamera/framebuffer_allocator.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * framebuffer_allocator.h - FrameBuffer allocator + * FrameBuffer allocator */ #pragma once diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h index d7fdbe70..3e6f0f5d 100644 --- a/include/libcamera/geometry.h +++ b/include/libcamera/geometry.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * geometry.h - Geometry-related classes + * Geometry-related classes */ #pragma once diff --git a/include/libcamera/internal/bayer_format.h b/include/libcamera/internal/bayer_format.h index 7d3e37c6..5c14bb5f 100644 --- a/include/libcamera/internal/bayer_format.h +++ b/include/libcamera/internal/bayer_format.h @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* - * Copyright (C) 2020, Raspberry Pi (Trading) Ltd. + * Copyright (C) 2020, Raspberry Pi Ltd * - * bayer_format.h - Bayer Pixel Format + * Bayer Pixel Format */ #pragma once @@ -34,6 +34,8 @@ public: None = 0, CSI2 = 1, IPU3 = 2, + PISP1 = 3, + PISP2 = 4, }; constexpr BayerFormat() diff --git a/include/libcamera/internal/byte_stream_buffer.h b/include/libcamera/internal/byte_stream_buffer.h index 0f4fce6f..5b1c10ab 100644 --- a/include/libcamera/internal/byte_stream_buffer.h +++ b/include/libcamera/internal/byte_stream_buffer.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * byte_stream_buffer.h - Byte stream buffer + * Byte stream buffer */ #pragma once diff --git a/include/libcamera/internal/camera.h b/include/libcamera/internal/camera.h index 597426a6..0add0428 100644 --- a/include/libcamera/internal/camera.h +++ b/include/libcamera/internal/camera.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2021, Google Inc. * - * camera.h - Camera private data + * Camera private data */ #pragma once @@ -50,6 +50,7 @@ private: CameraRunning, }; + bool isAcquired() const; bool isRunning() const; int isAccessAllowed(State state, bool allowDisconnected = false, const char *from = __builtin_FUNCTION()) const; diff --git a/include/libcamera/internal/camera_controls.h b/include/libcamera/internal/camera_controls.h index ee6d382f..4a5a3ebc 100644 --- a/include/libcamera/internal/camera_controls.h +++ b/include/libcamera/internal/camera_controls.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * camera_controls.h - Camera controls + * Camera controls */ #pragma once diff --git a/include/libcamera/internal/camera_lens.h b/include/libcamera/internal/camera_lens.h index 277417da..5a4b993b 100644 --- a/include/libcamera/internal/camera_lens.h +++ b/include/libcamera/internal/camera_lens.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2021, Google Inc. * - * camera_lens.h - A camera lens controller + * A camera lens controller */ #pragma once diff --git a/include/libcamera/internal/camera_manager.h b/include/libcamera/internal/camera_manager.h new file mode 100644 index 00000000..af9ed60a --- /dev/null +++ b/include/libcamera/internal/camera_manager.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Ideas on Board Oy. + * + * Camera manager private data + */ + +#pragma once + +#include <libcamera/camera_manager.h> + +#include <map> +#include <memory> +#include <sys/types.h> +#include <vector> + +#include <libcamera/base/class.h> +#include <libcamera/base/mutex.h> +#include <libcamera/base/thread.h> +#include <libcamera/base/thread_annotations.h> + +#include "libcamera/internal/ipa_manager.h" +#include "libcamera/internal/process.h" + +namespace libcamera { + +class Camera; +class DeviceEnumerator; + +class CameraManager::Private : public Extensible::Private, public Thread +{ + LIBCAMERA_DECLARE_PUBLIC(CameraManager) + +public: + Private(); + + int start(); + void addCamera(std::shared_ptr<Camera> camera) LIBCAMERA_TSA_EXCLUDES(mutex_); + void removeCamera(std::shared_ptr<Camera> camera) LIBCAMERA_TSA_EXCLUDES(mutex_); + +protected: + void run() override; + +private: + int init(); + void createPipelineHandlers(); + void pipelineFactoryMatch(const PipelineHandlerFactoryBase *factory); + void cleanup() LIBCAMERA_TSA_EXCLUDES(mutex_); + + /* + * This mutex protects + * + * - initialized_ and status_ during initialization + * - cameras_ after initialization + */ + mutable Mutex mutex_; + std::vector<std::shared_ptr<Camera>> cameras_ LIBCAMERA_TSA_GUARDED_BY(mutex_); + + ConditionVariable cv_; + bool initialized_ LIBCAMERA_TSA_GUARDED_BY(mutex_); + int status_ LIBCAMERA_TSA_GUARDED_BY(mutex_); + + std::unique_ptr<DeviceEnumerator> enumerator_; + + IPAManager ipaManager_; + ProcessManager processManager_; +}; + +} /* namespace libcamera */ diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h index b9f4d786..fc44ab98 100644 --- a/include/libcamera/internal/camera_sensor.h +++ b/include/libcamera/internal/camera_sensor.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * camera_sensor.h - A camera sensor + * A camera sensor */ #pragma once @@ -17,20 +17,25 @@ #include <libcamera/control_ids.h> #include <libcamera/controls.h> #include <libcamera/geometry.h> +#include <libcamera/orientation.h> +#include <libcamera/transform.h> #include <libcamera/ipa/core_ipa_interface.h> +#include "libcamera/internal/bayer_format.h" #include "libcamera/internal/formats.h" #include "libcamera/internal/v4l2_subdevice.h" namespace libcamera { -class BayerFormat; class CameraLens; class MediaEntity; +class SensorConfiguration; struct CameraSensorProperties; +enum class Orientation; + class CameraSensor : protected Loggable { public: @@ -41,32 +46,40 @@ public: const std::string &model() const { return model_; } const std::string &id() const { return id_; } + const MediaEntity *entity() const { return entity_; } + V4L2Subdevice *device() { return subdev_.get(); } + + CameraLens *focusLens() { return focusLens_.get(); } + const std::vector<unsigned int> &mbusCodes() const { return mbusCodes_; } std::vector<Size> sizes(unsigned int mbusCode) const; Size resolution() const; - const std::vector<controls::draft::TestPatternModeEnum> &testPatternModes() const - { - return testPatternModes_; - } - int setTestPatternMode(controls::draft::TestPatternModeEnum mode); V4L2SubdeviceFormat getFormat(const std::vector<unsigned int> &mbusCodes, const Size &size) const; - int setFormat(V4L2SubdeviceFormat *format); + int setFormat(V4L2SubdeviceFormat *format, + Transform transform = Transform::Identity); + int tryFormat(V4L2SubdeviceFormat *format) const; - const ControlInfoMap &controls() const; - ControlList getControls(const std::vector<uint32_t> &ids); - int setControls(ControlList *ctrls); - - V4L2Subdevice *device() { return subdev_.get(); } + int applyConfiguration(const SensorConfiguration &config, + Transform transform = Transform::Identity, + V4L2SubdeviceFormat *sensorFormat = nullptr); const ControlList &properties() const { return properties_; } int sensorInfo(IPACameraSensorInfo *info) const; + Transform computeTransform(Orientation *orientation) const; + BayerFormat::Order bayerOrder(Transform t) const; - void updateControlInfo(); + const ControlInfoMap &controls() const; + ControlList getControls(const std::vector<uint32_t> &ids); + int setControls(ControlList *ctrls); - CameraLens *focusLens() { return focusLens_.get(); } + const std::vector<controls::draft::TestPatternModeEnum> &testPatternModes() const + { + return testPatternModes_; + } + int setTestPatternMode(controls::draft::TestPatternModeEnum mode); protected: std::string logPrefix() const override; @@ -80,8 +93,8 @@ private: void initStaticProperties(); void initTestPatternModes(); int initProperties(); - int applyTestPatternMode(controls::draft::TestPatternModeEnum mode); int discoverAncillaryDevices(); + int applyTestPatternMode(controls::draft::TestPatternModeEnum mode); const MediaEntity *entity_; std::unique_ptr<V4L2Subdevice> subdev_; @@ -101,6 +114,9 @@ private: Size pixelArraySize_; Rectangle activeArea_; const BayerFormat *bayerFormat_; + bool supportFlips_; + bool flipsAlterBayerOrder_; + Orientation mountingOrientation_; ControlList properties_; diff --git a/include/libcamera/internal/camera_sensor_properties.h b/include/libcamera/internal/camera_sensor_properties.h index 1ee3cb99..480ac121 100644 --- a/include/libcamera/internal/camera_sensor_properties.h +++ b/include/libcamera/internal/camera_sensor_properties.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2021, Google Inc. * - * camera_sensor_properties.h - Database of camera sensor properties + * Database of camera sensor properties */ #pragma once diff --git a/include/libcamera/internal/control_serializer.h b/include/libcamera/internal/control_serializer.h index 99e57fee..8a63ae44 100644 --- a/include/libcamera/internal/control_serializer.h +++ b/include/libcamera/internal/control_serializer.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * control_serializer.h - Control (de)serializer + * Control (de)serializer */ #pragma once @@ -47,9 +47,9 @@ private: static void store(const ControlValue &value, ByteStreamBuffer &buffer); static void store(const ControlInfo &info, ByteStreamBuffer &buffer); - ControlValue loadControlValue(ControlType type, ByteStreamBuffer &buffer, + ControlValue loadControlValue(ByteStreamBuffer &buffer, bool isArray = false, unsigned int count = 1); - ControlInfo loadControlInfo(ControlType type, ByteStreamBuffer &buffer); + ControlInfo loadControlInfo(ByteStreamBuffer &buffer); unsigned int serial_; unsigned int serialSeed_; diff --git a/include/libcamera/internal/control_validator.h b/include/libcamera/internal/control_validator.h index 26412d8b..260602f2 100644 --- a/include/libcamera/internal/control_validator.h +++ b/include/libcamera/internal/control_validator.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * control_validator.h - Control validator + * Control validator */ #pragma once diff --git a/include/libcamera/internal/converter.h b/include/libcamera/internal/converter.h new file mode 100644 index 00000000..5d74db6b --- /dev/null +++ b/include/libcamera/internal/converter.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Laurent Pinchart + * Copyright 2022 NXP + * + * Generic format converter interface + */ + +#pragma once + +#include <functional> +#include <initializer_list> +#include <map> +#include <memory> +#include <string> +#include <tuple> +#include <vector> + +#include <libcamera/base/class.h> +#include <libcamera/base/signal.h> + +#include <libcamera/geometry.h> + +namespace libcamera { + +class FrameBuffer; +class MediaDevice; +class PixelFormat; +struct StreamConfiguration; + +class Converter +{ +public: + Converter(MediaDevice *media); + virtual ~Converter(); + + virtual int loadConfiguration(const std::string &filename) = 0; + + virtual bool isValid() const = 0; + + virtual std::vector<PixelFormat> formats(PixelFormat input) = 0; + virtual SizeRange sizes(const Size &input) = 0; + + virtual std::tuple<unsigned int, unsigned int> + strideAndFrameSize(const PixelFormat &pixelFormat, const Size &size) = 0; + + virtual int configure(const StreamConfiguration &inputCfg, + const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs) = 0; + virtual int exportBuffers(unsigned int output, unsigned int count, + std::vector<std::unique_ptr<FrameBuffer>> *buffers) = 0; + + virtual int start() = 0; + virtual void stop() = 0; + + virtual int queueBuffers(FrameBuffer *input, + const std::map<unsigned int, FrameBuffer *> &outputs) = 0; + + Signal<FrameBuffer *> inputBufferReady; + Signal<FrameBuffer *> outputBufferReady; + + const std::string &deviceNode() const { return deviceNode_; } + +private: + std::string deviceNode_; +}; + +class ConverterFactoryBase +{ +public: + ConverterFactoryBase(const std::string name, std::initializer_list<std::string> compatibles); + virtual ~ConverterFactoryBase() = default; + + const std::vector<std::string> &compatibles() const { return compatibles_; } + + static std::unique_ptr<Converter> create(MediaDevice *media); + static std::vector<ConverterFactoryBase *> &factories(); + static std::vector<std::string> names(); + +private: + LIBCAMERA_DISABLE_COPY_AND_MOVE(ConverterFactoryBase) + + static void registerType(ConverterFactoryBase *factory); + + virtual std::unique_ptr<Converter> createInstance(MediaDevice *media) const = 0; + + std::string name_; + std::vector<std::string> compatibles_; +}; + +template<typename _Converter> +class ConverterFactory : public ConverterFactoryBase +{ +public: + ConverterFactory(const char *name, std::initializer_list<std::string> compatibles) + : ConverterFactoryBase(name, compatibles) + { + } + + std::unique_ptr<Converter> createInstance(MediaDevice *media) const override + { + return std::make_unique<_Converter>(media); + } +}; + +#define REGISTER_CONVERTER(name, converter, compatibles) \ + static ConverterFactory<converter> global_##converter##Factory(name, compatibles); + +} /* namespace libcamera */ diff --git a/include/libcamera/internal/converter/converter_v4l2_m2m.h b/include/libcamera/internal/converter/converter_v4l2_m2m.h new file mode 100644 index 00000000..1126050c --- /dev/null +++ b/include/libcamera/internal/converter/converter_v4l2_m2m.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Laurent Pinchart + * Copyright 2022 NXP + * + * V4l2 M2M Format converter interface + */ + +#pragma once + +#include <functional> +#include <map> +#include <memory> +#include <string> +#include <tuple> +#include <vector> + +#include <libcamera/base/log.h> +#include <libcamera/base/signal.h> + +#include <libcamera/pixel_format.h> + +#include "libcamera/internal/converter.h" + +namespace libcamera { + +class FrameBuffer; +class MediaDevice; +class Size; +class SizeRange; +struct StreamConfiguration; +class V4L2M2MDevice; + +class V4L2M2MConverter : public Converter +{ +public: + V4L2M2MConverter(MediaDevice *media); + + int loadConfiguration([[maybe_unused]] const std::string &filename) { return 0; } + bool isValid() const { return m2m_ != nullptr; } + + std::vector<PixelFormat> formats(PixelFormat input); + SizeRange sizes(const Size &input); + + std::tuple<unsigned int, unsigned int> + strideAndFrameSize(const PixelFormat &pixelFormat, const Size &size); + + int configure(const StreamConfiguration &inputCfg, + const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfg); + int exportBuffers(unsigned int output, unsigned int count, + std::vector<std::unique_ptr<FrameBuffer>> *buffers); + + int start(); + void stop(); + + int queueBuffers(FrameBuffer *input, + const std::map<unsigned int, FrameBuffer *> &outputs); + +private: + class Stream : protected Loggable + { + public: + Stream(V4L2M2MConverter *converter, unsigned int index); + + bool isValid() const { return m2m_ != nullptr; } + + int configure(const StreamConfiguration &inputCfg, + const StreamConfiguration &outputCfg); + int exportBuffers(unsigned int count, + std::vector<std::unique_ptr<FrameBuffer>> *buffers); + + int start(); + void stop(); + + int queueBuffers(FrameBuffer *input, FrameBuffer *output); + + protected: + std::string logPrefix() const override; + + private: + void captureBufferReady(FrameBuffer *buffer); + void outputBufferReady(FrameBuffer *buffer); + + V4L2M2MConverter *converter_; + unsigned int index_; + std::unique_ptr<V4L2M2MDevice> m2m_; + + unsigned int inputBufferCount_; + unsigned int outputBufferCount_; + }; + + std::unique_ptr<V4L2M2MDevice> m2m_; + + std::vector<Stream> streams_; + std::map<FrameBuffer *, unsigned int> queue_; +}; + +} /* namespace libcamera */ diff --git a/include/libcamera/internal/converter/meson.build b/include/libcamera/internal/converter/meson.build new file mode 100644 index 00000000..891e79e7 --- /dev/null +++ b/include/libcamera/internal/converter/meson.build @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: CC0-1.0 + +libcamera_internal_headers += files([ + 'converter_v4l2_m2m.h', +]) diff --git a/include/libcamera/internal/delayed_controls.h b/include/libcamera/internal/delayed_controls.h index 703fdb66..e8d3014d 100644 --- a/include/libcamera/internal/delayed_controls.h +++ b/include/libcamera/internal/delayed_controls.h @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* - * Copyright (C) 2020, Raspberry Pi (Trading) Ltd. + * Copyright (C) 2020, Raspberry Pi Ltd * - * delayed_controls.h - Helper to deal with controls that take effect with a delay + * Helper to deal with controls that take effect with a delay */ #pragma once @@ -51,7 +51,7 @@ private: bool updated; }; - /* \todo: Make the listSize configurable at instance creation time. */ + /* \todo Make the listSize configurable at instance creation time. */ static constexpr int listSize = 16; class ControlRingBuffer : public std::array<Info, listSize> { @@ -72,9 +72,6 @@ private: std::unordered_map<const ControlId *, ControlParams> controlParams_; 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 */ diff --git a/include/libcamera/internal/device_enumerator.h b/include/libcamera/internal/device_enumerator.h index 72ec9a60..db3532a9 100644 --- a/include/libcamera/internal/device_enumerator.h +++ b/include/libcamera/internal/device_enumerator.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2018, Google Inc. * - * device_enumerator.h - API to enumerate and find media devices + * API to enumerate and find media devices */ #pragma once diff --git a/include/libcamera/internal/device_enumerator_sysfs.h b/include/libcamera/internal/device_enumerator_sysfs.h index 3e84b83f..a5bfc711 100644 --- a/include/libcamera/internal/device_enumerator_sysfs.h +++ b/include/libcamera/internal/device_enumerator_sysfs.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * device_enumerator_sysfs.h - sysfs-based device enumerator + * sysfs-based device enumerator */ #pragma once diff --git a/include/libcamera/internal/device_enumerator_udev.h b/include/libcamera/internal/device_enumerator_udev.h index 1b3360df..1378c190 100644 --- a/include/libcamera/internal/device_enumerator_udev.h +++ b/include/libcamera/internal/device_enumerator_udev.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2018-2019, Google Inc. * - * device_enumerator_udev.h - udev-based device enumerator + * udev-based device enumerator */ #pragma once diff --git a/include/libcamera/internal/dma_heaps.h b/include/libcamera/internal/dma_heaps.h new file mode 100644 index 00000000..f0a8aa5d --- /dev/null +++ b/include/libcamera/internal/dma_heaps.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Raspberry Pi Ltd + * + * Helper class for dma-heap allocations. + */ + +#pragma once + +#include <stddef.h> + +#include <libcamera/base/flags.h> +#include <libcamera/base/unique_fd.h> + +namespace libcamera { + +class DmaHeap +{ +public: + enum class DmaHeapFlag { + Cma = 1 << 0, + System = 1 << 1, + }; + + using DmaHeapFlags = Flags<DmaHeapFlag>; + + DmaHeap(DmaHeapFlags flags = DmaHeapFlag::Cma); + ~DmaHeap(); + bool isValid() const { return dmaHeapHandle_.isValid(); } + UniqueFD alloc(const char *name, std::size_t size); + +private: + UniqueFD dmaHeapHandle_; +}; + +LIBCAMERA_FLAGS_ENABLE_OPERATORS(DmaHeap::DmaHeapFlag) + +} /* namespace libcamera */ diff --git a/include/libcamera/internal/formats.h b/include/libcamera/internal/formats.h index ee599765..71895cd8 100644 --- a/include/libcamera/internal/formats.h +++ b/include/libcamera/internal/formats.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * formats.h - libcamera image formats + * libcamera image formats */ #pragma once @@ -53,10 +53,7 @@ public: /* \todo Add support for non-contiguous memory planes */ const char *name; PixelFormat format; - struct { - V4L2PixelFormat single; - V4L2PixelFormat multi; - } v4l2Formats; + std::vector<V4L2PixelFormat> v4l2Formats; unsigned int bitsPerPixel; enum ColourEncoding colourEncoding; bool packed; diff --git a/include/libcamera/internal/framebuffer.h b/include/libcamera/internal/framebuffer.h index 8a9cc98e..e6698a45 100644 --- a/include/libcamera/internal/framebuffer.h +++ b/include/libcamera/internal/framebuffer.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2020, Google Inc. * - * framebuffer.h - Internal frame buffer handling + * Internal frame buffer handling */ #pragma once @@ -22,7 +22,7 @@ class FrameBuffer::Private : public Extensible::Private LIBCAMERA_DECLARE_PUBLIC(FrameBuffer) public: - Private(); + Private(const std::vector<Plane> &planes, uint64_t cookie = 0); virtual ~Private(); void setRequest(Request *request) { request_ = request; } @@ -31,9 +31,15 @@ public: Fence *fence() const { return fence_.get(); } void setFence(std::unique_ptr<Fence> fence) { fence_ = std::move(fence); } - void cancel() { LIBCAMERA_O_PTR()->metadata_.status = FrameMetadata::FrameCancelled; } + void cancel() { metadata_.status = FrameMetadata::FrameCancelled; } + + FrameMetadata &metadata() { return metadata_; } private: + std::vector<Plane> planes_; + FrameMetadata metadata_; + uint64_t cookie_; + std::unique_ptr<Fence> fence_; Request *request_; bool isContiguous_; diff --git a/include/libcamera/internal/ipa_data_serializer.h b/include/libcamera/internal/ipa_data_serializer.h index a87449c9..337c948c 100644 --- a/include/libcamera/internal/ipa_data_serializer.h +++ b/include/libcamera/internal/ipa_data_serializer.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2020, Google Inc. * - * ipa_data_serializer.h - Image Processing Algorithm data serializer + * Image Processing Algorithm data serializer */ #pragma once @@ -14,6 +14,7 @@ #include <type_traits> #include <vector> +#include <libcamera/base/flags.h> #include <libcamera/base/log.h> #include <libcamera/control_ids.h> @@ -32,7 +33,7 @@ LOG_DECLARE_CATEGORY(IPADataSerializer) namespace { template<typename T, - typename std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr> + std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr> void appendPOD(std::vector<uint8_t> &vec, T val) { constexpr size_t byteWidth = sizeof(val); @@ -134,7 +135,7 @@ public: static std::vector<V> deserialize(std::vector<uint8_t> &data, ControlSerializer *cs = nullptr) { - return deserialize(data.cbegin(), data.end(), cs); + return deserialize(data.cbegin(), data.cend(), cs); } static std::vector<V> deserialize(std::vector<uint8_t>::const_iterator dataBegin, @@ -142,13 +143,13 @@ public: ControlSerializer *cs = nullptr) { std::vector<SharedFD> fds; - return deserialize(dataBegin, dataEnd, fds.cbegin(), fds.end(), cs); + return deserialize(dataBegin, dataEnd, fds.cbegin(), fds.cend(), cs); } static std::vector<V> deserialize(std::vector<uint8_t> &data, std::vector<SharedFD> &fds, ControlSerializer *cs = nullptr) { - return deserialize(data.cbegin(), data.end(), fds.cbegin(), fds.end(), cs); + return deserialize(data.cbegin(), data.cend(), fds.cbegin(), fds.cend(), cs); } static std::vector<V> deserialize(std::vector<uint8_t>::const_iterator dataBegin, @@ -240,7 +241,7 @@ public: static std::map<K, V> deserialize(std::vector<uint8_t> &data, ControlSerializer *cs = nullptr) { - return deserialize(data.cbegin(), data.end(), cs); + return deserialize(data.cbegin(), data.cend(), cs); } static std::map<K, V> deserialize(std::vector<uint8_t>::const_iterator dataBegin, @@ -248,13 +249,13 @@ public: ControlSerializer *cs = nullptr) { std::vector<SharedFD> fds; - return deserialize(dataBegin, dataEnd, fds.cbegin(), fds.end(), cs); + return deserialize(dataBegin, dataEnd, fds.cbegin(), fds.cend(), cs); } static std::map<K, V> deserialize(std::vector<uint8_t> &data, std::vector<SharedFD> &fds, ControlSerializer *cs = nullptr) { - return deserialize(data.cbegin(), data.end(), fds.cbegin(), fds.end(), cs); + return deserialize(data.cbegin(), data.cend(), fds.cbegin(), fds.cend(), cs); } static std::map<K, V> deserialize(std::vector<uint8_t>::const_iterator dataBegin, @@ -301,6 +302,51 @@ public: } }; +/* Serialization format for Flags is same as for PODs */ +template<typename E> +class IPADataSerializer<Flags<E>> +{ +public: + static std::tuple<std::vector<uint8_t>, std::vector<SharedFD>> + serialize(const Flags<E> &data, [[maybe_unused]] ControlSerializer *cs = nullptr) + { + std::vector<uint8_t> dataVec; + dataVec.reserve(sizeof(Flags<E>)); + appendPOD<uint32_t>(dataVec, static_cast<typename Flags<E>::Type>(data)); + + return { dataVec, {} }; + } + + static Flags<E> deserialize(std::vector<uint8_t> &data, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + return deserialize(data.cbegin(), data.cend()); + } + + static Flags<E> deserialize(std::vector<uint8_t>::const_iterator dataBegin, + std::vector<uint8_t>::const_iterator dataEnd, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + return Flags<E>{ static_cast<E>(readPOD<uint32_t>(dataBegin, 0, dataEnd)) }; + } + + static Flags<E> deserialize(std::vector<uint8_t> &data, + [[maybe_unused]] std::vector<SharedFD> &fds, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + return deserialize(data.cbegin(), data.cend()); + } + + static Flags<E> deserialize(std::vector<uint8_t>::const_iterator dataBegin, + std::vector<uint8_t>::const_iterator dataEnd, + [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsBegin, + [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + return deserialize(dataBegin, dataEnd); + } +}; + #endif /* __DOXYGEN__ */ } /* namespace libcamera */ diff --git a/include/libcamera/internal/ipa_manager.h b/include/libcamera/internal/ipa_manager.h index 7f36e58e..c6f74e11 100644 --- a/include/libcamera/internal/ipa_manager.h +++ b/include/libcamera/internal/ipa_manager.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * ipa_manager.h - Image Processing Algorithm module manager + * Image Processing Algorithm module manager */ #pragma once @@ -47,6 +47,13 @@ public: return proxy; } +#if HAVE_IPA_PUBKEY + static const PubKey &pubKey() + { + return pubKey_; + } +#endif + private: static IPAManager *self_; diff --git a/include/libcamera/internal/ipa_module.h b/include/libcamera/internal/ipa_module.h index 8038bdee..7c49d3f3 100644 --- a/include/libcamera/internal/ipa_module.h +++ b/include/libcamera/internal/ipa_module.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * ipa_module.h - Image Processing Algorithm module + * Image Processing Algorithm module */ #pragma once diff --git a/include/libcamera/internal/ipa_proxy.h b/include/libcamera/internal/ipa_proxy.h index 781c8b62..ed6a5bcf 100644 --- a/include/libcamera/internal/ipa_proxy.h +++ b/include/libcamera/internal/ipa_proxy.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * ipa_proxy.h - Image Processing Algorithm proxy + * Image Processing Algorithm proxy */ #pragma once diff --git a/include/libcamera/internal/ipc_pipe.h b/include/libcamera/internal/ipc_pipe.h index ab5dd67c..a4560752 100644 --- a/include/libcamera/internal/ipc_pipe.h +++ b/include/libcamera/internal/ipc_pipe.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2020, Google Inc. * - * ipc_pipe.h - Image Processing Algorithm IPC module for IPA proxies + * Image Processing Algorithm IPC module for IPA proxies */ #pragma once diff --git a/include/libcamera/internal/ipc_pipe_unixsocket.h b/include/libcamera/internal/ipc_pipe_unixsocket.h index 004d9539..4a0f6d57 100644 --- a/include/libcamera/internal/ipc_pipe_unixsocket.h +++ b/include/libcamera/internal/ipc_pipe_unixsocket.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2020, Google Inc. * - * ipc_pipe_unixsocket.h - Image Processing Algorithm IPC module using unix socket + * Image Processing Algorithm IPC module using unix socket */ #pragma once diff --git a/include/libcamera/internal/ipc_unixsocket.h b/include/libcamera/internal/ipc_unixsocket.h index 3963d182..48bb7a94 100644 --- a/include/libcamera/internal/ipc_unixsocket.h +++ b/include/libcamera/internal/ipc_unixsocket.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * ipc_unixsocket.h - IPC mechanism based on Unix sockets + * IPC mechanism based on Unix sockets */ #pragma once diff --git a/include/libcamera/internal/mapped_framebuffer.h b/include/libcamera/internal/mapped_framebuffer.h index fb39adbf..6aaabf50 100644 --- a/include/libcamera/internal/mapped_framebuffer.h +++ b/include/libcamera/internal/mapped_framebuffer.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2021, Google Inc. * - * mapped_framebuffer.h - Frame buffer memory mapping support + * Frame buffer memory mapping support */ #pragma once diff --git a/include/libcamera/internal/media_device.h b/include/libcamera/internal/media_device.h index eb8cfde4..bf2e475d 100644 --- a/include/libcamera/internal/media_device.h +++ b/include/libcamera/internal/media_device.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2018, Google Inc. * - * media_device.h - Media device handler + * Media device handler */ #pragma once diff --git a/include/libcamera/internal/media_object.h b/include/libcamera/internal/media_object.h index b1572968..c9d77511 100644 --- a/include/libcamera/internal/media_object.h +++ b/include/libcamera/internal/media_object.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2018, Google Inc. * - * media_object.h - Media Device objects: entities, pads and links. + * Media Device objects: entities, pads and links. */ #pragma once diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build index 7a780d48..160fdc37 100644 --- a/include/libcamera/internal/meson.build +++ b/include/libcamera/internal/meson.build @@ -4,9 +4,9 @@ subdir('tracepoints') libcamera_tracepoint_header = custom_target( 'tp_header', - input: ['tracepoints.h.in', tracepoint_files], - output: 'tracepoints.h', - command: [gen_tracepoints_header, '@OUTPUT@', '@INPUT@'], + input : ['tracepoints.h.in', tracepoint_files], + output : 'tracepoints.h', + command : [gen_tracepoints_header, include_build_dir, '@OUTPUT@', '@INPUT@'], ) libcamera_internal_headers = files([ @@ -15,14 +15,17 @@ libcamera_internal_headers = files([ 'camera.h', 'camera_controls.h', 'camera_lens.h', + 'camera_manager.h', 'camera_sensor.h', 'camera_sensor_properties.h', 'control_serializer.h', 'control_validator.h', + 'converter.h', 'delayed_controls.h', 'device_enumerator.h', 'device_enumerator_sysfs.h', 'device_enumerator_udev.h', + 'dma_heaps.h', 'formats.h', 'framebuffer.h', 'ipa_manager.h', @@ -36,6 +39,7 @@ libcamera_internal_headers = files([ 'process.h', 'pub_key.h', 'request.h', + 'shared_mem_object.h', 'source_paths.h', 'sysfs.h', 'v4l2_device.h', @@ -44,3 +48,6 @@ libcamera_internal_headers = files([ 'v4l2_videodevice.h', 'yaml_parser.h', ]) + +subdir('converter') +subdir('software_isp') diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index c3e4c258..746a34f8 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2018, Google Inc. * - * pipeline_handler.h - Pipeline handler infrastructure + * Pipeline handler infrastructure */ #pragma once @@ -45,11 +45,11 @@ public: MediaDevice *acquireMediaDevice(DeviceEnumerator *enumerator, const DeviceMatch &dm); - bool lock(); - void unlock(); + bool acquire(); + void release(Camera *camera); - virtual CameraConfiguration *generateConfiguration(Camera *camera, - const StreamRoles &roles) = 0; + virtual std::unique_ptr<CameraConfiguration> generateConfiguration(Camera *camera, + Span<const StreamRole> roles) = 0; virtual int configure(Camera *camera, CameraConfiguration *config) = 0; virtual int exportFrameBuffers(Camera *camera, Stream *stream, @@ -65,6 +65,9 @@ public: bool completeBuffer(Request *request, FrameBuffer *buffer); void completeRequest(Request *request); + std::string configurationFile(const std::string &subdir, + const std::string &name) const; + const char *name() const { return name_; } protected: @@ -74,9 +77,13 @@ protected: virtual int queueRequestDevice(Camera *camera, Request *request) = 0; virtual void stopDevice(Camera *camera) = 0; + virtual void releaseDevice(Camera *camera); + CameraManager *manager_; private: + void unlockMediaDevices(); + void mediaDeviceDisconnected(MediaDevice *media); virtual void disconnect(); @@ -91,42 +98,50 @@ private: const char *name_; Mutex lock_; - bool lockOwner_ LIBCAMERA_TSA_GUARDED_BY(lock_); /* *Not* ownership of lock_ */ + unsigned int useCount_ LIBCAMERA_TSA_GUARDED_BY(lock_); - friend class PipelineHandlerFactory; + friend class PipelineHandlerFactoryBase; }; -class PipelineHandlerFactory +class PipelineHandlerFactoryBase { public: - PipelineHandlerFactory(const char *name); - virtual ~PipelineHandlerFactory() = default; + PipelineHandlerFactoryBase(const char *name); + virtual ~PipelineHandlerFactoryBase() = default; - std::shared_ptr<PipelineHandler> create(CameraManager *manager); + std::shared_ptr<PipelineHandler> create(CameraManager *manager) const; const std::string &name() const { return name_; } - static void registerType(PipelineHandlerFactory *factory); - static std::vector<PipelineHandlerFactory *> &factories(); + static std::vector<PipelineHandlerFactoryBase *> &factories(); + static const PipelineHandlerFactoryBase *getFactoryByName(const std::string &name); private: - virtual PipelineHandler *createInstance(CameraManager *manager) = 0; + static void registerType(PipelineHandlerFactoryBase *factory); + + virtual std::unique_ptr<PipelineHandler> + createInstance(CameraManager *manager) const = 0; std::string name_; }; -#define REGISTER_PIPELINE_HANDLER(handler) \ -class handler##Factory final : public PipelineHandlerFactory \ -{ \ -public: \ - handler##Factory() : PipelineHandlerFactory(#handler) {} \ - \ -private: \ - PipelineHandler *createInstance(CameraManager *manager) \ - { \ - return new handler(manager); \ - } \ -}; \ -static handler##Factory global_##handler##Factory; +template<typename _PipelineHandler> +class PipelineHandlerFactory final : public PipelineHandlerFactoryBase +{ +public: + PipelineHandlerFactory(const char *name) + : PipelineHandlerFactoryBase(name) + { + } + + std::unique_ptr<PipelineHandler> + createInstance(CameraManager *manager) const override + { + return std::make_unique<_PipelineHandler>(manager); + } +}; + +#define REGISTER_PIPELINE_HANDLER(handler, name) \ + static PipelineHandlerFactory<handler> global_##handler##Factory(name); } /* namespace libcamera */ diff --git a/include/libcamera/internal/process.h b/include/libcamera/internal/process.h index 95e67e10..b1d07a5a 100644 --- a/include/libcamera/internal/process.h +++ b/include/libcamera/internal/process.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * process.h - Process object + * Process object */ #pragma once diff --git a/include/libcamera/internal/pub_key.h b/include/libcamera/internal/pub_key.h index a22ba037..c8cc04cb 100644 --- a/include/libcamera/internal/pub_key.h +++ b/include/libcamera/internal/pub_key.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2020, Google Inc. * - * pub_key.h - Public key signature verification + * Public key signature verification */ #pragma once @@ -11,7 +11,9 @@ #include <libcamera/base/span.h> -#if HAVE_GNUTLS +#if HAVE_CRYPTO +struct evp_pkey_st; +#elif HAVE_GNUTLS struct gnutls_pubkey_st; #endif @@ -28,7 +30,9 @@ public: private: bool valid_; -#if HAVE_GNUTLS +#if HAVE_CRYPTO + struct evp_pkey_st *pubkey_; +#elif HAVE_GNUTLS struct gnutls_pubkey_st *pubkey_; #endif }; diff --git a/include/libcamera/internal/request.h b/include/libcamera/internal/request.h index 9dadd6c6..f5d98069 100644 --- a/include/libcamera/internal/request.h +++ b/include/libcamera/internal/request.h @@ -2,10 +2,10 @@ /* * Copyright (C) 2019, Google Inc. * - * request.h - Request class private data + * Request class private data */ -#ifndef __LIBCAMERA_INTERNAL_REQUEST_H__ -#define __LIBCAMERA_INTERNAL_REQUEST_H__ + +#pragma once #include <chrono> #include <map> @@ -37,7 +37,7 @@ public: bool completeBuffer(FrameBuffer *buffer); void complete(); void cancel(); - void reuse(); + void reset(); void prepare(std::chrono::milliseconds timeout = 0ms); Signal<> prepared; @@ -62,5 +62,3 @@ private: }; } /* namespace libcamera */ - -#endif /* __LIBCAMERA_INTERNAL_REQUEST_H__ */ diff --git a/include/libcamera/internal/shared_mem_object.h b/include/libcamera/internal/shared_mem_object.h new file mode 100644 index 00000000..2ab0189f --- /dev/null +++ b/include/libcamera/internal/shared_mem_object.h @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023 Raspberry Pi Ltd + * Copyright (C) 2024 Andrei Konovalov + * Copyright (C) 2024 Dennis Bonke + * + * Helpers for shared memory allocations + */ +#pragma once + +#include <stddef.h> +#include <stdint.h> +#include <string> +#include <sys/mman.h> +#include <type_traits> +#include <utility> + +#include <libcamera/base/class.h> +#include <libcamera/base/shared_fd.h> +#include <libcamera/base/span.h> + +namespace libcamera { + +class SharedMem +{ +public: + SharedMem(); + + SharedMem(const std::string &name, std::size_t size); + SharedMem(SharedMem &&rhs); + + virtual ~SharedMem(); + + SharedMem &operator=(SharedMem &&rhs); + + const SharedFD &fd() const + { + return fd_; + } + + Span<uint8_t> mem() const + { + return mem_; + } + + explicit operator bool() const + { + return !mem_.empty(); + } + +private: + LIBCAMERA_DISABLE_COPY(SharedMem) + + SharedFD fd_; + + Span<uint8_t> mem_; +}; + +template<class T, typename = std::enable_if_t<std::is_standard_layout<T>::value>> +class SharedMemObject : public SharedMem +{ +public: + static constexpr std::size_t kSize = sizeof(T); + + SharedMemObject() + : SharedMem(), obj_(nullptr) + { + } + + template<class... Args> + SharedMemObject(const std::string &name, Args &&...args) + : SharedMem(name, kSize), obj_(nullptr) + { + if (mem().empty()) + return; + + obj_ = new (mem().data()) T(std::forward<Args>(args)...); + } + + SharedMemObject(SharedMemObject<T> &&rhs) + : SharedMem(std::move(rhs)) + { + this->obj_ = rhs.obj_; + rhs.obj_ = nullptr; + } + + ~SharedMemObject() + { + if (obj_) + obj_->~T(); + } + + SharedMemObject<T> &operator=(SharedMemObject<T> &&rhs) + { + SharedMem::operator=(std::move(rhs)); + this->obj_ = rhs.obj_; + rhs.obj_ = nullptr; + return *this; + } + + T *operator->() + { + return obj_; + } + + const T *operator->() const + { + return obj_; + } + + T &operator*() + { + return *obj_; + } + + const T &operator*() const + { + return *obj_; + } + +private: + LIBCAMERA_DISABLE_COPY(SharedMemObject) + + T *obj_; +}; + +} /* namespace libcamera */ diff --git a/include/libcamera/internal/software_isp/debayer_params.h b/include/libcamera/internal/software_isp/debayer_params.h new file mode 100644 index 00000000..ce1b5945 --- /dev/null +++ b/include/libcamera/internal/software_isp/debayer_params.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Red Hat Inc. + * + * Authors: + * Hans de Goede <hdegoede@redhat.com> + * + * DebayerParams header + */ + +#pragma once + +namespace libcamera { + +struct DebayerParams { + static constexpr unsigned int kGain10 = 256; + + unsigned int gainR; + unsigned int gainG; + unsigned int gainB; + + float gamma; + /** + * \brief Level of the black point, 0..255, 0 is no correction. + */ + unsigned int blackLevel; +}; + +} /* namespace libcamera */ diff --git a/include/libcamera/internal/software_isp/meson.build b/include/libcamera/internal/software_isp/meson.build new file mode 100644 index 00000000..508ddddc --- /dev/null +++ b/include/libcamera/internal/software_isp/meson.build @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: CC0-1.0 + +libcamera_internal_headers += files([ + 'debayer_params.h', + 'software_isp.h', + 'swisp_stats.h', +]) diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h new file mode 100644 index 00000000..7e9fae6a --- /dev/null +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Linaro Ltd + * + * Simple software ISP implementation + */ + +#pragma once + +#include <functional> +#include <initializer_list> +#include <map> +#include <memory> +#include <string> +#include <tuple> +#include <vector> + +#include <libcamera/base/class.h> +#include <libcamera/base/log.h> +#include <libcamera/base/signal.h> +#include <libcamera/base/thread.h> + +#include <libcamera/geometry.h> +#include <libcamera/pixel_format.h> + +#include <libcamera/ipa/soft_ipa_interface.h> +#include <libcamera/ipa/soft_ipa_proxy.h> + +#include "libcamera/internal/camera_sensor.h" +#include "libcamera/internal/dma_heaps.h" +#include "libcamera/internal/pipeline_handler.h" +#include "libcamera/internal/shared_mem_object.h" +#include "libcamera/internal/software_isp/debayer_params.h" + +namespace libcamera { + +class DebayerCpu; +class FrameBuffer; +class PixelFormat; +struct StreamConfiguration; + +LOG_DECLARE_CATEGORY(SoftwareIsp) + +class SoftwareIsp +{ +public: + SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor); + ~SoftwareIsp(); + + int loadConfiguration([[maybe_unused]] const std::string &filename) { return 0; } + + bool isValid() const; + + std::vector<PixelFormat> formats(PixelFormat input); + + SizeRange sizes(PixelFormat inputFormat, const Size &inputSize); + + std::tuple<unsigned int, unsigned int> + strideAndFrameSize(const PixelFormat &outputFormat, const Size &size); + + int configure(const StreamConfiguration &inputCfg, + const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs, + const ControlInfoMap &sensorControls); + + int exportBuffers(unsigned int output, unsigned int count, + std::vector<std::unique_ptr<FrameBuffer>> *buffers); + + void processStats(const ControlList &sensorControls); + + int start(); + void stop(); + + int queueBuffers(FrameBuffer *input, + const std::map<unsigned int, FrameBuffer *> &outputs); + + void process(FrameBuffer *input, FrameBuffer *output); + + Signal<FrameBuffer *> inputBufferReady; + Signal<FrameBuffer *> outputBufferReady; + Signal<> ispStatsReady; + Signal<const ControlList &> setSensorControls; + +private: + void saveIspParams(); + void setSensorCtrls(const ControlList &sensorControls); + void statsReady(); + void inputReady(FrameBuffer *input); + void outputReady(FrameBuffer *output); + + std::unique_ptr<DebayerCpu> debayer_; + Thread ispWorkerThread_; + SharedMemObject<DebayerParams> sharedParams_; + DebayerParams debayerParams_; + DmaHeap dmaHeap_; + + std::unique_ptr<ipa::soft::IPAProxySoft> ipa_; +}; + +} /* namespace libcamera */ diff --git a/include/libcamera/internal/software_isp/swisp_stats.h b/include/libcamera/internal/software_isp/swisp_stats.h new file mode 100644 index 00000000..ae11f112 --- /dev/null +++ b/include/libcamera/internal/software_isp/swisp_stats.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Linaro Ltd + * + * Statistics data format used by the software ISP and software IPA + */ + +#pragma once + +#include <array> +#include <stdint.h> + +namespace libcamera { + +/** + * \brief Struct that holds the statistics for the Software ISP + * + * The struct value types are large enough to not overflow. + * Should they still overflow for some reason, no check is performed and they + * wrap around. + */ +struct SwIspStats { + /** + * \brief Holds the sum of all sampled red pixels + */ + uint64_t sumR_; + /** + * \brief Holds the sum of all sampled green pixels + */ + uint64_t sumG_; + /** + * \brief Holds the sum of all sampled blue pixels + */ + uint64_t sumB_; + /** + * \brief Number of bins in the yHistogram + */ + static constexpr unsigned int kYHistogramSize = 64; + /** + * \brief Type of the histogram. + */ + using Histogram = std::array<uint32_t, kYHistogramSize>; + /** + * \brief A histogram of luminance values + */ + Histogram yHistogram; +}; + +} /* namespace libcamera */ diff --git a/include/libcamera/internal/source_paths.h b/include/libcamera/internal/source_paths.h index be6f153b..14e64717 100644 --- a/include/libcamera/internal/source_paths.h +++ b/include/libcamera/internal/source_paths.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2021, Google Inc. * - * source_paths.h - Identify libcamera source and build paths + * Identify libcamera source and build paths */ #pragma once diff --git a/include/libcamera/internal/sysfs.h b/include/libcamera/internal/sysfs.h index 917457be..aca60fb6 100644 --- a/include/libcamera/internal/sysfs.h +++ b/include/libcamera/internal/sysfs.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2020, Google Inc. * - * sysfs.h - Miscellaneous utility functions to access sysfs + * Miscellaneous utility functions to access sysfs */ #pragma once diff --git a/include/libcamera/internal/tracepoints.h.in b/include/libcamera/internal/tracepoints.h.in index d0fc1365..f0962091 100644 --- a/include/libcamera/internal/tracepoints.h.in +++ b/include/libcamera/internal/tracepoints.h.in @@ -2,7 +2,7 @@ /* * Copyright (C) {{year}}, Google Inc. * - * tracepoints.h - Tracepoints with lttng + * Tracepoints with lttng * * This file is auto-generated. Do not edit. */ diff --git a/include/libcamera/internal/tracepoints/request.tp b/include/libcamera/internal/tracepoints/request.tp index f1e54497..4f367e91 100644 --- a/include/libcamera/internal/tracepoints/request.tp +++ b/include/libcamera/internal/tracepoints/request.tp @@ -5,10 +5,10 @@ * request.tp - Tracepoints for the request object */ -#include <libcamera/internal/request.h> - #include <libcamera/framebuffer.h> +#include "libcamera/internal/request.h" + TRACEPOINT_EVENT_CLASS( libcamera, request, diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h index a52a5f2c..f5aa5024 100644 --- a/include/libcamera/internal/v4l2_device.h +++ b/include/libcamera/internal/v4l2_device.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * v4l2_device.h - Common base for V4L2 video devices and subdevices + * Common base for V4L2 video devices and subdevices */ #pragma once @@ -22,6 +22,8 @@ #include <libcamera/color_space.h> #include <libcamera/controls.h> +#include "libcamera/internal/formats.h" + namespace libcamera { class EventNotifier; @@ -59,7 +61,8 @@ protected: int fd() const { return fd_.get(); } template<typename T> - static std::optional<ColorSpace> toColorSpace(const T &v4l2Format); + static std::optional<ColorSpace> toColorSpace(const T &v4l2Format, + PixelFormatInfo::ColourEncoding colourEncoding); template<typename T> static int fromColorSpace(const std::optional<ColorSpace> &colorSpace, T &v4l2Format); @@ -67,8 +70,8 @@ protected: private: static ControlType v4l2CtrlType(uint32_t ctrlType); static std::unique_ptr<ControlId> v4l2ControlId(const v4l2_query_ext_ctrl &ctrl); - ControlInfo v4l2ControlInfo(const v4l2_query_ext_ctrl &ctrl); - ControlInfo v4l2MenuControlInfo(const v4l2_query_ext_ctrl &ctrl); + std::optional<ControlInfo> v4l2ControlInfo(const v4l2_query_ext_ctrl &ctrl); + std::optional<ControlInfo> v4l2MenuControlInfo(const v4l2_query_ext_ctrl &ctrl); void listControls(); void updateControls(ControlList *ctrls, diff --git a/include/libcamera/internal/v4l2_pixelformat.h b/include/libcamera/internal/v4l2_pixelformat.h index fb2d5d0b..c836346b 100644 --- a/include/libcamera/internal/v4l2_pixelformat.h +++ b/include/libcamera/internal/v4l2_pixelformat.h @@ -1,16 +1,18 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * Copyright (C) 2019, Google Inc. - * Copyright (C) 2020, Raspberry Pi (Trading) Ltd. + * Copyright (C) 2020, Raspberry Pi Ltd * - * v4l2_pixelformat.h - V4L2 Pixel Format + * V4L2 Pixel Format */ #pragma once +#include <functional> #include <ostream> #include <stdint.h> #include <string> +#include <vector> #include <linux/videodev2.h> @@ -43,9 +45,9 @@ public: std::string toString() const; const char *description() const; - PixelFormat toPixelFormat() const; - static V4L2PixelFormat fromPixelFormat(const PixelFormat &pixelFormat, - bool multiplanar = false); + PixelFormat toPixelFormat(bool warn = true) const; + static const std::vector<V4L2PixelFormat> & + fromPixelFormat(const PixelFormat &pixelFormat); private: uint32_t fourcc_; @@ -54,3 +56,15 @@ private: std::ostream &operator<<(std::ostream &out, const V4L2PixelFormat &f); } /* namespace libcamera */ + +namespace std { + +template<> +struct hash<libcamera::V4L2PixelFormat> { + size_t operator()(libcamera::V4L2PixelFormat const &format) const noexcept + { + return format.fourcc(); + } +}; + +} /* namespace std */ diff --git a/include/libcamera/internal/v4l2_subdevice.h b/include/libcamera/internal/v4l2_subdevice.h index 6fda52ad..a1de0fb0 100644 --- a/include/libcamera/internal/v4l2_subdevice.h +++ b/include/libcamera/internal/v4l2_subdevice.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * v4l2_subdevice.h - V4L2 Subdevice + * V4L2 Subdevice */ #pragma once @@ -13,6 +13,8 @@ #include <string> #include <vector> +#include <linux/v4l2-subdev.h> + #include <libcamera/base/class.h> #include <libcamera/base/log.h> @@ -27,13 +29,43 @@ namespace libcamera { class MediaDevice; +class MediaBusFormatInfo +{ +public: + enum class Type { + Image, + Metadata, + EmbeddedData, + }; + + bool isValid() const { return code != 0; } + + static const MediaBusFormatInfo &info(uint32_t code); + + const char *name; + uint32_t code; + Type type; + unsigned int bitsPerPixel; + PixelFormatInfo::ColourEncoding colourEncoding; +}; + +struct V4L2SubdeviceCapability final : v4l2_subdev_capability { + bool isReadOnly() const + { + return capabilities & V4L2_SUBDEV_CAP_RO_SUBDEV; + } + bool hasStreams() const + { + return capabilities & V4L2_SUBDEV_CAP_STREAMS; + } +}; + struct V4L2SubdeviceFormat { - uint32_t mbus_code; + uint32_t code; Size size; std::optional<ColorSpace> colorSpace; const std::string toString() const; - uint8_t bitsPerPixel() const; }; std::ostream &operator<<(std::ostream &out, const V4L2SubdeviceFormat &f); @@ -44,10 +76,43 @@ public: using Formats = std::map<unsigned int, std::vector<SizeRange>>; enum Whence { - ActiveFormat, - TryFormat, + TryFormat = V4L2_SUBDEV_FORMAT_TRY, + ActiveFormat = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + + struct Stream { + Stream() + : pad(0), stream(0) + { + } + + Stream(unsigned int p, unsigned int s) + : pad(p), stream(s) + { + } + + unsigned int pad; + unsigned int stream; }; + struct Route { + Route() + : flags(0) + { + } + + Route(const Stream &snk, const Stream &src, uint32_t f) + : sink(snk), source(src), flags(f) + { + } + + Stream sink; + Stream source; + uint32_t flags; + }; + + using Routing = std::vector<Route>; + explicit V4L2Subdevice(const MediaEntity *entity); ~V4L2Subdevice(); @@ -55,19 +120,45 @@ public: const MediaEntity *entity() const { return entity_; } - int getSelection(unsigned int pad, unsigned int target, + int getSelection(const Stream &stream, unsigned int target, Rectangle *rect); - int setSelection(unsigned int pad, unsigned int target, + int getSelection(unsigned int pad, unsigned int target, Rectangle *rect) + { + return getSelection({ pad, 0 }, target, rect); + } + int setSelection(const Stream &stream, unsigned int target, Rectangle *rect); - - Formats formats(unsigned int pad); - + int setSelection(unsigned int pad, unsigned int target, Rectangle *rect) + { + return setSelection({ pad, 0 }, target, rect); + } + + Formats formats(const Stream &stream); + Formats formats(unsigned int pad) + { + return formats({ pad, 0 }); + } + + int getFormat(const Stream &stream, V4L2SubdeviceFormat *format, + Whence whence = ActiveFormat); int getFormat(unsigned int pad, V4L2SubdeviceFormat *format, + Whence whence = ActiveFormat) + { + return getFormat({ pad, 0 }, format, whence); + } + int setFormat(const Stream &stream, V4L2SubdeviceFormat *format, Whence whence = ActiveFormat); int setFormat(unsigned int pad, V4L2SubdeviceFormat *format, - Whence whence = ActiveFormat); + Whence whence = ActiveFormat) + { + return setFormat({ pad, 0 }, format, whence); + } + + int getRouting(Routing *routing, Whence whence = ActiveFormat); + int setRouting(Routing *routing, Whence whence = ActiveFormat); const std::string &model(); + const V4L2SubdeviceCapability &caps() const { return caps_; } static std::unique_ptr<V4L2Subdevice> fromEntityName(const MediaDevice *media, const std::string &entity); @@ -78,13 +169,28 @@ protected: private: LIBCAMERA_DISABLE_COPY(V4L2Subdevice) - std::vector<unsigned int> enumPadCodes(unsigned int pad); - std::vector<SizeRange> enumPadSizes(unsigned int pad, + std::optional<ColorSpace> + toColorSpace(const v4l2_mbus_framefmt &format) const; + + std::vector<unsigned int> enumPadCodes(const Stream &stream); + std::vector<SizeRange> enumPadSizes(const Stream &stream, unsigned int code); const MediaEntity *entity_; std::string model_; + struct V4L2SubdeviceCapability caps_; }; +bool operator==(const V4L2Subdevice::Stream &lhs, const V4L2Subdevice::Stream &rhs); +static inline bool operator!=(const V4L2Subdevice::Stream &lhs, + const V4L2Subdevice::Stream &rhs) +{ + return !(lhs == rhs); +} + +std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Stream &stream); +std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Route &route); +std::ostream &operator<<(std::ostream &out, const V4L2Subdevice::Routing &routing); + } /* namespace libcamera */ diff --git a/include/libcamera/internal/v4l2_videodevice.h b/include/libcamera/internal/v4l2_videodevice.h index 8525acbc..9057be08 100644 --- a/include/libcamera/internal/v4l2_videodevice.h +++ b/include/libcamera/internal/v4l2_videodevice.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * v4l2_videodevice.h - V4L2 Video Device + * V4L2 Video Device */ #pragma once @@ -14,6 +14,7 @@ #include <ostream> #include <stdint.h> #include <string> +#include <unordered_set> #include <vector> #include <linux/videodev2.h> @@ -228,6 +229,8 @@ public: static std::unique_ptr<V4L2VideoDevice> fromEntityName(const MediaDevice *media, const std::string &entity); + V4L2PixelFormat toV4L2PixelFormat(const PixelFormat &pixelFormat) const; + protected: std::string logPrefix() const override; @@ -240,6 +243,8 @@ private: Stopped, }; + int initFormats(); + int getFormatMeta(V4L2DeviceFormat *format); int trySetFormatMeta(V4L2DeviceFormat *format, bool set); @@ -263,9 +268,13 @@ private: void watchdogExpired(); + template<typename T> + static std::optional<ColorSpace> toColorSpace(const T &v4l2Format); + V4L2Capability caps_; V4L2DeviceFormat format_; const PixelFormatInfo *formatInfo_; + std::unordered_set<V4L2PixelFormat> pixelFormats_; enum v4l2_buf_type bufferType_; enum v4l2_memory memoryType_; diff --git a/include/libcamera/internal/yaml_parser.h b/include/libcamera/internal/yaml_parser.h index 064cf443..b6979d73 100644 --- a/include/libcamera/internal/yaml_parser.h +++ b/include/libcamera/internal/yaml_parser.h @@ -2,13 +2,14 @@ /* * Copyright (C) 2022, Google Inc. * - * yaml_parser.h - libcamera YAML parsing helper + * libcamera YAML parsing helper */ #pragma once #include <iterator> #include <map> +#include <optional> #include <string> #include <vector> @@ -24,12 +25,21 @@ class YamlParserContext; class YamlObject { private: - using DictContainer = std::map<std::string, std::unique_ptr<YamlObject>>; + struct Value { + Value(std::string &&k, std::unique_ptr<YamlObject> &&v) + : key(std::move(k)), value(std::move(v)) + { + } + std::string key; + std::unique_ptr<YamlObject> value; + }; + + using Container = std::vector<Value>; using ListContainer = std::vector<std::unique_ptr<YamlObject>>; public: #ifndef __DOXYGEN__ - template<typename Container, typename Derived> + template<typename Derived> class Iterator { public: @@ -65,10 +75,10 @@ public: } protected: - typename Container::const_iterator it_; + Container::const_iterator it_; }; - template<typename Container, typename Iterator> + template<typename Iterator> class Adapter { public: @@ -91,7 +101,7 @@ public: const Container &container_; }; - class ListIterator : public Iterator<ListContainer, ListIterator> + class ListIterator : public Iterator<ListIterator> { public: using value_type = const YamlObject &; @@ -100,16 +110,16 @@ public: value_type operator*() const { - return *it_->get(); + return *it_->value.get(); } pointer operator->() const { - return it_->get(); + return it_->value.get(); } }; - class DictIterator : public Iterator<DictContainer, DictIterator> + class DictIterator : public Iterator<DictIterator> { public: using value_type = std::pair<const std::string &, const YamlObject &>; @@ -118,17 +128,17 @@ public: value_type operator*() const { - return { it_->first, *it_->second.get() }; + return { it_->key, *it_->value.get() }; } }; - class DictAdapter : public Adapter<DictContainer, DictIterator> + class DictAdapter : public Adapter<DictIterator> { public: using key_type = std::string; }; - class ListAdapter : public Adapter<ListContainer, ListIterator> + class ListAdapter : public Adapter<ListIterator> { }; #endif /* __DOXYGEN__ */ @@ -153,9 +163,35 @@ public: #ifndef __DOXYGEN__ template<typename T, - typename std::enable_if_t< + std::enable_if_t< + std::is_same_v<bool, T> || + std::is_same_v<double, T> || + std::is_same_v<int8_t, T> || + std::is_same_v<uint8_t, T> || + std::is_same_v<int16_t, T> || + std::is_same_v<uint16_t, T> || + std::is_same_v<int32_t, T> || + std::is_same_v<uint32_t, T> || + std::is_same_v<std::string, T> || + std::is_same_v<Size, T>> * = nullptr> +#else + template<typename T> +#endif + std::optional<T> get() const; + + template<typename T> + T get(const T &defaultValue) const + { + return get<T>().value_or(defaultValue); + } + +#ifndef __DOXYGEN__ + template<typename T, + std::enable_if_t< std::is_same_v<bool, T> || std::is_same_v<double, T> || + std::is_same_v<int8_t, T> || + std::is_same_v<uint8_t, T> || std::is_same_v<int16_t, T> || std::is_same_v<uint16_t, T> || std::is_same_v<int32_t, T> || @@ -165,9 +201,9 @@ public: #else template<typename T> #endif - T get(const T &defaultValue, bool *ok = nullptr) const; + std::optional<std::vector<T>> getList() const; - DictAdapter asDict() const { return DictAdapter{ dictionary_ }; } + DictAdapter asDict() const { return DictAdapter{ list_ }; } ListAdapter asList() const { return ListAdapter{ list_ }; } const YamlObject &operator[](std::size_t index) const; @@ -189,8 +225,8 @@ private: Type type_; std::string value_; - ListContainer list_; - DictContainer dictionary_; + Container list_; + std::map<std::string, YamlObject *> dictionary_; }; class YamlParser final diff --git a/include/libcamera/ipa/core.mojom b/include/libcamera/ipa/core.mojom index 74f3339e..bce79724 100644 --- a/include/libcamera/ipa/core.mojom +++ b/include/libcamera/ipa/core.mojom @@ -14,8 +14,8 @@ module libcamera; * - structs * * Attributes: - * - skipHeader - structs only, and only in core.mojom - * - Do not generate a C++ definition for the structure + * - skipHeader - allowed only for structs and enums in core.mojom + * - Do not generate a C++ definition for the structure or enum * - Any type used in a mojom interface definition must have a corresponding * definition in a mojom file for the code generator to accept it, except * for types solely used as map/array members for which a definition is not @@ -33,6 +33,15 @@ module libcamera; * available for the type and there's no need to generate one * - hasFd - struct fields or empty structs only * - Designate that this field or empty struct contains a SharedFD + * - scopedEnum - enum definitions + * - Designate that this enum should be an enum class, as opposed to a pure + * enum + * - flags - struct fields or function parameters that are enums + * - Designate that this enum type E should be Flags<E> in the generated C++ + * code + * - For example, if a struct field is defined as `[flags] ErrorFlag f;` + * (where ErrorFlag is defined as an enum elsewhere in mojom), then the + * generated code for this field will be `Flags<ErrorFlag> f` * * Rules: * - If the type is defined in a libcamera C++ header *and* a (de)serializer is @@ -43,6 +52,8 @@ module libcamera; * then the type definition in the core.mojom file should have the * [skipHeader] attribute only * - A (de)serializer will be generated for the type + * - enums that are defined in a libcamera C++ header also fall in this + * category * - If a type definition has [skipHeader], then the header where the type is * defined must be included in ipa_interface.h * - Types that are solely used as array/map members do not require a mojom @@ -130,6 +141,18 @@ module libcamera; */ /** + * \var IPACameraSensorInfo::cfaPattern + * \brief The arrangement of colour filters on the image sensor + * + * This takes a value defined by properties::draft::ColorFilterArrangementEnum. + * For non-Bayer colour sensors, the cfaPattern will be set to + * properties::draft::ColorFilterArrangementEnum::RGB. + * + * \todo Make this variable optional once mojom supports it, instead of using + * RGB for sensors that don't have a CFA. + */ + +/** * \var IPACameraSensorInfo::activeAreaSize * \brief The size of the pixel array active area of the sensor */ @@ -172,10 +195,17 @@ module libcamera; */ /** - * \var IPACameraSensorInfo::lineLength - * \brief Total line length in pixels + * \var IPACameraSensorInfo::minLineLength + * \brief The minimum line length in pixels * - * The total line length in pixel clock periods, including blanking. + * The minimum allowable line length in pixel clock periods, including blanking. + */ + +/** + * \var IPACameraSensorInfo::maxLineLength + * \brief The maximum line length in pixels + * + * The maximum allowable line length in pixel clock periods, including blanking. */ /** @@ -189,7 +219,7 @@ module libcamera; * To obtain the minimum frame duration: * * \verbatim - frameDuration(s) = minFrameLength(lines) * lineLength(pixels) / pixelRate(pixels per second) + frameDuration(s) = minFrameLength(lines) * minLineLength(pixels) / pixelRate(pixels per second) \endverbatim */ @@ -204,20 +234,23 @@ module libcamera; * To obtain the maximum frame duration: * * \verbatim - frameDuration(s) = maxFrameLength(lines) * lineLength(pixels) / pixelRate(pixels per second) + frameDuration(s) = maxFrameLength(lines) * maxLineLength(pixels) / pixelRate(pixels per second) \endverbatim */ struct IPACameraSensorInfo { string model; uint32 bitsPerPixel; + uint32 cfaPattern; Size activeAreaSize; Rectangle analogCrop; Size outputSize; uint64 pixelRate; - uint32 lineLength; + + uint32 minLineLength; + uint32 maxLineLength; uint32 minFrameLength; uint32 maxFrameLength; diff --git a/include/libcamera/ipa/ipa_controls.h b/include/libcamera/ipa/ipa_controls.h index e5da1946..5fd13394 100644 --- a/include/libcamera/ipa/ipa_controls.h +++ b/include/libcamera/ipa/ipa_controls.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * ipa_controls.h - IPA Control handling + * IPA Control handling */ #pragma once diff --git a/include/libcamera/ipa/ipa_interface.h b/include/libcamera/ipa/ipa_interface.h index 50ca0e7b..b93f1a15 100644 --- a/include/libcamera/ipa/ipa_interface.h +++ b/include/libcamera/ipa/ipa_interface.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * ipa_interface.h - Image Processing Algorithm interface + * Image Processing Algorithm interface */ #pragma once @@ -13,6 +13,7 @@ #include <map> #include <vector> +#include <libcamera/base/flags.h> #include <libcamera/base/signal.h> #include <libcamera/controls.h> @@ -22,8 +23,8 @@ namespace libcamera { /* - * Structs that are defined in core.mojom and have the skipHeader tag must be - * #included here. + * Structs and enums that are defined in core.mojom that have the skipHeader + * tag must be #included here. */ class IPAInterface diff --git a/include/libcamera/ipa/ipa_module_info.h b/include/libcamera/ipa/ipa_module_info.h index b19b00f7..3507a6d7 100644 --- a/include/libcamera/ipa/ipa_module_info.h +++ b/include/libcamera/ipa/ipa_module_info.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * ipa_module_info.h - Image Processing Algorithm module information + * Image Processing Algorithm module information */ #pragma once diff --git a/include/libcamera/ipa/meson.build b/include/libcamera/ipa/meson.build index 442ca3dd..3352d08f 100644 --- a/include/libcamera/ipa/meson.build +++ b/include/libcamera/ipa/meson.build @@ -9,7 +9,7 @@ libcamera_ipa_headers = files([ ]) install_headers(libcamera_ipa_headers, - subdir: libcamera_ipa_include_dir) + subdir : libcamera_ipa_include_dir) libcamera_generated_ipa_headers = [] @@ -60,14 +60,14 @@ libcamera_generated_ipa_headers += custom_target('core_ipa_serializer_h', './' +'@INPUT@' ]) -ipa_mojom_files = [ - 'ipu3.mojom', - 'raspberrypi.mojom', - 'rkisp1.mojom', - 'vimc.mojom', -] - -ipa_mojoms = [] +# Mapping from pipeline handler name to mojom file +pipeline_ipa_mojom_mapping = { + 'ipu3': 'ipu3.mojom', + 'rkisp1': 'rkisp1.mojom', + 'rpi/vc4': 'raspberrypi.mojom', + 'simple': 'soft.mojom', + 'vimc': 'vimc.mojom', +} # # Generate headers from templates. @@ -75,14 +75,23 @@ ipa_mojoms = [] # TODO Define per-pipeline ControlInfoMap with yaml? -foreach file : ipa_mojom_files +ipa_mojoms = [] +mojoms_built = [] +foreach pipeline, file : pipeline_ipa_mojom_mapping name = file.split('.')[0] - if name not in pipelines + # Avoid building duplicate mojom interfaces with the same interface file + if name in mojoms_built continue endif - # {pipeline}.mojom-module + if pipeline not in pipelines + continue + endif + + mojoms_built += name + + # {interface}.mojom-module mojom = custom_target(name + '_mojom_module', input : file, output : file + '-module', @@ -94,7 +103,7 @@ foreach file : ipa_mojom_files '--mojoms', '@INPUT@' ]) - # {pipeline}_ipa_interface.h + # {interface}_ipa_interface.h header = custom_target(name + '_ipa_interface_h', input : mojom, output : name + '_ipa_interface.h', @@ -110,7 +119,7 @@ foreach file : ipa_mojom_files './' +'@INPUT@' ]) - # {pipeline}_ipa_serializer.h + # {interface}_ipa_serializer.h serializer = custom_target(name + '_ipa_serializer_h', input : mojom, output : name + '_ipa_serializer.h', @@ -124,7 +133,7 @@ foreach file : ipa_mojom_files './' +'@INPUT@' ]) - # {pipeline}_ipa_proxy.h + # {interface}_ipa_proxy.h proxy_header = custom_target(name + '_proxy_h', input : mojom, output : name + '_ipa_proxy.h', @@ -146,6 +155,12 @@ foreach file : ipa_mojom_files libcamera_generated_ipa_headers += [header, serializer, proxy_header] endforeach +ipa_mojom_files = [] +foreach pipeline, file : pipeline_ipa_mojom_mapping + if file not in ipa_mojom_files + ipa_mojom_files += file + endif +endforeach ipa_mojom_files = files(ipa_mojom_files) # Pass this to the documentation generator in src/libcamera/ipa diff --git a/include/libcamera/ipa/raspberrypi.mojom b/include/libcamera/ipa/raspberrypi.mojom index c0de435b..5986c436 100644 --- a/include/libcamera/ipa/raspberrypi.mojom +++ b/include/libcamera/ipa/raspberrypi.mojom @@ -8,82 +8,139 @@ module ipa.RPi; import "include/libcamera/ipa/core.mojom"; -enum BufferMask { - MaskID = 0x00ffff, - MaskStats = 0x010000, - MaskEmbeddedData = 0x020000, - MaskBayerData = 0x040000, - MaskExternalBuffer = 0x100000, -}; - -/* Size of the LS grid allocation. */ +/* Size of the LS grid allocation on VC4. */ const uint32 MaxLsGridSize = 0x8000; struct SensorConfig { uint32 gainDelay; uint32 exposureDelay; uint32 vblankDelay; + uint32 hblankDelay; uint32 sensorMetadata; }; -struct IPAInitResult { +struct InitParams { + bool lensPresent; + libcamera.IPACameraSensorInfo sensorInfo; + /* PISP specific */ + libcamera.SharedFD fe; + libcamera.SharedFD be; +}; + +struct InitResult { SensorConfig sensorConfig; libcamera.ControlInfoMap controlInfo; }; -struct ISPConfig { - uint32 embeddedBufferId; - uint32 bayerBufferId; - bool embeddedBufferPresent; - libcamera.ControlList controls; +struct BufferIds { + uint32 bayer; + uint32 embedded; + uint32 stats; }; -struct IPAConfig { +struct ConfigParams { uint32 transform; + libcamera.ControlInfoMap sensorControls; + libcamera.ControlInfoMap ispControls; + libcamera.ControlInfoMap lensControls; + /* VC4 specific */ libcamera.SharedFD lsTableHandle; }; -struct IPAConfigResult { - float modeSensitivity; - libcamera.ControlInfoMap controlInfo; +struct ConfigResult { + float modeSensitivity; + libcamera.ControlInfoMap controlInfo; + libcamera.ControlList sensorControls; + libcamera.ControlList lensControls; }; -struct StartConfig { +struct StartResult { libcamera.ControlList controls; int32 dropFrameCount; - uint32 maxSensorFrameLengthMs; +}; + +struct PrepareParams { + BufferIds buffers; + libcamera.ControlList sensorControls; + libcamera.ControlList requestControls; + uint32 ipaContext; + uint32 delayContext; +}; + +struct ProcessParams { + BufferIds buffers; + uint32 ipaContext; }; interface IPARPiInterface { - init(libcamera.IPASettings settings) - => (int32 ret, IPAInitResult result); - start(libcamera.ControlList controls) => (StartConfig startConfig); + /** + * \fn init() + * \brief Initialise the IPA + * \param[in] settings Camera sensor information and configuration file + * \param[in] params Platform specific initialisation parameters + * \param[out] ret 0 on success or a negative error code otherwise + * \param[out] result Static sensor configuration and controls available + * + * This function initialises the IPA for a particular sensor from the + * pipeline handler. + * + * The \a settings conveys information about the camera sensor and + * configuration file requested by the pipeline handler. + * + * The \a result parameter returns the sensor delay for the given camera + * as well as a ControlInfoMap of available controls that can be handled + * by the IPA. + */ + init(libcamera.IPASettings settings, InitParams params) + => (int32 ret, InitResult result); + + /** + * \fn start() + * \brief Start the IPA + * \param[in] controls List of control to handle + * \param[out] result Controls to apply and number of dropped frames + * + * This function sets the IPA to a started state. + * + * The \a controls provide a list of controls to handle immediately. The + * actual controls to apply on the sensor and ISP in the pipeline + * handler are returned in \a result. + * + * The number of convergence frames to be dropped is also returned in + * \a result. + */ + start(libcamera.ControlList controls) => (StartResult result); + + /** + * \fn start() + * \brief Stop the IPA + * + * This function sets the IPA to a stopped state. + */ stop(); /** * \fn configure() - * \brief Configure the IPA stream and sensor settings - * \param[in] sensorInfo Camera sensor information - * \param[in] streamConfig Configuration of all active streams - * \param[in] entityControls Controls provided by the pipeline entities - * \param[in] ipaConfig Pipeline-handler-specific configuration data - * \param[out] controls Controls to apply by the pipeline entity - * \param[out] result Other results that the pipeline handler may require - * - * This function shall be called when the camera is configured to inform - * the IPA of the camera's streams and the sensor settings. - * - * The \a sensorInfo conveys information about the camera sensor settings that - * the pipeline handler has selected for the configuration. - * - * The \a ipaConfig and \a controls parameters carry data passed by the - * pipeline handler to the IPA and back. + * \brief Configure the IPA + * \param[in] sensorInfo Sensor mode configuration + * \param[in] params Platform configuration parameters + * \param[out] ret 0 on success or a negative error code otherwise + * \param[out] result Results of the configuration operation + * + * This function configures the IPA for a particular camera + * configuration + * + * The \a params parameter provides a list of available controls for the + * ISP, sensor and lens devices, and the user requested transform + * operation. It can also provide platform specific configuration + * parameters, e.g. the lens shading table memory handle for VC4. + * + * The \a result parameter returns the available controls for the given + * camera mode, a list of controls to apply to the sensor device, and + * the requested mode's sensitivity characteristics. */ - configure(libcamera.IPACameraSensorInfo sensorInfo, - map<uint32, libcamera.IPAStream> streamConfig, - map<uint32, libcamera.ControlInfoMap> entityControls, - IPAConfig ipaConfig) - => (int32 ret, libcamera.ControlList controls, IPAConfigResult result); + configure(libcamera.IPACameraSensorInfo sensorInfo, ConfigParams params) + => (int32 ret, ConfigResult result); /** * \fn mapBuffers() @@ -106,7 +163,7 @@ interface IPARPiInterface { * depending on the IPA protocol. Regardless of the protocol, all * buffers mapped at a given time shall have unique numerical IDs. * - * The numerical IDs have no meaning defined by the IPA interface, and + * The numerical IDs have no meaning defined by the IPA interface, and * should be treated as opaque handles by IPAs, with the only exception * that ID zero is invalid. * @@ -126,15 +183,119 @@ interface IPARPiInterface { */ unmapBuffers(array<uint32> ids); - [async] signalStatReady(uint32 bufferId); - [async] signalQueueRequest(libcamera.ControlList controls); - [async] signalIspPrepare(ISPConfig data); + /** + * \fn prepareIsp() + * \brief Prepare the ISP configuration for a frame + * \param[in] params Parameter set for the frame to process + * + * This function call into all the algorithms in preparation for the + * frame to be processed by the ISP. + * + * The \a params parameter lists the buffer IDs for the Bayer and + * embedded data buffers, a ControlList of sensor frame params, and + * a ControlList of request controls for the current frame. + * + * Additionally, \a params also contains the IPA context (ipaContext) to + * use as an index location to store control algorithm results, and a + * historical IPA context (delayContext) that was active when the sensor + * settings were requested by the IPA. + */ + [async] prepareIsp(PrepareParams params); + + /** + * \fn processStats() + * \brief Process the statistics provided by the ISP + * \param[in] params Parameter set for the statistics to process + * + * This function call into all the algorithms to provide the statistics + * generated by the ISP for the processed frame. + * + * The \a params parameter lists the buffer ID for the statistics buffer + * and an IPA context (ipaContext) to use as an index location to store + * algorithm results. + */ + [async] processStats(ProcessParams params); }; interface IPARPiEventInterface { - statsMetadataComplete(uint32 bufferId, libcamera.ControlList controls); - runIsp(uint32 bufferId); - embeddedComplete(uint32 bufferId); + /** + * \fn prepareIspComplete() + * \brief Signal completion of \a prepareIsp + * \param[in] buffers Bayer and embedded buffers actioned. + * \param[in] stitchSwapBuffers Whether the stitch block buffers need to be swapped. + * + * This asynchronous event is signalled to the pipeline handler once + * the \a prepareIsp signal has completed, and the ISP is ready to start + * processing the frame. The embedded data buffer may be recycled after + * this event. + */ + prepareIspComplete(BufferIds buffers, bool stitchSwapBuffers); + + /** + * \fn processStatsComplete() + * \brief Signal completion of \a processStats + * \param[in] buffers Statistics buffers actioned. + * + * This asynchronous event is signalled to the pipeline handler once + * the \a processStats signal has completed. The statistics buffer may + * be recycled after this event. + */ + processStatsComplete(BufferIds buffers); + + /** + * \fn metadataReady() + * \brief Signal request metadata is to be merged + * \param[in] metadata Control list of metadata to be merged + * + * This asynchronous event is signalled to the pipeline handler once + * all the frame metadata has been gathered. The pipeline handler will + * copy or merge this metadata into the \a Request returned back to the + * application. + */ + metadataReady(libcamera.ControlList metadata); + + /** + * \fn setIspControls() + * \brief Signal ISP controls to be applied. + * \param[in] controls List of controls to be applied. + * + * This asynchronous event is signalled to the pipeline handler during + * the \a prepareISP signal after all algorithms have been run and the + * IPA requires ISP controls to be applied for the frame. + */ setIspControls(libcamera.ControlList controls); - setDelayedControls(libcamera.ControlList controls); + + /** + * \fn setDelayedControls() + * \brief Signal Sensor controls to be applied. + * \param[in] controls List of controls to be applied. + * \param[in] delayContext IPA context index used for this request + * + * This asynchronous event is signalled to the pipeline handler when + * the IPA requires sensor specific controls (e.g. shutter speed, gain, + * blanking) to be applied. + */ + setDelayedControls(libcamera.ControlList controls, uint32 delayContext); + + /** + * \fn setLensControls() + * \brief Signal lens controls to be applied. + * \param[in] controls List of controls to be applied. + * + * This asynchronous event is signalled to the pipeline handler when + * the IPA requires a lens movement control to be applied. + */ + setLensControls(libcamera.ControlList controls); + + /** + * \fn setCameraTimeout() + * \brief Request a watchdog timeout value to use + * \param[in] maxFrameLengthMs Timeout value in ms + * + * This asynchronous event is used by the IPA to inform the pipeline + * handler of an acceptable watchdog timer value to use for the sensor + * stream. This value is based on the history of frame lengths requested + * by the IPA. + */ + setCameraTimeout(uint32 maxFrameLengthMs); }; diff --git a/include/libcamera/ipa/rkisp1.mojom b/include/libcamera/ipa/rkisp1.mojom index e3537385..1009e970 100644 --- a/include/libcamera/ipa/rkisp1.mojom +++ b/include/libcamera/ipa/rkisp1.mojom @@ -8,17 +8,23 @@ module ipa.rkisp1; import "include/libcamera/ipa/core.mojom"; +struct IPAConfigInfo { + libcamera.IPACameraSensorInfo sensorInfo; + libcamera.ControlInfoMap sensorControls; +}; + interface IPARkISP1Interface { init(libcamera.IPASettings settings, - uint32 hwRevision) - => (int32 ret); + uint32 hwRevision, + libcamera.IPACameraSensorInfo sensorInfo, + libcamera.ControlInfoMap sensorControls) + => (int32 ret, libcamera.ControlInfoMap ipaControls); start() => (int32 ret); stop(); - configure(libcamera.IPACameraSensorInfo sensorInfo, - map<uint32, libcamera.IPAStream> streamConfig, - map<uint32, libcamera.ControlInfoMap> entityControls) - => (int32 ret); + configure(IPAConfigInfo configInfo, + map<uint32, libcamera.IPAStream> streamConfig) + => (int32 ret, libcamera.ControlInfoMap ipaControls); mapBuffers(array<libcamera.IPABuffer> buffers); unmapBuffers(array<uint32> ids); diff --git a/include/libcamera/ipa/soft.mojom b/include/libcamera/ipa/soft.mojom new file mode 100644 index 00000000..3aa2066e --- /dev/null +++ b/include/libcamera/ipa/soft.mojom @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +/* + * \todo Document the interface and remove the related EXCLUDE_PATTERNS entry. + */ + +module ipa.soft; + +import "include/libcamera/ipa/core.mojom"; + +interface IPASoftInterface { + init(libcamera.IPASettings settings, + libcamera.SharedFD fdStats, + libcamera.SharedFD fdParams, + libcamera.ControlInfoMap sensorCtrlInfoMap) + => (int32 ret); + start() => (int32 ret); + stop(); + configure(libcamera.ControlInfoMap sensorCtrlInfoMap) + => (int32 ret); + + [async] processStats(libcamera.ControlList sensorControls); +}; + +interface IPASoftEventInterface { + setSensorControls(libcamera.ControlList sensorControls); + setIspParams(); +}; diff --git a/include/libcamera/ipa/vimc.mojom b/include/libcamera/ipa/vimc.mojom index 718b9674..dd991f7e 100644 --- a/include/libcamera/ipa/vimc.mojom +++ b/include/libcamera/ipa/vimc.mojom @@ -17,8 +17,18 @@ enum IPAOperationCode { IPAOperationStop, }; +[scopedEnum] enum TestFlag { + Flag1 = 0x1, + Flag2 = 0x2, + Flag3 = 0x4, + Flag4 = 0x8, +}; + interface IPAVimcInterface { - init(libcamera.IPASettings settings) => (int32 ret); + init(libcamera.IPASettings settings, + IPAOperationCode code, + [flags] TestFlag inFlags) + => (int32 ret, [flags] TestFlag outFlags); configure(libcamera.IPACameraSensorInfo sensorInfo, map<uint32, libcamera.IPAStream> streamConfig, @@ -41,5 +51,5 @@ interface IPAVimcInterface { }; interface IPAVimcEventInterface { - paramsBufferReady(uint32 bufferId); + paramsBufferReady(uint32 bufferId, [flags] TestFlag flags); }; diff --git a/include/libcamera/logging.h b/include/libcamera/logging.h index cd842f67..e334d87b 100644 --- a/include/libcamera/logging.h +++ b/include/libcamera/logging.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * logging.h - Logging infrastructure + * Logging infrastructure */ #pragma once diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build index 408b7acf..84c6c4cb 100644 --- a/include/libcamera/meson.build +++ b/include/libcamera/meson.build @@ -12,6 +12,7 @@ libcamera_public_headers = files([ 'framebuffer_allocator.h', 'geometry.h', 'logging.h', + 'orientation.h', 'pixel_format.h', 'request.h', 'stream.h', @@ -31,20 +32,58 @@ install_headers(libcamera_public_headers, libcamera_headers_install_dir = get_option('includedir') / libcamera_include_dir -# control_ids.h and property_ids.h -control_source_files = [ - 'control_ids', - 'property_ids', -] +controls_map = { + 'controls': { + 'draft': 'control_ids_draft.yaml', + 'core': 'control_ids_core.yaml', + 'rpi/vc4': 'control_ids_rpi.yaml', + }, + + 'properties': { + 'draft': 'property_ids_draft.yaml', + 'core': 'property_ids_core.yaml', + } +} control_headers = [] +controls_files = [] +properties_files = [] + +foreach mode, entry : controls_map + files_list = [] + input_files = [] + foreach vendor, header : entry + if vendor != 'core' and vendor != 'draft' + if vendor not in pipelines + continue + endif + endif + + if header in files_list + continue + endif + + files_list += header + input_files += files('../../src/libcamera/' + header) + endforeach + + outfile = '' + if mode == 'controls' + outfile = 'control_ids.h' + controls_files += files_list + else + outfile = 'property_ids.h' + properties_files += files_list + endif -foreach header : control_source_files - input_files = files('../../src/libcamera/' + header +'.yaml', header + '.h.in') + template_file = files(outfile + '.in') + ranges_file = files('../../src/libcamera/control_ranges.yaml') control_headers += custom_target(header + '_h', input : input_files, - output : header + '.h', - command : [gen_controls, '-o', '@OUTPUT@', '@INPUT@'], + output : outfile, + command : [gen_controls, '-o', '@OUTPUT@', + '--mode', mode, '-t', template_file, + '-r', ranges_file, '@INPUT@'], install : true, install_dir : libcamera_headers_install_dir) endforeach diff --git a/include/libcamera/orientation.h b/include/libcamera/orientation.h new file mode 100644 index 00000000..a3b40e63 --- /dev/null +++ b/include/libcamera/orientation.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Ideas On Board Oy + * + * Image orientation + */ + +#pragma once + +#include <iostream> + +namespace libcamera { + +enum class Orientation { + /* EXIF tag 274 starts from '1' */ + Rotate0 = 1, + Rotate0Mirror, + Rotate180, + Rotate180Mirror, + Rotate90Mirror, + Rotate270, + Rotate270Mirror, + Rotate90, +}; + +Orientation orientationFromRotation(int angle, bool *success = nullptr); + +std::ostream &operator<<(std::ostream &out, const Orientation &orientation); + +} /* namespace libcamera */ diff --git a/include/libcamera/pixel_format.h b/include/libcamera/pixel_format.h index d49c5f78..ea60fe72 100644 --- a/include/libcamera/pixel_format.h +++ b/include/libcamera/pixel_format.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * pixel_format.h - libcamera Pixel Format + * libcamera Pixel Format */ #pragma once diff --git a/include/libcamera/property_ids.h.in b/include/libcamera/property_ids.h.in index ff019408..e6edabca 100644 --- a/include/libcamera/property_ids.h.in +++ b/include/libcamera/property_ids.h.in @@ -2,14 +2,16 @@ /* * Copyright (C) 2019, Google Inc. * - * property_ids.h - Property ID list + * Property ID list * * This file is auto-generated. Do not edit. */ #pragma once +#include <map> #include <stdint.h> +#include <string> #include <libcamera/controls.h> @@ -23,14 +25,10 @@ ${ids} ${controls} -namespace draft { - -${draft_controls} - -} /* namespace draft */ - extern const ControlIdMap properties; +${vendor_controls} + } /* namespace properties */ } /* namespace libcamera */ diff --git a/include/libcamera/request.h b/include/libcamera/request.h index dffde153..2c78d9bb 100644 --- a/include/libcamera/request.h +++ b/include/libcamera/request.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * request.h - Capture request handling + * Capture request handling */ #pragma once diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h index f0ae7e62..d510238a 100644 --- a/include/libcamera/stream.h +++ b/include/libcamera/stream.h @@ -2,13 +2,14 @@ /* * Copyright (C) 2019, Google Inc. * - * stream.h - Video stream for a Camera + * Video stream for a Camera */ #pragma once #include <map> #include <memory> +#include <ostream> #include <string> #include <vector> @@ -61,14 +62,14 @@ private: StreamFormats formats_; }; -enum StreamRole { +enum class StreamRole { Raw, StillCapture, VideoRecording, Viewfinder, }; -using StreamRoles = std::vector<StreamRole>; +std::ostream &operator<<(std::ostream &out, StreamRole role); class Stream { diff --git a/include/libcamera/transform.h b/include/libcamera/transform.h index 2e76b940..a88f809e 100644 --- a/include/libcamera/transform.h +++ b/include/libcamera/transform.h @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* - * Copyright (C) 2020, Raspberry Pi (Trading) Limited + * Copyright (C) 2020, Raspberry Pi Ltd * - * transform.h - 2D plane transforms + * 2D plane transforms */ #pragma once @@ -11,6 +11,8 @@ namespace libcamera { +enum class Orientation; + enum class Transform : int { Identity = 0, Rot0 = Identity, @@ -70,6 +72,9 @@ constexpr Transform operator~(Transform t) Transform transformFromRotation(int angle, bool *success = nullptr); +Transform operator/(const Orientation &o1, const Orientation &o2); +Orientation operator*(const Orientation &o, const Transform &t); + const char *transformToString(Transform t); } /* namespace libcamera */ diff --git a/include/libcamera/version.h.in b/include/libcamera/version.h.in index 6e24d0a8..50bf1001 100644 --- a/include/libcamera/version.h.in +++ b/include/libcamera/version.h.in @@ -2,7 +2,7 @@ /* * Copyright (C) 2019, Google Inc. * - * version.h - Library version information + * Library version information * * This file is auto-generated. Do not edit. */ |