[libcamera-devel] [RFC 1/2] libcamera: stream: Implement StreamProperties

Jacopo Mondi jacopo at jmondi.org
Mon Apr 1 12:14:09 CEST 2019


Add definition for the StreamProperties and StreamUsage classes.

Use them in the IPU3 pipeline handler to store stream-specific properties,
and extend the StreamProperties base class with IPU3 specific
parameters, such as the desired ImgU pipeline mode.

Also add an 'hints' field to StreamConfiguration to implement matching
between the stream properties and a requested configuration.

Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
---
 include/libcamera/meson.build             |   1 +
 include/libcamera/stream.h                |   7 ++
 include/libcamera/stream_usages.h         |  20 ++++
 src/libcamera/include/stream_properties.h |  41 ++++++++
 src/libcamera/meson.build                 |   1 +
 src/libcamera/pipeline/ipu3/ipu3.cpp      |  45 ++++++++
 src/libcamera/stream.cpp                  |  25 +++++
 src/libcamera/stream_properties.cpp       | 121 ++++++++++++++++++++++
 8 files changed, 261 insertions(+)
 create mode 100644 include/libcamera/stream_usages.h
 create mode 100644 src/libcamera/include/stream_properties.h
 create mode 100644 src/libcamera/stream_properties.cpp

diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build
index 3f4d1e28208b..25901303b97d 100644
--- a/include/libcamera/meson.build
+++ b/include/libcamera/meson.build
@@ -9,6 +9,7 @@ libcamera_api = files([
     'request.h',
     'signal.h',
     'stream.h',
+    'stream_usages.h',
     'timer.h',
 ])
 
diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h
index 970c479627fa..afcc4ff08923 100644
--- a/include/libcamera/stream.h
+++ b/include/libcamera/stream.h
@@ -7,7 +7,10 @@
 #ifndef __LIBCAMERA_STREAM_H__
 #define __LIBCAMERA_STREAM_H__
 
+#include <forward_list>
+
 #include <libcamera/buffer.h>
+#include <libcamera/stream_usages.h>
 
 namespace libcamera {
 
@@ -19,6 +22,10 @@ struct StreamConfiguration {
 	unsigned int pixelFormat;
 
 	unsigned int bufferCount;
+
+	std::forward_list<enum StreamUsage> hints;
+
+	bool supports(const enum StreamUsage &usage) const;
 };
 
 class Stream final
diff --git a/include/libcamera/stream_usages.h b/include/libcamera/stream_usages.h
new file mode 100644
index 000000000000..9f7358954181
--- /dev/null
+++ b/include/libcamera/stream_usages.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * stream_usages.h - Definition of stream usage hints
+ */
+#ifndef __LIBCAMERA_STREAM_USAGES_H__
+#define __LIBCAMERA_STREAM_USAGES_H__
+
+namespace libcamera {
+
+enum StreamUsage {
+	VIEWFINDER,
+	VIDEO_RECORDING,
+	STILL_CAPTURE,
+};
+
+} /* namespace libcamera */
+
+#endif /* __LIBCAMERA_STREAM_USAGES_H__ */
diff --git a/src/libcamera/include/stream_properties.h b/src/libcamera/include/stream_properties.h
new file mode 100644
index 000000000000..ced8bb931bf6
--- /dev/null
+++ b/src/libcamera/include/stream_properties.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * stream_properties.h - Properties associated with a camera stream
+ */
+
+#ifndef __LIBCAMERA_STREAM_PROPERTIES_H__
+#define __LIBCAMERA_STREAM_PROPERTIES_H__
+
+#include <forward_list>
+#include <string>
+
+#include <libcamera/stream.h>
+#include <libcamera/stream_usages.h>
+
+#include "formats.h"
+
+namespace libcamera {
+
+class StreamProperties {
+public:
+	virtual ~StreamProperties() { }
+
+	void addUsage(const enum StreamUsage &usage);
+	void addFormat(unsigned int pixfmt, std::vector<SizeRange> sizes);
+
+	const std::string &name() const { return name_; }
+	void setName(const std::string &name);
+
+	virtual bool match(const StreamConfiguration &config) const;
+
+private:
+	std::forward_list<enum StreamUsage> usages_;
+	FormatEnum formats_;
+	std::string name_;
+};
+
+} /* namespace libcamera */
+
+#endif /* __LIBCAMERA_STREAM_USAGES_H__ */
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 4433abfceca3..b00a34919c2c 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -16,6 +16,7 @@ libcamera_sources = files([
     'request.cpp',
     'signal.cpp',
     'stream.cpp',
+    'stream_properties.cpp',
     'timer.cpp',
     'v4l2_device.cpp',
     'v4l2_subdevice.cpp',
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 69b40aa0026b..46479944a4da 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -14,12 +14,14 @@
 #include <libcamera/camera.h>
 #include <libcamera/request.h>
 #include <libcamera/stream.h>
+#include <libcamera/stream_usages.h>
 
 #include "device_enumerator.h"
 #include "geometry.h"
 #include "log.h"
 #include "media_device.h"
 #include "pipeline_handler.h"
+#include "stream_properties.h"
 #include "utils.h"
 #include "v4l2_device.h"
 #include "v4l2_subdevice.h"
@@ -28,6 +30,17 @@ namespace libcamera {
 
 LOG_DEFINE_CATEGORY(IPU3)
 
+class IPU3StreamProperties : public StreamProperties
+{
+public:
+	static constexpr unsigned int IMGU_VIDEO_MODE = 0;
+	static constexpr unsigned int IMGU_STILL_MODE = 1;
+
+	~IPU3StreamProperties() { }
+
+	unsigned int pipelineMode;
+};
+
 static int mediaBusToCIO2Format(unsigned int code)
 {
 	switch (code) {
@@ -222,6 +235,7 @@ private:
 
 		Stream outStream_;
 		Stream vfStream_;
+		std::map<Stream *, IPU3StreamProperties> streamProps_;
 
 		/* Absolute miniumum and maximum sizes. */
 		SizeRange sizes_;
@@ -811,6 +825,37 @@ int PipelineHandlerIPU3::registerCameras()
 		data->imgu_->viewfinder_->bufferReady.connect(data.get(),
 					&IPU3CameraData::imguCaptureBufferReady);
 
+
+		/*
+		 * Prepare the enumerations of formats supported by the
+		 * streams.
+		 *
+		 * \todo: As of now, only support continous size ranges.
+		 */
+		SizeRange &cio2MaxSize = cio2->maxSizes_.second;
+		SizeRange ipu3StreamSizes(1, 1, cio2MaxSize.maxWidth,
+					  cio2MaxSize.maxHeight);
+
+		/* Fill in the properties for each supported stream. */
+		IPU3StreamProperties outputStreamProps;
+		outputStreamProps.setName("output");
+		outputStreamProps.addUsage(STILL_CAPTURE);
+		outputStreamProps.addFormat(V4L2_PIX_FMT_NV12,
+					    { ipu3StreamSizes } );
+		outputStreamProps.pipelineMode =
+			IPU3StreamProperties::IMGU_STILL_MODE;
+		data->streamProps_[&data->outStream_] = outputStreamProps;
+
+		IPU3StreamProperties viewfinderStreamProps;
+		viewfinderStreamProps.setName("viewfinder");
+		viewfinderStreamProps.addUsage(VIEWFINDER);
+		viewfinderStreamProps.addUsage(VIDEO_RECORDING);
+		viewfinderStreamProps.addFormat(V4L2_PIX_FMT_NV12,
+						{ ipu3StreamSizes } );
+		outputStreamProps.pipelineMode =
+			IPU3StreamProperties::IMGU_VIDEO_MODE;
+		data->streamProps_[&data->vfStream_] = viewfinderStreamProps;
+
 		/* Create and register the Camera instance. */
 		std::string cameraName = cio2->name() + " "
 				       + std::to_string(id);
diff --git a/src/libcamera/stream.cpp b/src/libcamera/stream.cpp
index c4943c91b2e6..7b8d6ac4f895 100644
--- a/src/libcamera/stream.cpp
+++ b/src/libcamera/stream.cpp
@@ -60,6 +60,31 @@ namespace libcamera {
  * \brief Requested number of buffers to allocate for the stream
  */
 
+/**
+ * \var StreamConfiguration::hints
+ * \brief List of intended stream usages
+ *
+ * This field represents a list of intended stream usage hints. It is set
+ * by applications when requesting the stream's default configurations with
+ * Camera::streamConfiguration() method.
+ */
+
+/**
+ * \brief Verify if a stream configuration supports a \a usage
+ * \param[in] usage The stream usage to verify
+ *
+ * \return True if the usage is supported, false otherwise
+ */
+bool StreamConfiguration::supports(const enum StreamUsage &usage) const
+{
+	for (const enum StreamUsage &hint : hints) {
+		if (hint == usage)
+			return true;
+	}
+
+	return false;
+}
+
 /**
  * \class Stream
  * \brief Video stream for a camera
diff --git a/src/libcamera/stream_properties.cpp b/src/libcamera/stream_properties.cpp
new file mode 100644
index 000000000000..582b314b7bb6
--- /dev/null
+++ b/src/libcamera/stream_properties.cpp
@@ -0,0 +1,121 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * stream_properties.cpp - Properties associated with a camera stream
+ */
+
+#include <libcamera/stream.h>
+
+#include "log.h"
+#include "stream_properties.h"
+
+namespace libcamera {
+
+LOG_DEFINE_CATEGORY(PROPS)
+
+/**
+ * \class StreamProperties
+ * \brief Collect a stream characteristics and matches them against a
+ * requested stream configuration
+ *
+ * The StreamProperties class collects all the informations related to a
+ * Stream capabilities, including its name, the list of supported formats and
+ * sizes and the list of intended usages of the streams.
+ *
+ * Streams are created by pipeline handlers, and their static properties are
+ * represented by instances of this class, which pipeline handlers should
+ * internally associate with each of its streams.
+ *
+ * The stream properties can be matched against a requested stream
+ * configuration, and this operations is usually performed by pipeline
+ * handlers trying to satisfy an application request at
+ * PipelineHander::streamConfiguration() time, where a list of
+ * StreamConfiguration instances gets associated with a list of Streams.
+ *
+ * Pipeline handlers are free to sub-class StreamProperties to extend them
+ * and add platform-specific informations, as StreamProperties are not exposed
+ * to applications nor in the public library interface (for this reason, there
+ * is not direct dependencies between this class and the Stream one, which is
+ * publicly exposed and directly used by applications). The additional
+ * platform specific informations shall be used in the stream matching procedure
+ * or to store pipeline specific configuration parameters associated with a
+ * stream.
+ */
+
+/**
+ * \brief Add a usage hint to the stream property
+ * \param[in] usage The usage hint
+ */
+void StreamProperties::addUsage(const enum StreamUsage &usage)
+{
+	usages_.push_front(usage);
+}
+
+/**
+ * \brief Add a list of supported sizes associated with a pixel format
+ * \param[in] pixfmt The pixel format
+ * \param[in] sizes The list of size ranges
+ */
+void StreamProperties::addFormat(unsigned int pixfmt,
+				 std::vector<SizeRange> sizes)
+{
+	if (formats_.find(pixfmt) != formats_.end())
+		LOG(PROPS, Error) << "Overwriting sizes associated with format "
+				  << pixfmt;
+
+	formats_[pixfmt] = sizes;
+}
+
+/**
+ * \fn StreamProperties::name()
+ * \brief Retrieve the stream name
+ *
+ * \return The stream name
+ */
+
+/**
+ * \brief Set the stream name
+ * \param[in] name The stream name
+ */
+void StreamProperties::setName(const std::string &name)
+{
+	name_ = name;
+}
+
+/**
+ * \brief Compare the properties of a stream with a stream configuration request
+ * \param[in] config The requested stream configuration
+ *
+ * This helper method compares the properties of a stream with a stream
+ * requested configuration. Its intended users are pipeline handlers that
+ * receive stream configurations and try to match them with a stream that
+ * satisfies the request parameters.
+ *
+ * A StreamProperties satisfies the requested \a config when:
+ * 1) The requested pixel format is listed in the property's formats map;
+ * 2) The requested sizes are included in the supported size intervals list in
+ * the property's formats map;
+ * 3) At least one of the requested usage hints is reported in the property's
+ * list of intended usages;
+ *
+ * If all the above criteria as satisfied, the helper return true and the
+ * stream associated with the property matches the requested configuration.
+ *
+ * \return True if the stream's properties satisfy the requested configuration,
+ * false otherwise
+ */
+bool StreamProperties::match(const StreamConfiguration &config) const
+{
+	/* \todo: as a proof of concept, right now only match on 'hints'. */
+	for (const enum StreamUsage &usage : usages_) {
+		for (const enum StreamUsage &hint : config.hints) {
+			if (usage == hint)
+				return true;
+		}
+	}
+
+	return false;
+}
+
+} /* namespace libcamera */
-- 
2.21.0



More information about the libcamera-devel mailing list