diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libcamera/include/media_object.h | 106 | ||||
-rw-r--r-- | src/libcamera/media_object.cpp | 282 | ||||
-rw-r--r-- | src/libcamera/meson.build | 2 |
3 files changed, 390 insertions, 0 deletions
diff --git a/src/libcamera/include/media_object.h b/src/libcamera/include/media_object.h new file mode 100644 index 00000000..65b55085 --- /dev/null +++ b/src/libcamera/include/media_object.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018, Google Inc. + * + * media_object.h - Media Device objects: entities, pads and links. + */ +#ifndef __LIBCAMERA_MEDIA_OBJECT_H__ +#define __LIBCAMERA_MEDIA_OBJECT_H__ + +#include <string> +#include <vector> + +#include <linux/media.h> + +namespace libcamera { + +class MediaDevice; +class MediaEntity; +class MediaPad; + +class MediaObject +{ +public: + unsigned int id() const { return id_; } + +protected: + friend class MediaDevice; + + MediaObject(unsigned int id) : id_(id) { } + virtual ~MediaObject() { } + + unsigned int id_; +}; + +class MediaLink : public MediaObject +{ +public: + MediaPad *source() const { return source_; } + MediaPad *sink() const { return sink_; } + unsigned int flags() const { return flags_; } + +private: + friend class MediaDevice; + + MediaLink(const struct media_v2_link *link, + MediaPad *source, MediaPad *sink); + MediaLink(const MediaLink &) = delete; + ~MediaLink() { } + + MediaPad *source_; + MediaPad *sink_; + unsigned int flags_; +}; + +class MediaPad : public MediaObject +{ +public: + unsigned int index() const { return index_; } + MediaEntity *entity() const { return entity_; } + unsigned int flags() const { return flags_; } + const std::vector<MediaLink *> &links() const { return links_; } + + void addLink(MediaLink *link); + +private: + friend class MediaDevice; + + MediaPad(const struct media_v2_pad *pad, MediaEntity *entity); + MediaPad(const MediaPad &) = delete; + ~MediaPad(); + + unsigned int index_; + MediaEntity *entity_; + unsigned int flags_; + + std::vector<MediaLink *> links_; +}; + +class MediaEntity : public MediaObject +{ +public: + const std::string &name() const { return name_; } + + const std::vector<MediaPad *> &pads() const { return pads_; } + + const MediaPad *getPadByIndex(unsigned int index) const; + const MediaPad *getPadById(unsigned int id) const; + +private: + friend class MediaDevice; + + MediaEntity(const struct media_v2_entity *entity); + MediaEntity(const MediaEntity &) = delete; + ~MediaEntity(); + + std::string name_; + std::string devnode_; + + std::vector<MediaPad *> pads_; + + void addPad(MediaPad *pad); +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_MEDIA_OBJECT_H__ */ diff --git a/src/libcamera/media_object.cpp b/src/libcamera/media_object.cpp new file mode 100644 index 00000000..b64dcc3c --- /dev/null +++ b/src/libcamera/media_object.cpp @@ -0,0 +1,282 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018, Google Inc. + * + * media_object.cpp - Media device objects: entities, pads and links + */ + +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <sys/stat.h> + +#include <string> +#include <vector> + +#include <linux/media.h> + +#include "log.h" +#include "media_object.h" + +/** + * \file media_object.h + * \brief Provides a class hierarchy that represents the media objects exposed + * by the Linux kernel Media Controller APIs. + * + * The abstract MediaObject class represents any Media Controller graph object + * identified by an id unique in the media device context. It is subclassed by + * the MediaEntity, MediaPad and MediaLink classes that represent the entities, + * pads and links respectively. They are populated based on the media graph + * information exposed by the Linux kernel through the MEDIA_IOC_G_TOPOLOGY + * ioctl. + * + * As the media objects represent their kernel counterpart, information about + * the properties they expose can be found in the Linux kernel documentation. + * + * All media objects are meant to be created and destroyed solely by the + * MediaDevice and thus have private constructors and destructors. + */ + +namespace libcamera { + +/** + * \class MediaObject + * \brief Base class for all media objects + * + * MediaObject is an abstract base class for all media objects in the media + * graph. Every media graph object is identified by an id unique in the media + * device context, and this base class provides that. + * + * \sa MediaEntity, MediaPad, MediaLink + */ + +/** + * \fn MediaObject::MediaObject() + * \brief Construct a MediaObject with \a id + * \param id The media object id + * + * The caller shall ensure unicity of the object id in the media device context. + * This constraint is neither enforced nor checked by the MediaObject. + */ + +/** + * \fn MediaObject::id() + * \brief Retrieve the media object id + * \return The media object id + */ + +/** + * \var MediaObject::id_ + * \brief The media object id + */ + +/** + * \class MediaLink + * \brief The MediaLink represents a link between two pads in the media graph. + * + * Links are created from the information provided by the Media Controller API + * in the media_v2_link structure. They reference the source() and sink() pads + * they connect and track the link status through link flags(). + * + * Each link is referenced in the link array of both of the pads it connect. + */ + +/** + * \brief Construct a MediaLink + * \param link The media link kernel data + * \param source The source pad at the origin of the link + * \param sink The sink pad at the destination of the link + */ +MediaLink::MediaLink(const struct media_v2_link *link, MediaPad *source, + MediaPad *sink) + : MediaObject(link->id), source_(source), + sink_(sink), flags_(link->flags) +{ +} + +/** + * \fn MediaLink::source() + * \brief Retrieve the link's source pad + * \return The source pad at the origin of the link + */ + +/** + * \fn MediaLink::sink() + * \brief Retrieve the link's sink pad + * \return The sink pad at the destination of the link + */ + +/** + * \fn MediaLink::flags() + * \brief Retrieve the link's flags + * + * Link flags are a bitmask of flags defined by the Media Controller API + * MEDIA_LNK_FL_* macros. + * + * \return The link flags + */ + +/** + * \class MediaPad + * \brief The MediaPad represents a pad of an entity in the media graph + * + * Pads are created from the information provided by the Media Controller API + * in the media_v2_pad structure. They reference the entity() they belong to. + * + * In addition to its graph id, every media graph pad is identified by an index + * unique in the context of the entity the pad belongs to. + * + * A pad can be either a 'source' pad or a 'sink' pad. This information is + * captured in the pad flags(). + * + * Pads are connected through links. Links originating from a source pad are + * outbound links, and links arriving at a sink pad are inbound links. Pads + * reference all the links() that are connected to them. + */ + +/** + * \brief Construct a MediaPad + * \param pad The media pad kernel data + * \param entity The entity the pad belongs to + */ +MediaPad::MediaPad(const struct media_v2_pad *pad, MediaEntity *entity) + : MediaObject(pad->id), index_(pad->index), entity_(entity), + flags_(pad->flags) +{ +} + +MediaPad::~MediaPad() +{ + /* + * Don't delete the links as we only borrow the reference owned by + * MediaDevice. + */ + links_.clear(); +} + +/** + * \fn MediaPad::index() + * \brief Retrieve the pad index + * \return The 0-based pad index identifying the pad in the context of the + * entity it belongs to + */ + +/** + * \fn MediaPad::entity() + * \brief Retrieve the entity the pad belongs to + * \return The MediaEntity the pad belongs to + */ + +/** + * \fn MediaPad::flags() + * \brief Retrieve the pad flags + * + * Pad flags are a bitmask of flags defined by the Media Controller API + * MEDIA_PAD_FL_* macros. + * + * \return The pad flags + */ + +/** + * \fn MediaPad::links() + * \brief Retrieve all links in the pad + * \return A list of links connected to the pad + */ + +/** + * \brief Add a new link to this pad + * \param link The MediaLink to add + */ +void MediaPad::addLink(MediaLink *link) +{ + links_.push_back(link); +} + +/** + * \class MediaEntity + * \brief The MediaEntity represents an entity in the media graph + * + * Entities are created from the information provided by the Media Controller + * API in the media_v2_entity structure. They reference the pads() they contain. + * + * In addition to its graph id, every media graph entity is identified by a + * name() unique in the media device context. + * + * \todo Add support for associating a devnode to the entity when integrating + * with DeviceEnumerator. + */ + +/** + * \fn MediaEntity::name() + * \brief Retrieve the entity name + * \return The entity name + */ + +/** + * \fn MediaEntity::pads() + * \brief Retrieve all pads of the entity + * \return The list of the entity's pads + */ + +/** + * \brief Get a pad in this entity by its index + * \param index The 0-based pad index + * \return The pad identified by \a index, or nullptr if no such pad exist + */ +const MediaPad *MediaEntity::getPadByIndex(unsigned int index) const +{ + for (MediaPad *p : pads_) { + if (p->index() == index) + return p; + } + + return nullptr; +} + +/** + * \brief Get a pad in this entity by its object id + * \param id The pad id + * \return The pad identified by \a id, or nullptr if no such pad exist + */ +const MediaPad *MediaEntity::getPadById(unsigned int id) const +{ + for (MediaPad *p : pads_) { + if (p->id() == id) + return p; + } + + return nullptr; +} + +/** + * \brief Construct a MediaEntity + * \param entity The media entity kernel data + */ +MediaEntity::MediaEntity(const struct media_v2_entity *entity) + : MediaObject(entity->id), name_(entity->name) +{ +} + +MediaEntity::~MediaEntity() +{ + /* + * Don't delete the pads as we only borrow the reference owned by + * MediaDevice. + */ + pads_.clear(); +} + +/** + * \brief Add \a pad to the entity's list of pads + * \param pad The pad to add to the list + * + * This function is meant to add pads to the entity during parsing of the media + * graph, after the MediaPad objects are constructed and before the MediaDevice + * is made available externally. + */ +void MediaEntity::addPad(MediaPad *pad) +{ + pads_.push_back(pad); +} + +} /* namespace libcamera */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index ac5bba05..2985d40c 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -4,12 +4,14 @@ libcamera_sources = files([ 'device_enumerator.cpp', 'log.cpp', 'main.cpp', + 'media_object.cpp', 'pipeline_handler.cpp', ]) libcamera_headers = files([ 'include/device_enumerator.h', 'include/log.h', + 'include/media_object.h', 'include/pipeline_handler.h', 'include/utils.h', ]) |