From patchwork Thu Jan 3 17:38:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 146 Return-Path: Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 22A5B60B13 for ; Thu, 3 Jan 2019 18:39:03 +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 relay9-d.mail.gandi.net (Postfix) with ESMTPSA id B3A2DFF804; Thu, 3 Jan 2019 17:39:02 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 3 Jan 2019 18:38:56 +0100 Message-Id: <20190103173859.22624-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190103173859.22624-1-jacopo@jmondi.org> References: <20190103173859.22624-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/5] libcamera: media_device: Add function to get a MediaLink 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: Thu, 03 Jan 2019 17:39:03 -0000 Add three overloaded functions 'link()' to retrieve a link between two pads. Each overloaded implementation exposes a different method to identify the source and sink entities. Signed-off-by: Jacopo Mondi --- src/libcamera/include/media_device.h | 6 ++ src/libcamera/media_device.cpp | 119 +++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/src/libcamera/include/media_device.h b/src/libcamera/include/media_device.h index 9f45fc7..3228ad5 100644 --- a/src/libcamera/include/media_device.h +++ b/src/libcamera/include/media_device.h @@ -40,6 +40,12 @@ public: const std::vector &entities() const { return entities_; } MediaEntity *getEntityByName(const std::string &name) const; + MediaLink *link(const std::string sourceName, unsigned int sourceIdx, + const std::string sinkName, unsigned int sinkIdx) const; + MediaLink *link(const MediaEntity *source, unsigned int sourceIdx, + const MediaEntity *sink, unsigned int sinkIdx) const; + MediaLink *link(const MediaPad *source, const MediaPad *sink) const; + private: std::string driver_; std::string devnode_; diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp index 2f9490c..6892300 100644 --- a/src/libcamera/media_device.cpp +++ b/src/libcamera/media_device.cpp @@ -306,6 +306,125 @@ MediaEntity *MediaDevice::getEntityByName(const std::string &name) const return nullptr; } +/** + * \brief Return the MediaLink that connects two entities identified by name + * \param sourceName The source entity name + * \param sourceIdx The index of the source pad + * \param sinkName The sink entity name + * \param sinkIdx The index of the sink pad + * + * Find link that connects the pads at index \a sourceIdx of the source + * entity with name \a sourceName, to the pad at index \a sinkIdx of the + * sink entity with name \a sinkName, if any. + * + * \sa MediaDevice::link(const MediaEntity *source, unsigned int sourceIdx, const MediaEntity *sink, unsigned int sinkIdx) const + * \sa MediaDevice::link(const MediaPad *source, const MediaPad *sink) const + * + * \return The link that connects the two entities, nullptr otherwise + */ +MediaLink *MediaDevice::link(const std::string sourceName, unsigned int sourceIdx, + const std::string sinkName, unsigned int sinkIdx) const +{ + const MediaEntity *source = getEntityByName(sourceName); + if (!source) { + LOG(Error) << "Failed to find entity with name: " + << sourceName << "\n"; + return nullptr; + } + + const MediaPad *sourcePad = source->getPadByIndex(sourceIdx); + if (!sourcePad) { + LOG(Error) << "Entity \"" << sourceName << "\" " + << "has no pad at index " << sourceIdx << "\n"; + return nullptr; + } + + const MediaEntity *sink = getEntityByName(sinkName); + if (!sink) { + LOG(Error) << "Failed to find entity with name: " + << sinkName << "\n"; + return nullptr; + } + + const MediaPad *sinkPad = sink->getPadByIndex(sinkIdx); + if (!sinkPad) { + LOG(Error) << "Entity \"" << sinkName << "\" " + << "has no pad at index " << sinkIdx << "\n"; + return nullptr; + } + + return link(sourcePad, sinkPad); +} + +/** + * \brief Return the MediaLink that connects two entities + * \param source The source entity + * \param sourceIdx The index of the source pad + * \param sink The sink entity + * \param sinkIdx The index of the sink pad + * + * Find link that connects the pads at index \a sourceIdx of the source + * entity \a source, to the pad at index \a sinkIdx of the sink entity \a + * sink, if any. + * + * \sa MediaDevice::link(const std::string sourceName, unsigned int sourceIdx, const std::string sinkName, unsigned int sinkIdx) const + * \sa MediaDevice::link(const MediaPad *source, const MediaPad *sink) const + * + * \return The link that connects the two entities, nullptr otherwise + */ +MediaLink *MediaDevice::link(const MediaEntity *source, unsigned int sourceIdx, + const MediaEntity *sink, unsigned int sinkIdx) const +{ + + const MediaPad *sourcePad = source->getPadByIndex(sourceIdx); + if (!sourcePad) { + LOG(Error) << "Entity \"" << source->name() << "\" " + << "has no pad at index " << sourceIdx << "\n"; + return nullptr; + } + + const MediaPad *sinkPad = sink->getPadByIndex(sinkIdx); + if (!sinkPad) { + LOG(Error) << "Entity \"" << sink->name() << "\" " + << "has no pad at index " << sinkIdx << "\n"; + return nullptr; + } + + return link(sourcePad, sinkPad); +} + +/** + * \brief Return the MediaLink that connects two pads + * \param source The source pad + * \param sink The sink pad + * + * \sa MediaDevice::link(const std::string sourceName, unsigned int sourceIdx, const std::string sinkName, unsigned int sinkIdx) const + * \sa MediaDevice::link(const MediaEntity *source, unsigned int sourceIdx, const MediaEntity *sink, unsigned int sinkIdx) const + * + * \return The link that connects the two pads, nullptr otherwise + */ +MediaLink *MediaDevice::link(const MediaPad *source, const MediaPad *sink) const +{ + if (!source || !sink) + return nullptr; + + /* + * Now that we have made sure all instances are valid, compare + * their ids to find a matching link. + */ + for (MediaLink *link : source->links()) { + if (link->sink()->id() != sink->id()) + continue; + + if (link->sink()->entity()->id() != sink->entity()->id()) + continue; + + return link; + } + + return nullptr; +} + /** * \var MediaDevice::objects_ * \brief Global map of media objects (entities, pads, links) keyed by their