Patch Detail
Show a patch.
GET /api/1.1/patches/63/?format=api
{ "id": 63, "url": "https://patchwork.libcamera.org/api/1.1/patches/63/?format=api", "web_url": "https://patchwork.libcamera.org/patch/63/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<1545324285-16730-2-git-send-email-jacopo@jmondi.org>", "date": "2018-12-20T16:44:44", "name": "[libcamera-devel,1/2] libcamera: Add MediaObject class hierarchy", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "04e6dad4b41f74f3ce12c75dda3c0b696c2918c6", "submitter": { "id": 3, "url": "https://patchwork.libcamera.org/api/1.1/people/3/?format=api", "name": "Jacopo Mondi", "email": "jacopo@jmondi.org" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/63/mbox/", "series": [ { "id": 33, "url": "https://patchwork.libcamera.org/api/1.1/series/33/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=33", "date": "2018-12-20T16:44:43", "name": "Add MediaDevice and associated MediaObjects", "version": 1, "mbox": "https://patchwork.libcamera.org/series/33/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/63/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/63/checks/", "tags": {}, "headers": { "Return-Path": "<jacopo@jmondi.org>", "Received": [ "from relay10.mail.gandi.net (relay10.mail.gandi.net\n\t[217.70.178.230])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3E2EA60B1F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 20 Dec 2018 17:45:06 +0100 (CET)", "from w540.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101])\n\t(Authenticated sender: jacopo@jmondi.org)\n\tby relay10.mail.gandi.net (Postfix) with ESMTPSA id BECF2240017;\n\tThu, 20 Dec 2018 16:45:05 +0000 (UTC)" ], "From": "Jacopo Mondi <jacopo@jmondi.org>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Thu, 20 Dec 2018 17:44:44 +0100", "Message-Id": "<1545324285-16730-2-git-send-email-jacopo@jmondi.org>", "X-Mailer": "git-send-email 2.7.4", "In-Reply-To": "<1545324285-16730-1-git-send-email-jacopo@jmondi.org>", "References": "<1545324285-16730-1-git-send-email-jacopo@jmondi.org>", "Subject": "[libcamera-devel] [PATCH 1/2] libcamera: Add MediaObject class\n\thierarchy", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.23", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "X-List-Received-Date": "Thu, 20 Dec 2018 16:45:06 -0000" }, "content": "Add a class hierarcy to represent all media objects a media graph represents.\nAdd a base MediaObject class, which retains the global unique object id,\nand define the derived MediaEntity, MediaLink and MediaPad classes.\n\nThis hierarchy will be used by the MediaDevice objects which represents and\nhandles the media graph.\n\nSigned-off-by: Jacopo Mondi <jacopo@jmondi.org>\n---\n src/libcamera/include/media_object.h | 120 ++++++++++++++\n src/libcamera/media_object.cpp | 302 +++++++++++++++++++++++++++++++++++\n src/libcamera/meson.build | 1 +\n 3 files changed, 423 insertions(+)\n create mode 100644 src/libcamera/include/media_object.h\n create mode 100644 src/libcamera/media_object.cpp", "diff": "diff --git a/src/libcamera/include/media_object.h b/src/libcamera/include/media_object.h\nnew file mode 100644\nindex 0000000..bbacb05\n--- /dev/null\n+++ b/src/libcamera/include/media_object.h\n@@ -0,0 +1,120 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2018, Google Inc.\n+ *\n+ * media_object.h - Media Device objects: entities, pads and links.\n+ */\n+#ifndef __LIBCAMERA_MEDIA_OBJECT_H__\n+#define __LIBCAMERA_MEDIA_OBJECT_H__\n+\n+#include <functional>\n+#include <string>\n+#include <sstream>\n+#include <vector>\n+\n+#include <linux/media.h>\n+\n+namespace libcamera {\n+\n+class MediaDevice;\n+class MediaEntity;\n+\n+class MediaObject\n+{\n+public:\n+\tMediaObject(unsigned int id) : id_(id) { }\n+\tvirtual ~MediaObject() { }\n+\n+\tunsigned int id() { return id_; }\n+\n+protected:\n+\tunsigned int id_;\n+};\n+\n+class MediaLink : public MediaObject\n+{\n+\tfriend class MediaDevice;\n+\n+public:\n+\t~MediaLink() { }\n+\n+\tunsigned int source() { return source_; }\n+\tunsigned int sink() { return sink_; }\n+\tunsigned int flags() { return flags_; }\n+\tvoid setFlags(unsigned int flags) { flags_ = flags; }\n+\n+private:\n+\tMediaLink(const struct media_v2_link *link);\n+\tMediaLink(const MediaLink &) = delete;\n+\n+\tunsigned int source_;\n+\tunsigned int sink_;\n+\tunsigned int flags_;\n+};\n+\n+class MediaPad : public MediaObject\n+{\n+\tfriend class MediaDevice;\n+\n+public:\n+\t~MediaPad();\n+\n+\tunsigned int index() { return index_; }\n+\tunsigned int entity() { return entity_; }\n+\tunsigned int flags() { return flags_; }\n+\tstd::vector<MediaLink *> &links() { return links_; }\n+\n+\tvoid addLink(MediaLink *link);\n+\n+private:\n+\tMediaPad(const struct media_v2_pad *pad);\n+\tMediaPad(const MediaPad &) = delete;\n+\n+\tunsigned int index_;\n+\tunsigned int entity_;\n+\tunsigned int flags_;\n+\n+\tstd::vector<MediaLink *> links_;\n+};\n+\n+class MediaEntity : public MediaObject\n+{\n+\tfriend class MediaDevice;\n+\n+public:\n+\tbool operator==(unsigned int id) const { return this->id_ == id; }\n+\tbool operator!=(unsigned int id) const { return this->id_ != id; }\n+\tbool operator==(std::string name) const\n+\t{\n+\t\treturn !name_.compare(name);\n+\t}\n+\n+\tstd::string name() { return name_; }\n+\tstd::vector<MediaPad *> &sources() { return sources_; }\n+\tstd::vector<MediaPad *> &sinks() { return sinks_; }\n+\n+\tMediaPad *getPadByIndex(unsigned int index);\n+\tMediaPad *getPadById(unsigned int id);\n+\n+private:\n+\tMediaEntity(const struct media_v2_entity *entity);\n+\tMediaEntity(const MediaEntity &) = delete;\n+\t~MediaEntity();\n+\n+\tstd::string name_;\n+\tstd::string path_;\n+\n+\tstd::vector<MediaPad *> sources_;\n+\tstd::vector<MediaPad *> sinks_;\n+\n+\tint setDevice(const std::string &path);\n+\n+\tvoid addPad(MediaPad *pad);\n+\n+\tMediaPad *__getPad(std::vector<MediaPad *> &v,\n+\t\t\t std::function<bool(MediaPad *)> f);\n+\tMediaPad *getPad(std::function<bool(MediaPad *)> f);\n+};\n+\n+} /* namespace libcamera */\n+#endif /* __LIBCAMERA_MEDIA_OBJECT_H__ */\ndiff --git a/src/libcamera/media_object.cpp b/src/libcamera/media_object.cpp\nnew file mode 100644\nindex 0000000..740a5fb\n--- /dev/null\n+++ b/src/libcamera/media_object.cpp\n@@ -0,0 +1,302 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2018, Google Inc.\n+ *\n+ * media_object.cpp - Media device objects: entities, pads and links\n+ */\n+\n+#include <errno.h>\n+#include <fcntl.h>\n+#include <string.h>\n+#include <sys/stat.h>\n+\n+#include <functional>\n+#include <string>\n+#include <vector>\n+\n+#include <linux/media.h>\n+\n+#include \"log.h\"\n+#include \"media_object.h\"\n+\n+/**\n+ * \\file media_object.h\n+ */\n+namespace libcamera {\n+\n+/**\n+ * \\class MediaObject\n+ * \\brief Base class for all media object types\n+ *\n+ * Defines a simple base class for all media objects with a simple\n+ * unique id.\n+ */\n+\n+/**\n+ * \\fn MediaObject::MediaObject(unsigned int id)\n+ * \\brief Construct a MediaObject with id \\a id\n+ * \\param id The globally unique object's id as returned by MEDIA_IOC_G_TOPOLOGY\n+ */\n+\n+/**\n+ * \\fn MediaObject::id()\n+ * \\brief Return the object's globally unique id /ref id_\n+ */\n+\n+/**\n+ * \\var MediaObject::id_\n+ * \\brief The MediaObject unique id as returned by MEDIA_IOC_G_TOPOLOGY\n+ */\n+\n+/**\n+ * \\class MediaLink\n+ * \\brief A Media Link object\n+ *\n+ * A MediaLink object represents a media link between two entities\n+ */\n+\n+/**\n+ * \\fn MediaLink::MediaLink(const struct media_v2_link *link)\n+ * \\brief Construct a MediaLink with informations from \\a link\n+ * \\param link The media link representation as returned by\n+ *\t MEDIA_IOC_G_TOPOLOGY\n+ */\n+MediaLink::MediaLink(const struct media_v2_link *link) : MediaObject(link->id),\n+\t\t\t\t\t\t\t source_(link->source_id),\n+\t\t\t\t\t\t\t sink_(link->sink_id),\n+\t\t\t\t\t\t\t flags_(link->flags) { }\n+/**\n+ * \\fn MediaLink::source()\n+ * \\brief Return the source pad id\n+ */\n+\n+/**\n+ * \\fn MediaLink::sink()\n+ * \\brief Return the sink pad id\n+ */\n+\n+/**\n+ * \\fn MediaLink::flags()\n+ * \\brief Return the link flags\n+ */\n+\n+/**\n+ * \\fn MediaLink::setFlags(unsigned int flags)\n+ * \\brief Set the link flags to \\a flags\n+ * \\param flags The flags to be applied to the link\n+ */\n+\n+/**\n+ * \\class MediaPad\n+ * \\brief Media Pad object\n+ *\n+ * A MediaPad object represents a media pad with its associated links\n+ */\n+\n+/**\n+ * \\fn MediaPad::MediaPad(const struct media_v2_pad *pad)\n+ * \\brief Create a MediaPad object\n+ * \\param mediaPad The media pad representation as returned by\n+ *\t\t MEDIA_IOC_G_TOPOLOGY\n+ */\n+MediaPad::MediaPad(const struct media_v2_pad *pad) : MediaObject(pad->id),\n+\t\t\t\t\t\t index_(pad->index),\n+\t\t\t\t\t\t entity_(pad->entity_id),\n+\t\t\t\t\t\t flags_(pad->flags) { }\n+MediaPad::~MediaPad()\n+{\n+\tlinks_.clear();\n+}\n+\n+/**\n+ * \\fn MediaPad::index()\n+ * \\brief Return the 0-indexed pad index\n+ */\n+\n+/**\n+ * \\fn MediaPad::entity()\n+ * \\brief Return the entity id this pad belongs to\n+ */\n+\n+/**\n+ * \\fn MediaPad::flags()\n+ * \\brief Return the pad flags (MEDIA_PAD_FL_*)\n+ */\n+\n+/**\n+ * \\fn MediaPad::links()\n+ * \\brief Return all outbound and inbound links from/to this pad\n+ */\n+\n+/**\n+ * \\fn MediaPad::addLink(MediaLink *link)\n+ * \\brief Add a new outbound or inbound link from/to this pad\n+ * \\param link The new link to add\n+ */\n+void MediaPad::addLink(MediaLink *link)\n+{\n+\tlinks_.push_back(link);\n+}\n+\n+/**\n+ * \\class MediaEntity\n+ * \\brief Media entity object\n+ *\n+ * A MediaEntity object represents a media entity with its id, name and its\n+ * associated pads\n+ */\n+\n+/**\n+ * \\fn MediaEntity::operator==(unsigned int id) const\n+ * \\brief Compare entities by id (check if they're equal)\n+ * \\param id The entity id to compare with\n+ */\n+\n+/**\n+ * \\fn MediaEntity::operator!=(unsigned int id) const\n+ * \\brief Compare entities by id (check if they're not equal)\n+ * \\param id The entity id to compare with\n+ */\n+\n+/**\n+ * \\fn MediaEntity::operator==(std::string name) const\n+ * \\brief Compare entities by name (check if they're equal)\n+ * \\param name The entity name to compare with\n+ */\n+\n+/**\n+ * \\fn MediaEntity::name()\n+ * \\brief Return the entity name\n+ */\n+\n+/**\n+ * \\fn MediaEntity::sources()\n+ * \\brief Get all source pads\n+ */\n+\n+/**\n+ * \\fn MediaEntity::sinks()\n+ * \\brief Get all sink pads\n+ */\n+\n+/**\n+ * \\fn MediaEntity::getPadByIndex(unsigned int index)\n+ * \\brief Get a pad in this entity by its index\n+ * \\param index The pad index (starting from 0)\n+ */\n+MediaPad *MediaEntity::getPadByIndex(unsigned int index)\n+{\n+\treturn getPad([&index](MediaPad *p) -> bool { return p->index() == index; });\n+}\n+\n+/**\n+ * \\fn MediaEntity::getPadById(unsigned int id)\n+ * \\brief Get a pad in this entity by its id\n+ * \\param id The pad globally unique id\n+ */\n+MediaPad *MediaEntity::getPadById(unsigned int id)\n+{\n+\treturn getPad([&id](MediaPad *p) -> bool { return p->id() == id; });\n+}\n+\n+/**\n+ * \\fn MediaEntity::MediaEntity(const struct media_v2_entity *entity)\n+ * \\brief Construct a MediaEntity with informations from \\a entity\n+ * \\param entity The media entity representation as returned by\n+ *\t\t MEDIA_IOC_G_TOPOLOGY\n+ */\n+MediaEntity::MediaEntity(const struct media_v2_entity *entity) :\n+\t\t\t\t\t\t\tMediaObject(entity->id),\n+\t\t\t\t\t\t\tname_(entity->name) { }\n+\n+/**\n+ * \\fn MediaEntity::~MediaEntity()\n+ * \\brief Release memory for all pads and links\n+ */\n+MediaEntity::~MediaEntity()\n+{\n+\tfor (MediaPad *s : sources_)\n+\t\tdelete s;\n+\tfor (MediaPad *s : sinks_)\n+\t\tdelete s;\n+\n+\tsources_.clear();\n+\tsinks_.clear();\n+}\n+\n+/**\n+ * \\var MediaEntity::sources_\n+ * \\brief The MediaPad sources vector\n+ */\n+\n+/**\n+ * \\var MediaEntity::sinks_\n+ * \\brief The MediaPad sinks vector\n+ */\n+\n+/**\n+ * \\fn MediaEntity::setDevice(const std::string &path)\n+ * \\brief Set the entity video (sub)device node path\n+ * \\param path The video (sub)device node path associated with this entity\n+ */\n+int MediaEntity::setDevice(const std::string &path)\n+{\n+\t/* Make sure the path exists first. */\n+\tstruct stat pstat;\n+\tint ret = ::stat(const_cast<const char *>(path.c_str()), &pstat);\n+\tif (ret < 0) {\n+\t\tLOG(Error) << \"Unable to open: \" << path << \" : \"\n+\t\t\t << strerror(errno);\n+\t\treturn -errno;\n+\t}\n+\n+\tpath_ = path;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * \\fn MediaEntity::addPad(MediaPad *pad)\n+ * \\brief Add pad \\a pad to \\ref sources_ or \\ref sinks_\n+ * \\param pad The pad to add\n+ */\n+void MediaEntity::addPad(MediaPad *pad)\n+{\n+\tstd::vector<MediaPad *> *pads =\n+\t\t\t\t pad->flags() & MEDIA_PAD_FL_SOURCE ?\n+\t\t\t\t &sources_ : &sinks_;\n+\tpads->push_back(pad);\n+}\n+\n+/**\n+ * \\fn MediaEntity::__getPad(std::vector<MediaPad *> &v,\n+ *\t\t\t std::function<bool(MediaPad *)> f)\n+ * \\brief Find MediaPad the satisfies predicates \\a f in the pad vector \\v\n+ * \\param v The std::vector<MediaPad *> to search in\n+ * \\param f The predicate the pad has to satisfy\n+ */\n+MediaPad *MediaEntity::__getPad(std::vector<MediaPad *> &v,\n+\t\t\t\tstd::function<bool(MediaPad *)> f)\n+{\n+\tstd::vector<MediaPad *>::iterator it = v.begin();\n+\twhile (it != sources_.end()) {\n+\t\tif (f(*it))\n+\t\t\treturn *it;\n+\t\t++it;\n+\t}\n+\n+\treturn nullptr;\n+}\n+\n+/**\n+ * \\fn MediaEntity::getPad(std::function<bool(MediaPad *)> f)\n+ * \\brief Run predicate \\a f on both \\ref sources_ and \\ref sinks_\n+ * \\param f The predicate the pad has to satisfy\n+ */\n+MediaPad *MediaEntity::getPad(std::function<bool(MediaPad *)> f)\n+{\n+\tMediaPad *_p = __getPad(sources_, f);\n+\treturn (_p != nullptr ? _p : __getPad(sinks_, f));\n+}\n+\n+} /* namespace libcamera */\ndiff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\nindex f632eb5..da06eba 100644\n--- a/src/libcamera/meson.build\n+++ b/src/libcamera/meson.build\n@@ -1,6 +1,7 @@\n libcamera_sources = files([\n 'log.cpp',\n 'main.cpp',\n+ 'media_object.cpp',\n ])\n \n libcamera_headers = files([\n", "prefixes": [ "libcamera-devel", "1/2" ] }