/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * Copyright (C) 2020, Laurent Pinchart * Copyright 2022 NXP * * Generic format converter interface */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include "libcamera/internal/v4l2_request.h" namespace libcamera { class FrameBuffer; class MediaDevice; class PixelFormat; class Stream; struct StreamConfiguration; class Converter { public: enum class Feature { None = 0, InputCrop = (1 << 0), }; using Features = Flags; enum class Alignment { Down = 0, Up, }; Converter(std::shared_ptr media, Features features = Feature::None); virtual ~Converter(); virtual int loadConfiguration(const std::string &filename) = 0; virtual bool isValid() const = 0; virtual std::vector formats(PixelFormat input) = 0; virtual SizeRange sizes(const Size &input) = 0; virtual Size adjustInputSize(const PixelFormat &pixFmt, const Size &size, Alignment align = Alignment::Down) = 0; virtual Size adjustOutputSize(const PixelFormat &pixFmt, const Size &size, Alignment align = Alignment::Down) = 0; virtual std::tuple strideAndFrameSize(const PixelFormat &pixelFormat, const Size &size) = 0; virtual int validateOutput(StreamConfiguration *cfg, bool *adjusted, Alignment align = Alignment::Down) = 0; virtual int configure(const StreamConfiguration &inputCfg, const std::vector> &outputCfgs) = 0; virtual bool isConfigured(const Stream *stream) const = 0; virtual int exportBuffers(const Stream *stream, unsigned int count, std::vector> *buffers) = 0; virtual int start() = 0; virtual void stop() = 0; virtual int queueBuffers(FrameBuffer *input, const std::map &outputs, const V4L2Request *request = nullptr) = 0; virtual int setInputCrop(const Stream *stream, Rectangle *rect) = 0; virtual std::pair inputCropBounds() = 0; virtual std::pair inputCropBounds(const Stream *stream) = 0; Signal inputBufferReady; Signal outputBufferReady; const std::string &deviceNode() const { return deviceNode_; } Features features() const { return features_; } protected: Features features_; private: std::string deviceNode_; }; class ConverterFactoryBase { public: ConverterFactoryBase(const std::string name, std::initializer_list compatibles); virtual ~ConverterFactoryBase() = default; const std::vector &compatibles() const { return compatibles_; } static std::unique_ptr create(std::shared_ptr media); static std::vector &factories(); static std::vector names(); private: LIBCAMERA_DISABLE_COPY_AND_MOVE(ConverterFactoryBase) static void registerType(ConverterFactoryBase *factory); virtual std::unique_ptr createInstance(std::shared_ptr media) const = 0; std::string name_; std::vector compatibles_; }; template class ConverterFactory : public ConverterFactoryBase { public: ConverterFactory(const char *name, std::initializer_list compatibles) : ConverterFactoryBase(name, compatibles) { } std::unique_ptr createInstance(std::shared_ptr media) const override { return std::make_unique<_Converter>(media); } }; #define REGISTER_CONVERTER(name, converter, compatibles) \ static ConverterFactory global_##converter##Factory(name, compatibles); } /* namespace libcamera */