summaryrefslogtreecommitdiff
path: root/src/qcam/assets/feathericons/navigation.svg
AgeCommit message (Expand)Author
2020-02-14qcam: assets: Provide initial icon setKieran Bingham
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright 2022 NXP
 *
 * converter.cpp - Generic format converter interface
 */

#include "libcamera/internal/converter.h"

#include <algorithm>

#include <libcamera/base/log.h>

#include "libcamera/internal/media_device.h"

/**
 * \file internal/converter.h
 * \brief Abstract converter
 */

namespace libcamera {

LOG_DEFINE_CATEGORY(Converter)

/**
 * \class Converter
 * \brief Abstract Base Class for converter
 *
 * The Converter class is an Abstract Base Class defining the interfaces of
 * 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 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)
{
	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()
{
}

/**
 * \fn Converter::loadConfiguration()
 * \brief Load converter configuration from file
 * \param[in] filename The file name path
 *
 * Load converter dependent configuration parameters to apply on the hardware.
 *
 * \return 0 on success or a negative error code otherwise
 */

/**
 * \fn Converter::isValid()
 * \brief Check if the converter configuration is valid
 * \return True is the converter is valid, false otherwise
 */

/**
 * \fn Converter::formats()
 * \brief Retrieve the list of supported pixel formats for an input pixel format
 * \param[in] input Input pixel format to retrieve output pixel format list for
 * \return The list of supported output pixel formats
 */

/**
 * \fn Converter::sizes()
 * \brief Retrieve the range of minimum and maximum output sizes for an input size
 * \param[in] input Input stream size to retrieve range for
 * \return A range of output image sizes
 */

/**
 * \fn Converter::strideAndFrameSize()
 * \brief Retrieve the output stride and frame size for an input configutation
 * \param[in] pixelFormat Input stream pixel format
 * \param[in] size Input stream size
 * \return A tuple indicating the stride and frame size or an empty tuple on error
 */

/**
 * \fn Converter::configure()
 * \brief Configure a set of output stream conversion from an input stream
 * \param[in] inputCfg Input stream configuration
 * \param[out] outputCfgs A list of output stream configurations
 * \return 0 on success or a negative error code otherwise
 */

/**
 * \fn Converter::exportBuffers()
 * \brief Export buffers from the converter device
 * \param[in] output Output stream index exporting the buffers
 * \param[in] count Number of buffers to allocate
 * \param[out] buffers Vector to store allocated buffers
 *
 * This function operates similarly to V4L2VideoDevice::exportBuffers() on the
 * output stream indicated by the \a output index.
 *
 * \return The number of allocated buffers on success or a negative error code
 * otherwise
 */

/**
 * \fn Converter::start()
 * \brief Start the converter streaming operation
 * \return 0 on success or a negative error code otherwise
 */

/**
 * \fn Converter::stop()
 * \brief Stop the converter streaming operation
 */

/**
 * \fn Converter::queueBuffers()
 * \brief Queue buffers to converter device
 * \param[in] input The frame buffer to apply the conversion
 * \param[out] outputs The container holding the output stream indexes and
 * their respective frame buffer outputs.
 *
 * This function queues the \a input frame buffer on the output streams of the
 * \a outputs map key and retrieve the output frame buffer indicated by the
 * buffer map value.
 *
 * \return 0 on success or a negative error code otherwise
 */

/**
 * \var Converter::inputBufferReady
 * \brief A signal emitted when the input frame buffer completes
 */

/**
 * \var Converter::outputBufferReady
 * \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 list of compatible name aliases of the converter
 */

/**
 * \brief Create an instance of the converter corresponding to the media device
 * \param[in] media The media device to create the converter for
 *
 * The converter is created by matching the factory name or any of its
 * compatible aliases with the media device driver name.
 *
 * \return A new instance of the converter subclass corresponding to the media
 * device, or null if the media device driver name doesn't match anything
 */
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 factory 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
 * factory 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 */