summaryrefslogtreecommitdiff
path: root/src/libcamera/pipeline_handler.cpp
blob: a737f222b465380ca4fd22c8b339e834faf025e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2018, Google Inc.
 *
 * pipeline_handler.cpp - Pipeline handler infrastructure
 */

#include "device_enumerator.h"
#include "log.h"
#include "pipeline_handler.h"

/**
 * \file pipeline_handler.h
 * \brief Create pipelines and cameras from one or more media devices
 *
 * Each pipeline supported by libcamera needs to be backed by a pipeline
 * handler implementation which describes the one or many media devices
 * needed for a pipeline to function properly.
 *
 * The pipeline handler is responsible for providing a description of the
 * media devices it requires to operate. Once all media devices can be
 * provided the pipeline handler can acquire them and create camera
 * devices that utilize the acquired media devices.
 *
 * To make it a bit less bit complicated to write pipe line handlers a
 * macro REGISTER_PIPELINE_HANDLER() is provided which allows a pipeline
 * handler implementation to register itself with the library with ease.
 */

namespace libcamera {

/**
 * \class PipelineHandler
 * \brief Find a set of media devices and provide cameras
 *
 * The responsibility of a PipelineHandler is to describe all media
 * devices it would need in order to provide cameras to the system.
 */

/**
 * \class PipelineHandlerFactory
 * \brief Keep a registry and create instances of available pipeline handlers
 *
 * The responsibility of the PipelineHandlerFactory is to keep a list
 * of all pipelines in the system. Each pipeline handler should register
 * it self with the factory using the REGISTER_PIPELINE_HANDLER() macro.
 */

/**
 * \brief Add a pipeline handler to the global list
 *
 * \param[in] name Name of the pipeline handler to add
 * \param[in] factory Factory to use to construct the pipeline
 *
 * The caller is responsible to guarantee the uniqueness of the pipeline name.
 */
void PipelineHandlerFactory::registerType(const std::string &name,
					  PipelineHandlerFactory *factory)
{
	std::map<std::string, PipelineHandlerFactory *> &factories = registry();

	if (factories.count(name)) {
		LOG(Error) <<  "Registering '" << name << "' pipeline twice";
		return;
	}

	factories[name] = factory;
}

/**
 * \brief Create a new pipeline handler and try to match the media devices it requires
 *
 * \param[in] name Name of the pipeline handler to try
 * \param[in] enumerator Device enumerator to search for a match for the handler
 *
 * Try to match the media devices pipeline \a name requires against the ones
 * registered in \a enumerator.
 *
 * \return Pipeline handler if a match was found, nullptr otherwise
 */
PipelineHandler *PipelineHandlerFactory::create(const std::string &name,
						DeviceEnumerator *enumerator)
{
	std::map<std::string, PipelineHandlerFactory *> &factories = registry();

	auto it = factories.find(name);
	if (it == factories.end()) {
		LOG(Error) << "Trying to create non-existing pipeline handler "
			   << name;
		return nullptr;
	}

	PipelineHandler *pipe = it->second->create();

	if (pipe->match(enumerator))
		return pipe;

	delete pipe;
	return nullptr;
}

/**
 * \brief List all names of piepline handlers from the global list
 *
 * \return List of registerd pipeline handler names
 */
std::vector<std::string> PipelineHandlerFactory::handlers()
{
	std::map<std::string, PipelineHandlerFactory *> &factories = registry();
	std::vector<std::string> handlers;

	for (auto const &handler : factories)
		handlers.push_back(handler.first);

	return handlers;
}

/**
 * \brief Static global list of pipeline handlers
 *
 * The static factories map is defined inside the function to ensures it gets
 * initialized on first use, without any dependency on link order.
 *
 * \return Global list of pipeline handlers
 */
std::map<std::string, PipelineHandlerFactory *> &PipelineHandlerFactory::registry()
{
	static std::map<std::string, PipelineHandlerFactory *> factories;
	return factories;
}

/**
 * \def REGISTER_PIPELINE_HANDLER
 * \brief Register a pipeline handler with the global list
 *
 * \param[in] handler Class name of PipelineHandler derived class to register
 *
 * Register a specific pipeline handler with the global list and make it
 * available to try and match devices.
 */

} /* namespace libcamera */