[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