[libcamera-devel] [PATCH 3/5] libcamera: Add MediaLink link setup function

Jacopo Mondi jacopo at jmondi.org
Thu Jan 3 18:38:57 CET 2019


Add a function to the MediaLink class to set the state of a link to
enabled or disabled. The function makes use of an internal MediaDevice
method, which is defined private and only accessible by the MediaLink
setup() function itself.

Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
---
 src/libcamera/include/media_device.h |  8 ++++++
 src/libcamera/include/media_object.h |  1 +
 src/libcamera/media_device.cpp       | 30 +++++++++++++++++++++
 src/libcamera/media_object.cpp       | 40 ++++++++++++++++++++++++++++
 4 files changed, 79 insertions(+)

diff --git a/src/libcamera/include/media_device.h b/src/libcamera/include/media_device.h
index 3228ad5..d019639 100644
--- a/src/libcamera/include/media_device.h
+++ b/src/libcamera/include/media_device.h
@@ -65,6 +65,14 @@ private:
 	bool populateEntities(const struct media_v2_topology &topology);
 	bool populatePads(const struct media_v2_topology &topology);
 	bool populateLinks(const struct media_v2_topology &topology);
+
+	/*
+	 * The MediaLink enable method needs to access the private
+	 * setLink() function.
+	 */
+	friend int MediaLink::enable(bool enable);
+	int setLink(const MediaPad *source, const MediaPad *sink,
+		    unsigned int flags);
 };
 
 } /* namespace libcamera */
diff --git a/src/libcamera/include/media_object.h b/src/libcamera/include/media_object.h
index 0f0bb29..e00c639 100644
--- a/src/libcamera/include/media_object.h
+++ b/src/libcamera/include/media_object.h
@@ -40,6 +40,7 @@ public:
 	MediaPad *source() const { return source_; }
 	MediaPad *sink() const { return sink_; }
 	unsigned int flags() const { return flags_; }
+	int enable(bool enable);
 
 private:
 	friend class MediaDevice;
diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp
index 6892300..b86d0c4 100644
--- a/src/libcamera/media_device.cpp
+++ b/src/libcamera/media_device.cpp
@@ -641,4 +641,34 @@ bool MediaDevice::populateLinks(const struct media_v2_topology &topology)
 	return true;
 }
 
+int MediaDevice::setLink(const MediaPad *source, const MediaPad *sink,
+			 unsigned int flags)
+{
+	struct media_link_desc linkDesc = { };
+
+	linkDesc.source.entity = source->entity()->id();
+	linkDesc.source.index = source->index();
+	linkDesc.source.flags = MEDIA_PAD_FL_SOURCE;
+
+	linkDesc.sink.entity = sink->entity()->id();
+	linkDesc.sink.index = sink->index();
+	linkDesc.sink.flags = MEDIA_PAD_FL_SINK;
+
+	linkDesc.flags = flags;
+
+	int ret = ioctl(fd_, MEDIA_IOC_SETUP_LINK, &linkDesc);
+	if (ret) {
+		ret = -errno;
+		LOG(Error) << "Failed to setup link: " << strerror(-ret) << "\n";
+		return ret;
+	}
+
+	LOG(Debug) << source->entity()->name() << "["
+		   << source->index() << "] -> "
+		   << sink->entity()->name() << "["
+		   << sink->index() << "]: " << flags;
+
+	return 0;
+}
+
 } /* namespace libcamera */
diff --git a/src/libcamera/media_object.cpp b/src/libcamera/media_object.cpp
index f1535e6..1ee8823 100644
--- a/src/libcamera/media_object.cpp
+++ b/src/libcamera/media_object.cpp
@@ -16,6 +16,7 @@
 
 #include "log.h"
 #include "media_object.h"
+#include "media_device.h"
 
 /**
  * \file media_object.h
@@ -87,6 +88,45 @@ namespace libcamera {
  * Each link is referenced in the link array of both of the pads it connect.
  */
 
+/**
+ * \brief Set a link state to enabled or disabled
+ * \param enable The enable flag, true enables the link, false disables it
+ *
+ * Set the status of a link, according to the value of \a enable.
+ * Links between two pads can be set to the enabled or disabled state freely,
+ * unless they're immutable links, whose status cannot be changed.
+ * Enabling an immutable link is not considered an error, while trying to
+ * disable it is. Caller should inspect the link flags before trying to
+ * disable an immutable link.
+ *
+ * Enabling a link establishes a data connection between two pads, while
+ * disabling it interrupts such a connections.
+ *
+ * \return 0 for success, negative error code otherwise
+ */
+int MediaLink::enable(bool enable)
+{
+	unsigned int flags = enable ? MEDIA_LNK_FL_ENABLED : 0;
+
+	if ((flags_ & MEDIA_LNK_FL_IMMUTABLE) && !enable) {
+		LOG(Error) << "Immutable links cannot be disabled";
+		return -EINVAL;
+	}
+
+	/* Do not try to enable an already enabled link. */
+	if ((flags_ & MEDIA_LNK_FL_ENABLED) && enable)
+		return 0;
+
+	int ret = media_->setLink(source_, sink_, flags);
+	if (ret)
+		return ret;
+
+	/* Only update flags if 'setLink()' didn't fail. */
+	flags_ = flags;
+
+	return 0;
+}
+
 /**
  * \brief Construct a MediaLink
  * \param media The media device this entity belongs to
-- 
2.20.1



More information about the libcamera-devel mailing list