[libcamera-devel] [PATCH 1/3] libcamera: converter: split ConverterMD (media device) out of Converter
Jacopo Mondi
jacopo.mondi at ideasonboard.com
Mon Sep 11 17:55:47 CEST 2023
Hi Andrey
On Sun, Sep 10, 2023 at 08:50:25PM +0300, Andrey Konovalov via libcamera-devel wrote:
> Make Converter a bit more generic by not requiring it to use a media device.
> For this split out ConverterMD from Converter class, and rename
> ConverterFactoryBase / ConverterFactory to ConverterMDFactoryBase /
> ConverterMDFactory for consistency.
>
> Signed-off-by: Andrey Konovalov <andrey.konovalov at linaro.org>
I understand where this is going, but before going into a full review
I would like to explore the possibility of generalizing the existing
hierarchy before splitting it in media and non-media versions, which
would require re-defining another FactoryBase because as you said, I
do expect as well software converter to need a factory too..
As far as I can see the MediaDevice is mostly used to get the
->driver() name out and match it against a list of compatibles the
Converter-derived class has been instantiated with.
It seems to possible to make the '*media' parameter optional to most
functions that accept it, or even overload the
ConverterFactoryBase::create() and createInstance() functions to
accept instead a string that identifies the software converter version
(ie "linaro-sw-converter" in your case?).
I would go as far as wondering if insted we shouldn't make the whole
hierarchy string-based and MediaDevice completely.
The only thing we would lose for real would be
const std::vector<MediaEntity *> &entities = media->entities();
auto it = std::find_if(entities.begin(), entities.end(),
[](MediaEntity *entity) {
return entity->function() == MEDIA_ENT_F_IO_V4L;
});
if (it == entities.end()) {
LOG(Converter, Error)
<< "No entity suitable for implementing a converter in "
<< media->driver() << " entities list.";
return;
}
at construction-time. Would this be that bad ? (if we want to keep it
we can have 2 overloaded constructors, in example).
Have this options been discussed in the previous version or have you
considered them but then discarded by any chance ?
Below some drive-by comments
> ---
> include/libcamera/internal/converter.h | 49 +---
> .../internal/converter/converter_v4l2_m2m.h | 4 +-
> include/libcamera/internal/converter_media.h | 86 +++++++
> include/libcamera/internal/meson.build | 1 +
> src/libcamera/converter.cpp | 191 +-------------
> .../converter/converter_v4l2_m2m.cpp | 4 +-
> src/libcamera/converter_media.cpp | 241 ++++++++++++++++++
> src/libcamera/meson.build | 1 +
> src/libcamera/pipeline/simple/simple.cpp | 4 +-
> 9 files changed, 337 insertions(+), 244 deletions(-)
> create mode 100644 include/libcamera/internal/converter_media.h
> create mode 100644 src/libcamera/converter_media.cpp
>
> diff --git a/include/libcamera/internal/converter.h b/include/libcamera/internal/converter.h
> index 834ec5ab..da1f5d73 100644
> --- a/include/libcamera/internal/converter.h
> +++ b/include/libcamera/internal/converter.h
> @@ -24,14 +24,13 @@
> namespace libcamera {
>
> class FrameBuffer;
> -class MediaDevice;
> class PixelFormat;
> struct StreamConfiguration;
>
> class Converter
> {
> public:
> - Converter(MediaDevice *media);
> + Converter();
> virtual ~Converter();
>
> virtual int loadConfiguration(const std::string &filename) = 0;
> @@ -57,52 +56,6 @@ public:
>
> 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
> index 815916d0..aeb8c0e9 100644
> --- a/include/libcamera/internal/converter/converter_v4l2_m2m.h
> +++ b/include/libcamera/internal/converter/converter_v4l2_m2m.h
> @@ -20,7 +20,7 @@
>
> #include <libcamera/pixel_format.h>
>
> -#include "libcamera/internal/converter.h"
> +#include "libcamera/internal/converter_media.h"
>
> namespace libcamera {
>
> @@ -31,7 +31,7 @@ class SizeRange;
> struct StreamConfiguration;
> class V4L2M2MDevice;
>
> -class V4L2M2MConverter : public Converter
> +class V4L2M2MConverter : public ConverterMD
> {
> public:
> V4L2M2MConverter(MediaDevice *media);
> diff --git a/include/libcamera/internal/converter_media.h b/include/libcamera/internal/converter_media.h
> new file mode 100644
> index 00000000..2b56ebdb
> --- /dev/null
> +++ b/include/libcamera/internal/converter_media.h
> @@ -0,0 +1,86 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2020, Laurent Pinchart
> + * Copyright 2022 NXP
> + *
> + * converter_media.h - Generic media device based 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>
> +
> +#include "libcamera/internal/converter.h"
A lot of stuff (inclusions an forward declaration) are duplicated in
this and in the libcamera/internal/converter.h header. You can include
converter.h first and add only what is missing.
> +
> +namespace libcamera {
> +
> +class FrameBuffer;
> +class MediaDevice;
> +class PixelFormat;
> +struct StreamConfiguration;
> +
> +class ConverterMD : public Converter
> +{
> +public:
> + ConverterMD(MediaDevice *media);
> + ~ConverterMD();
> +
> + const std::string &deviceNode() const { return deviceNode_; }
> +
> +private:
> + std::string deviceNode_;
> +};
> +
> +class ConverterMDFactoryBase
> +{
> +public:
> + ConverterMDFactoryBase(const std::string name, std::initializer_list<std::string> compatibles);
> + virtual ~ConverterMDFactoryBase() = default;
> +
> + const std::vector<std::string> &compatibles() const { return compatibles_; }
> +
> + static std::unique_ptr<ConverterMD> create(MediaDevice *media);
> + static std::vector<ConverterMDFactoryBase *> &factories();
> + static std::vector<std::string> names();
> +
> +private:
> + LIBCAMERA_DISABLE_COPY_AND_MOVE(ConverterMDFactoryBase)
> +
> + static void registerType(ConverterMDFactoryBase *factory);
> +
> + virtual std::unique_ptr<ConverterMD> createInstance(MediaDevice *media) const = 0;
> +
> + std::string name_;
> + std::vector<std::string> compatibles_;
> +};
> +
> +template<typename _ConverterMD>
> +class ConverterMDFactory : public ConverterMDFactoryBase
> +{
> +public:
> + ConverterMDFactory(const char *name, std::initializer_list<std::string> compatibles)
> + : ConverterMDFactoryBase(name, compatibles)
> + {
> + }
> +
> + std::unique_ptr<ConverterMD> createInstance(MediaDevice *media) const override
> + {
> + return std::make_unique<_ConverterMD>(media);
> + }
> +};
> +
> +#define REGISTER_CONVERTER_MD(name, converter, compatibles) \
> + static ConverterMDFactory<converter> global_##converter##MDFactory(name, compatibles);
> +
> +} /* namespace libcamera */
> diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build
> index 7f1f3440..e9c41346 100644
> --- a/include/libcamera/internal/meson.build
> +++ b/include/libcamera/internal/meson.build
> @@ -21,6 +21,7 @@ libcamera_internal_headers = files([
> 'control_serializer.h',
> 'control_validator.h',
> 'converter.h',
> + 'converter_media.h',
> 'delayed_controls.h',
> 'device_enumerator.h',
> 'device_enumerator_sysfs.h',
> diff --git a/src/libcamera/converter.cpp b/src/libcamera/converter.cpp
> index fa0f1ec8..92dcdc03 100644
> --- a/src/libcamera/converter.cpp
> +++ b/src/libcamera/converter.cpp
> @@ -38,26 +38,9 @@ LOG_DEFINE_CATEGORY(Converter)
>
> /**
> * \brief Construct a Converter instance
> - * \param[in] media The media device implementing the converter
> - *
> - * This searches for the entity implementing the data streaming function in the
> - * media graph entities and use its device node as the converter device node.
> */
> -Converter::Converter(MediaDevice *media)
> +Converter::Converter()
> {
> - const std::vector<MediaEntity *> &entities = media->entities();
> - auto it = std::find_if(entities.begin(), entities.end(),
> - [](MediaEntity *entity) {
> - return entity->function() == MEDIA_ENT_F_IO_V4L;
> - });
> - if (it == entities.end()) {
> - LOG(Converter, Error)
> - << "No entity suitable for implementing a converter in "
> - << media->driver() << " entities list.";
> - return;
> - }
> -
> - deviceNode_ = (*it)->deviceNode();
> }
>
> Converter::~Converter()
> @@ -159,176 +142,4 @@ Converter::~Converter()
> * \brief A signal emitted on each frame buffer completion of the output queue
> */
>
> -/**
> - * \fn Converter::deviceNode()
> - * \brief The converter device node attribute accessor
> - * \return The converter device node string
> - */
> -
> -/**
> - * \class ConverterFactoryBase
> - * \brief Base class for converter factories
> - *
> - * The ConverterFactoryBase class is the base of all specializations of the
> - * ConverterFactory class template. It implements the factory registration,
> - * maintains a registry of factories, and provides access to the registered
> - * factories.
> - */
> -
> -/**
> - * \brief Construct a converter factory base
> - * \param[in] name Name of the converter class
> - * \param[in] compatibles Name aliases of the converter class
> - *
> - * Creating an instance of the factory base registers it with the global list of
> - * factories, accessible through the factories() function.
> - *
> - * The factory \a name is used as unique identifier. If the converter
> - * implementation fully relies on a generic framework, the name should be the
> - * same as the framework. Otherwise, if the implementation is specialized, the
> - * factory name should match the driver name implementing the function.
> - *
> - * The factory \a compatibles holds a list of driver names implementing a generic
> - * subsystem without any personalizations.
> - */
> -ConverterFactoryBase::ConverterFactoryBase(const std::string name, std::initializer_list<std::string> compatibles)
> - : name_(name), compatibles_(compatibles)
> -{
> - registerType(this);
> -}
> -
> -/**
> - * \fn ConverterFactoryBase::compatibles()
> - * \return The names compatibles
> - */
> -
> -/**
> - * \brief Create an instance of the converter corresponding to a named factory
> - * \param[in] media Name of the factory
This clearly was wrong already, and if you shuffle code around might
be a good occasion to change it.
> - *
> - * \return A unique pointer to a new instance of the converter subclass
> - * corresponding to the named factory or one of its alias. Otherwise a null
> - * pointer if no such factory exists
> - */
> -std::unique_ptr<Converter> ConverterFactoryBase::create(MediaDevice *media)
> -{
> - const std::vector<ConverterFactoryBase *> &factories =
> - ConverterFactoryBase::factories();
> -
> - for (const ConverterFactoryBase *factory : factories) {
> - const std::vector<std::string> &compatibles = factory->compatibles();
> - auto it = std::find(compatibles.begin(), compatibles.end(), media->driver());
> -
> - if (it == compatibles.end() && media->driver() != factory->name_)
> - continue;
> -
> - LOG(Converter, Debug)
> - << "Creating converter from "
> - << factory->name_ << " factory with "
> - << (it == compatibles.end() ? "no" : media->driver()) << " alias.";
> -
> - std::unique_ptr<Converter> converter = factory->createInstance(media);
> - if (converter->isValid())
> - return converter;
> - }
> -
> - return nullptr;
> -}
> -
> -/**
> - * \brief Add a converter class to the registry
> - * \param[in] factory Factory to use to construct the converter class
> - *
> - * The caller is responsible to guarantee the uniqueness of the converter name.
> - */
> -void ConverterFactoryBase::registerType(ConverterFactoryBase *factory)
> -{
> - std::vector<ConverterFactoryBase *> &factories =
> - ConverterFactoryBase::factories();
> -
> - factories.push_back(factory);
> -}
> -
> -/**
> - * \brief Retrieve the list of all converter factory names
> - * \return The list of all converter factory names
> - */
> -std::vector<std::string> ConverterFactoryBase::names()
> -{
> - std::vector<std::string> list;
> -
> - std::vector<ConverterFactoryBase *> &factories =
> - ConverterFactoryBase::factories();
> -
> - for (ConverterFactoryBase *factory : factories) {
> - list.push_back(factory->name_);
> - for (auto alias : factory->compatibles())
> - list.push_back(alias);
> - }
> -
> - return list;
> -}
> -
> -/**
> - * \brief Retrieve the list of all converter factories
> - * \return The list of converter factories
> - */
> -std::vector<ConverterFactoryBase *> &ConverterFactoryBase::factories()
> -{
> - /*
> - * The static factories map is defined inside the function to ensure
> - * it gets initialized on first use, without any dependency on link
> - * order.
> - */
> - static std::vector<ConverterFactoryBase *> factories;
> - return factories;
> -}
> -
> -/**
> - * \var ConverterFactoryBase::name_
> - * \brief The name of the factory
> - */
> -
> -/**
> - * \var ConverterFactoryBase::compatibles_
> - * \brief The list holding the factory compatibles
> - */
> -
> -/**
> - * \class ConverterFactory
> - * \brief Registration of ConverterFactory classes and creation of instances
> - * \param _Converter The converter class type for this factory
> - *
> - * To facilitate discovery and instantiation of Converter classes, the
> - * ConverterFactory class implements auto-registration of converter helpers.
> - * Each Converter subclass shall register itself using the REGISTER_CONVERTER()
> - * macro, which will create a corresponding instance of a ConverterFactory
> - * subclass and register it with the static list of factories.
> - */
> -
> -/**
> - * \fn ConverterFactory::ConverterFactory(const char *name, std::initializer_list<std::string> compatibles)
> - * \brief Construct a converter factory
> - * \details \copydetails ConverterFactoryBase::ConverterFactoryBase
> - */
> -
> -/**
> - * \fn ConverterFactory::createInstance() const
> - * \brief Create an instance of the Converter corresponding to the factory
> - * \param[in] media Media device pointer
> - * \return A unique pointer to a newly constructed instance of the Converter
> - * subclass corresponding to the factory
> - */
> -
> -/**
> - * \def REGISTER_CONVERTER
> - * \brief Register a converter with the Converter factory
> - * \param[in] name Converter name used to register the class
> - * \param[in] converter Class name of Converter derived class to register
> - * \param[in] compatibles List of compatible names
> - *
> - * Register a Converter subclass with the factory and make it available to try
> - * and match converters.
> - */
> -
> } /* namespace libcamera */
> diff --git a/src/libcamera/converter/converter_v4l2_m2m.cpp b/src/libcamera/converter/converter_v4l2_m2m.cpp
> index 2a4d1d99..d0a5e3bf 100644
> --- a/src/libcamera/converter/converter_v4l2_m2m.cpp
> +++ b/src/libcamera/converter/converter_v4l2_m2m.cpp
> @@ -194,7 +194,7 @@ void V4L2M2MConverter::Stream::captureBufferReady(FrameBuffer *buffer)
> */
>
> V4L2M2MConverter::V4L2M2MConverter(MediaDevice *media)
> - : Converter(media)
> + : ConverterMD(media)
> {
> if (deviceNode().empty())
> return;
> @@ -448,6 +448,6 @@ static std::initializer_list<std::string> compatibles = {
> "pxp",
> };
>
> -REGISTER_CONVERTER("v4l2_m2m", V4L2M2MConverter, compatibles)
> +REGISTER_CONVERTER_MD("v4l2_m2m", V4L2M2MConverter, compatibles)
>
> } /* namespace libcamera */
> diff --git a/src/libcamera/converter_media.cpp b/src/libcamera/converter_media.cpp
> new file mode 100644
> index 00000000..f5024764
> --- /dev/null
> +++ b/src/libcamera/converter_media.cpp
> @@ -0,0 +1,241 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright 2022 NXP
> + *
You copyright here and in the header file if you like to
> + * converter.cpp - Generic format converter interface
> + */
> +
> +#include "libcamera/internal/converter_media.h"
> +
> +#include <algorithm>
> +
> +#include <libcamera/base/log.h>
> +
> +#include "libcamera/internal/media_device.h"
> +
> +#include "linux/media.h"
I know it was already like this, but I would have expected to see <>
It shouldn't make a difference though, even if this is a system-wide
header we ship our own copy and adjust the inclusion prefix precendece
to use our own version (I presume) so both "" and <> will do the same
thing ?
And, btw, this is included by media_device.h (again, not your fault)
> +
> +/**
> + * \file internal/converter_media.h
> + * \brief Abstract media device based converter
> + */
> +
> +namespace libcamera {
> +
> +LOG_DECLARE_CATEGORY(Converter)
Maybe ConverterMD ?
> +
> +/**
> + * \class ConverterMD
> + * \brief Abstract Base Class for media device based converter
> + *
> + * The ConverterMD class is an Abstract Base Class defining the interfaces of
> + * media device based converter implementations.
> + *
> + * Converters offer scaling and pixel format conversion services on an input
> + * stream. The converter can output multiple streams with individual conversion
> + * parameters from the same input stream.
> + */
> +
> +/**
> + * \brief Construct a ConverterMD instance
> + * \param[in] media The media device implementing the converter
> + *
> + * This searches for the entity implementing the data streaming function in the
> + * media graph entities and use its device node as the converter device node.
> + */
> +ConverterMD::ConverterMD(MediaDevice *media)
> +{
> + const std::vector<MediaEntity *> &entities = media->entities();
> + auto it = std::find_if(entities.begin(), entities.end(),
> + [](MediaEntity *entity) {
> + return entity->function() == MEDIA_ENT_F_IO_V4L;
> + });
> + if (it == entities.end()) {
> + LOG(Converter, Error)
> + << "No entity suitable for implementing a converter in "
> + << media->driver() << " entities list.";
> + return;
> + }
> +
> + deviceNode_ = (*it)->deviceNode();
> +}
> +
> +ConverterMD::~ConverterMD()
> +{
> +}
> +
> +/**
> + * \fn ConverterMD::deviceNode()
> + * \brief The converter device node attribute accessor
> + * \return The converter device node string
> + */
> +
> +/**
> + * \class ConverterMDFactoryBase
> + * \brief Base class for media device based converter factories
> + *
> + * The ConverterMDFactoryBase class is the base of all specializations of the
> + * ConverterMDFactory class template. It implements the factory registration,
> + * maintains a registry of factories, and provides access to the registered
> + * factories.
> + */
> +
> +/**
> + * \brief Construct a media device based converter factory base
> + * \param[in] name Name of the converter class
> + * \param[in] compatibles Name aliases of the converter class
> + *
> + * Creating an instance of the factory base registers it with the global list of
> + * factories, accessible through the factories() function.
> + *
> + * The factory \a name is used as unique identifier. If the converter
> + * implementation fully relies on a generic framework, the name should be the
> + * same as the framework. Otherwise, if the implementation is specialized, the
> + * factory name should match the driver name implementing the function.
> + *
> + * The factory \a compatibles holds a list of driver names implementing a generic
> + * subsystem without any personalizations.
> + */
> +ConverterMDFactoryBase::ConverterMDFactoryBase(const std::string name, std::initializer_list<std::string> compatibles)
> + : name_(name), compatibles_(compatibles)
> +{
> + registerType(this);
> +}
> +
> +/**
> + * \fn ConverterMDFactoryBase::compatibles()
> + * \return The names compatibles
> + */
> +
> +/**
> + * \brief Create an instance of the converter corresponding to a named factory
> + * \param[in] media Name of the factory
> + *
> + * \return A unique pointer to a new instance of the media device based
> + * converter subclass corresponding to the named factory or one of its alias.
> + * Otherwise a null pointer if no such factory exists.
> + */
> +std::unique_ptr<ConverterMD> ConverterMDFactoryBase::create(MediaDevice *media)
> +{
> + const std::vector<ConverterMDFactoryBase *> &factories =
> + ConverterMDFactoryBase::factories();
> +
> + for (const ConverterMDFactoryBase *factory : factories) {
> + const std::vector<std::string> &compatibles = factory->compatibles();
> + auto it = std::find(compatibles.begin(), compatibles.end(), media->driver());
> +
> + if (it == compatibles.end() && media->driver() != factory->name_)
> + continue;
> +
> + LOG(Converter, Debug)
> + << "Creating converter from "
> + << factory->name_ << " factory with "
> + << (it == compatibles.end() ? "no" : media->driver()) << " alias.";
> +
> + std::unique_ptr<ConverterMD> converter = factory->createInstance(media);
> + if (converter->isValid())
> + return converter;
> + }
> +
> + return nullptr;
> +}
> +
> +/**
> + * \brief Add a media device based converter class to the registry
> + * \param[in] factory Factory to use to construct the media device based
> + * converter class
> + *
> + * The caller is responsible to guarantee the uniqueness of the converter name.
> + */
> +void ConverterMDFactoryBase::registerType(ConverterMDFactoryBase *factory)
> +{
> + std::vector<ConverterMDFactoryBase *> &factories =
> + ConverterMDFactoryBase::factories();
> +
> + factories.push_back(factory);
> +}
> +
> +/**
> + * \brief Retrieve the list of all media device based converter factory names
> + * \return The list of all media device based converter factory names
> + */
> +std::vector<std::string> ConverterMDFactoryBase::names()
> +{
> + std::vector<std::string> list;
> +
> + std::vector<ConverterMDFactoryBase *> &factories =
> + ConverterMDFactoryBase::factories();
> +
> + for (ConverterMDFactoryBase *factory : factories) {
> + list.push_back(factory->name_);
> + for (auto alias : factory->compatibles())
> + list.push_back(alias);
> + }
> +
> + return list;
> +}
> +
> +/**
> + * \brief Retrieve the list of all media device based converter factories
> + * \return The list of media device based converter factories
> + */
> +std::vector<ConverterMDFactoryBase *> &ConverterMDFactoryBase::factories()
> +{
> + /*
> + * The static factories map is defined inside the function to ensure
> + * it gets initialized on first use, without any dependency on link
> + * order.
> + */
> + static std::vector<ConverterMDFactoryBase *> factories;
> + return factories;
> +}
> +
> +/**
> + * \var ConverterMDFactoryBase::name_
> + * \brief The name of the factory
> + */
> +
> +/**
> + * \var ConverterMDFactoryBase::compatibles_
> + * \brief The list holding the factory compatibles
> + */
> +
> +/**
> + * \class ConverterMDFactory
> + * \brief Registration of ConverterMDFactory classes and creation of instances
> + * \param _Converter The converter class type for this factory
> + *
> + * To facilitate discovery and instantiation of ConverterMD classes, the
> + * ConverterMDFactory class implements auto-registration of converter helpers.
> + * Each ConverterMD subclass shall register itself using the
> + * REGISTER_CONVERTER() macro, which will create a corresponding instance of a
> + * ConverterMDFactory subclass and register it with the static list of
> + * factories.
> + */
> +
> +/**
> + * \fn ConverterMDFactory::ConverterMDFactory(const char *name, std::initializer_list<std::string> compatibles)
> + * \brief Construct a media device converter factory
> + * \details \copydetails ConverterMDFactoryBase::ConverterMDFactoryBase
> + */
> +
> +/**
> + * \fn ConverterMDFactory::createInstance() const
> + * \brief Create an instance of the ConverterMD corresponding to the factory
> + * \param[in] media Media device pointer
> + * \return A unique pointer to a newly constructed instance of the ConverterMD
> + * subclass corresponding to the factory
> + */
> +
> +/**
> + * \def REGISTER_CONVERTER_MD
> + * \brief Register a media device based converter with the ConverterMD factory
> + * \param[in] name ConverterMD name used to register the class
> + * \param[in] converter Class name of ConverterMD derived class to register
> + * \param[in] compatibles List of compatible names
> + *
> + * Register a ConverterMD subclass with the factory and make it available to try
> + * and match converters.
> + */
> +
> +} /* namespace libcamera */
> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
> index b24f8296..af8b1812 100644
> --- a/src/libcamera/meson.build
> +++ b/src/libcamera/meson.build
> @@ -14,6 +14,7 @@ libcamera_sources = files([
> 'control_serializer.cpp',
> 'control_validator.cpp',
> 'converter.cpp',
> + 'converter_media.cpp',
> 'delayed_controls.cpp',
> 'device_enumerator.cpp',
> 'device_enumerator_sysfs.cpp',
> diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
> index 05ba76bc..f0622a74 100644
> --- a/src/libcamera/pipeline/simple/simple.cpp
> +++ b/src/libcamera/pipeline/simple/simple.cpp
> @@ -30,7 +30,7 @@
>
> #include "libcamera/internal/camera.h"
> #include "libcamera/internal/camera_sensor.h"
> -#include "libcamera/internal/converter.h"
> +#include "libcamera/internal/converter_media.h"
> #include "libcamera/internal/device_enumerator.h"
> #include "libcamera/internal/media_device.h"
> #include "libcamera/internal/pipeline_handler.h"
> @@ -497,7 +497,7 @@ int SimpleCameraData::init()
> /* Open the converter, if any. */
> MediaDevice *converter = pipe->converter();
> if (converter) {
> - converter_ = ConverterFactoryBase::create(converter);
> + converter_ = ConverterMDFactoryBase::create(converter);
> if (!converter_) {
> LOG(SimplePipeline, Warning)
> << "Failed to create converter, disabling format conversion";
> --
> 2.34.1
>
More information about the libcamera-devel
mailing list