From patchwork Tue Jan 8 20:47:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 193 Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2E7A360B30 for ; Tue, 8 Jan 2019 21:47:34 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id C08C140008; Tue, 8 Jan 2019 20:47:33 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 8 Jan 2019 21:47:33 +0100 Message-Id: <20190108204733.10823-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190108204733.10823-1-jacopo@jmondi.org> References: <20190108204733.10823-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 3/3] libcamera: Add link handling functions X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 Jan 2019 20:47:34 -0000 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 setEnable() function itself. Also add to MediaDevice a function to reset all links registered in the media graph. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/include/media_device.h | 4 ++ src/libcamera/include/media_object.h | 1 + src/libcamera/media_device.cpp | 75 ++++++++++++++++++++++++++++ src/libcamera/media_object.cpp | 29 +++++++++++ 4 files changed, 109 insertions(+) diff --git a/src/libcamera/include/media_device.h b/src/libcamera/include/media_device.h index 22c32b7..286740d 100644 --- a/src/libcamera/include/media_device.h +++ b/src/libcamera/include/media_device.h @@ -45,6 +45,7 @@ public: MediaLink *link(const MediaEntity *source, unsigned int sourceIdx, const MediaEntity *sink, unsigned int sinkIdx); MediaLink *link(const MediaPad *source, const MediaPad *sink); + int disableLinks(); private: std::string driver_; @@ -65,6 +66,9 @@ 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); + + friend int MediaLink::setEnable(bool enable); + int setupLink(const MediaLink *link, unsigned int flags); }; } /* namespace libcamera */ diff --git a/src/libcamera/include/media_object.h b/src/libcamera/include/media_object.h index b2c3d8e..fdc9bf8 100644 --- a/src/libcamera/include/media_object.h +++ b/src/libcamera/include/media_object.h @@ -41,6 +41,7 @@ public: MediaPad *source() const { return source_; } MediaPad *sink() const { return sink_; } unsigned int flags() const { return flags_; } + int setEnable(bool enable); private: friend class MediaDevice; diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp index ca12caa..1130ba4 100644 --- a/src/libcamera/media_device.cpp +++ b/src/libcamera/media_device.cpp @@ -386,6 +386,35 @@ MediaLink *MediaDevice::link(const MediaPad *source, const MediaPad *sink) return nullptr; } +/** + * \brief Disable all links in the media device + * + * Disable all the media device links, clearing the MEDIA_LNK_FL_ENABLED flag + * on links which are not flagged as IMMUTABLE. + * + * \return 0 on success, or a negative error code otherwise + */ +int MediaDevice::disableLinks() +{ + for (MediaEntity *entity : entities_) { + for (MediaPad *pad : entity->pads()) { + if (!(pad->flags() & MEDIA_PAD_FL_SOURCE)) + continue; + + for (MediaLink *link : pad->links()) { + if (link->flags() & MEDIA_LNK_FL_IMMUTABLE) + continue; + + int ret = link->setEnable(false); + if (ret) + return ret; + } + } + } + + return 0; +} + /** * \var MediaDevice::objects_ * \brief Global map of media objects (entities, pads, links) keyed by their @@ -602,4 +631,50 @@ bool MediaDevice::populateLinks(const struct media_v2_topology &topology) return true; } +/** + * \brief Apply \a flags to a link between two pads + * \param link The link to apply flags to + * \param flags The flags to apply to the link + * + * This function applies the link \a flags (as defined by the MEDIA_LNK_FL_* + * macros from the Media Controller API) to the given \a link. It implements + * low-level link setup as it performs no checks on the validity of the \a + * flags, and assumes that the supplied \a flags are valid for the link (e.g. + * immutable links cannot be disabled). +* + * \sa MediaLink::setEnable(bool enable) + * + * \return 0 on success, or a negative error code otherwise + */ +int MediaDevice::setupLink(const MediaLink *link, unsigned int flags) +{ + struct media_link_desc linkDesc = { }; + MediaPad *source = link->source(); + MediaPad *sink = link->sink(); + + 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); + 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 4ff9620..cd2b912 100644 --- a/src/libcamera/media_object.cpp +++ b/src/libcamera/media_object.cpp @@ -15,6 +15,7 @@ #include #include "log.h" +#include "media_device.h" #include "media_object.h" /** @@ -95,6 +96,34 @@ namespace libcamera { * Each link is referenced in the link array of both of the pads it connect. */ +/** + * \brief Enable or disable a link + * \param enable True to enable the link, false to disable 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. + * + * Enabling a link establishes a data connection between two pads, while + * disabling it interrupts that connection. + * + * \return 0 on success, or a negative error code otherwise + */ +int MediaLink::setEnable(bool enable) +{ + unsigned int flags = enable ? MEDIA_LNK_FL_ENABLED : 0; + + int ret = dev_->setupLink(this, flags); + if (ret) + return ret; + + flags_ = flags; + + return 0; +} + /** * \brief Construct a MediaLink * \param link The media link kernel data