diff options
author | Naushir Patuck <naush@raspberrypi.com> | 2023-05-03 13:20:27 +0100 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2023-05-04 20:47:40 +0300 |
commit | 726e9274ea95fa46352556d340c5793a8da51fcd (patch) | |
tree | 80f6adcdbf744f9317e09eff3e80c602b384a753 /src/libcamera/pipeline/rpi/common/rpi_stream.h | |
parent | 46aefed208fef4bc8d6f6e8882b92b9af710a60b (diff) |
pipeline: ipa: raspberrypi: Refactor and move the Raspberry Pi code
Split the Raspberry Pi pipeline handler and IPA source code into common
and VC4/BCM2835 specific file structures.
For the pipeline handler, the common code files now live in
src/libcamera/pipeline/rpi/common/
and the VC4-specific files in src/libcamera/pipeline/rpi/vc4/.
For the IPA, the common code files now live in
src/ipa/rpi/{cam_helper,controller}/
and the vc4 specific files in src/ipa/rpi/vc4/. With this change, the
camera tuning files are now installed under share/libcamera/ipa/rpi/vc4/.
To build the pipeline and IPA, the meson configuration options have now
changed from "raspberrypi" to "rpi/vc4":
meson setup build -Dipas=rpi/vc4 -Dpipelines=rpi/vc4
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/libcamera/pipeline/rpi/common/rpi_stream.h')
-rw-r--r-- | src/libcamera/pipeline/rpi/common/rpi_stream.h | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/src/libcamera/pipeline/rpi/common/rpi_stream.h b/src/libcamera/pipeline/rpi/common/rpi_stream.h new file mode 100644 index 00000000..b8bd79cf --- /dev/null +++ b/src/libcamera/pipeline/rpi/common/rpi_stream.h @@ -0,0 +1,185 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Raspberry Pi Ltd + * + * rpi_stream.h - Raspberry Pi device stream abstraction class. + */ + +#pragma once + +#include <queue> +#include <string> +#include <unordered_map> +#include <vector> + +#include <libcamera/stream.h> + +#include "libcamera/internal/v4l2_videodevice.h" + +namespace libcamera { + +namespace RPi { + +using BufferMap = std::unordered_map<unsigned int, FrameBuffer *>; + +enum BufferMask { + MaskID = 0x00ffff, + MaskStats = 0x010000, + MaskEmbeddedData = 0x020000, + MaskBayerData = 0x040000, + MaskExternalBuffer = 0x100000, +}; + +/* + * Device stream abstraction for either an internal or external stream. + * Used for both Unicam and the ISP. + */ +class Stream : public libcamera::Stream +{ +public: + Stream() + : id_(BufferMask::MaskID) + { + } + + Stream(const char *name, MediaEntity *dev, bool importOnly = false) + : external_(false), importOnly_(importOnly), name_(name), + dev_(std::make_unique<V4L2VideoDevice>(dev)), id_(BufferMask::MaskID) + { + } + + V4L2VideoDevice *dev() const; + std::string name() const; + bool isImporter() const; + void resetBuffers(); + + void setExternal(bool external); + bool isExternal() const; + + void setExportedBuffers(std::vector<std::unique_ptr<FrameBuffer>> *buffers); + const BufferMap &getBuffers() const; + int getBufferId(FrameBuffer *buffer) const; + + void setExternalBuffer(FrameBuffer *buffer); + void removeExternalBuffer(FrameBuffer *buffer); + + int prepareBuffers(unsigned int count); + int queueBuffer(FrameBuffer *buffer); + void returnBuffer(FrameBuffer *buffer); + + int queueAllBuffers(); + void releaseBuffers(); + +private: + class IdGenerator + { + public: + IdGenerator(int max) + : max_(max), id_(0) + { + } + + int get() + { + int id; + if (!recycle_.empty()) { + id = recycle_.front(); + recycle_.pop(); + } else { + id = id_++; + ASSERT(id_ <= max_); + } + return id; + } + + void release(int id) + { + recycle_.push(id); + } + + void reset() + { + id_ = 0; + recycle_ = {}; + } + + private: + int max_; + int id_; + std::queue<int> recycle_; + }; + + void clearBuffers(); + int queueToDevice(FrameBuffer *buffer); + + /* + * Indicates that this stream is active externally, i.e. the buffers + * might be provided by (and returned to) the application. + */ + bool external_; + + /* Indicates that this stream only imports buffers, e.g. ISP input. */ + bool importOnly_; + + /* Stream name identifier. */ + std::string name_; + + /* The actual device stream. */ + std::unique_ptr<V4L2VideoDevice> dev_; + + /* Tracks a unique id key for the bufferMap_ */ + IdGenerator id_; + + /* All frame buffers associated with this device stream. */ + BufferMap bufferMap_; + + /* + * List of frame buffers that we can use if none have been provided by + * the application for external streams. This is populated by the + * buffers exported internally. + */ + std::queue<FrameBuffer *> availableBuffers_; + + /* + * List of frame buffers that are to be queued into the device from a Request. + * A nullptr indicates any internal buffer can be used (from availableBuffers_), + * whereas a valid pointer indicates an external buffer to be queued. + * + * Ordering buffers to be queued is important here as it must match the + * requests coming from the application. + */ + std::queue<FrameBuffer *> requestBuffers_; + + /* + * This is a list of buffers exported internally. Need to keep this around + * as the stream needs to maintain ownership of these buffers. + */ + std::vector<std::unique_ptr<FrameBuffer>> internalBuffers_; +}; + +/* + * The following class is just a convenient (and typesafe) array of device + * streams indexed with an enum class. + */ +template<typename E, std::size_t N> +class Device : public std::array<class Stream, N> +{ +private: + constexpr auto index(E e) const noexcept + { + return static_cast<std::underlying_type_t<E>>(e); + } +public: + Stream &operator[](E e) + { + return std::array<class Stream, N>::operator[](index(e)); + } + const Stream &operator[](E e) const + { + return std::array<class Stream, N>::operator[](index(e)); + } +}; + +} /* namespace RPi */ + +} /* namespace libcamera */ |