[libcamera-devel] [PATCH v3] libcamera: media_device: Fallback to legacy ioctls on older kernels
Kieran Bingham
kieran.bingham at ideasonboard.com
Sat Jan 26 08:46:17 CET 2019
Hi Laurent,
Thank you for looking into this issue,
On 25/01/2019 23:09, Laurent Pinchart wrote:
> Prior to kernel v4.19, the MEDIA_IOC_G_TOPOLOGY ioctl didn't expose
> entity flags. Fallback to calling MEDIA_IOC_ENUM_ENTITIES for each
> entity to retrieve the flags in that case.
>
This does indeed fix my issue.
Tested-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
Is a 'fixes' tag appropriate here? Perhaps not, because it's not so much
a bug in the original code, as a missing feature.
Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
Please push this as soon as you're ready.
Thanks.
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> Reviewed-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> ---
> Changes since v1:
>
> - Move MEDIA_V2_ENTITY_HAS_FLAGS() test to populateEntities()
> - Rename fixupEntity() to fixupEntityFlag()
> ---
> src/libcamera/include/media_device.h | 3 ++
> src/libcamera/media_device.cpp | 41 ++++++++++++++++++++++++++--
> 2 files changed, 41 insertions(+), 3 deletions(-)
>
> diff --git a/src/libcamera/include/media_device.h b/src/libcamera/include/media_device.h
> index 27a2b46a4392..9f038093b2b2 100644
> --- a/src/libcamera/include/media_device.h
> +++ b/src/libcamera/include/media_device.h
> @@ -56,6 +56,8 @@ private:
> std::string driver_;
> std::string deviceNode_;
> std::string model_;
> + unsigned int version_;
> +
> int fd_;
> bool valid_;
> bool acquired_;
> @@ -72,6 +74,7 @@ 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);
> + void fixupEntityFlags(struct media_v2_entity *entity);
>
> friend int MediaLink::setEnabled(bool enable);
> int setupLink(const MediaLink *link, unsigned int flags);
> diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp
> index be81bd8c4c23..a4995b996601 100644
> --- a/src/libcamera/media_device.cpp
> +++ b/src/libcamera/media_device.cpp
> @@ -167,6 +167,7 @@ int MediaDevice::open()
>
> driver_ = info.driver;
> model_ = info.model;
> + version_ = info.media_version;
>
> return 0;
> }
> @@ -553,20 +554,29 @@ bool MediaDevice::populateEntities(const struct media_v2_topology &topology)
> (topology.ptr_entities);
>
> for (unsigned int i = 0; i < topology.num_entities; ++i) {
> + struct media_v2_entity *ent = &mediaEntities[i];
> +
> + /*
> + * The media_v2_entity structure was missing the flag field before
> + * v4.19.
> + */
> + if (!MEDIA_V2_ENTITY_HAS_FLAGS(version_))
> + fixupEntityFlags(ent);
> +
> /*
> * Find the interface linked to this entity to get the device
> * node major and minor numbers.
> */
> struct media_v2_interface *iface =
> - findInterface(topology, mediaEntities[i].id);
> + findInterface(topology, ent->id);
>
> MediaEntity *entity;
> if (iface)
> - entity = new MediaEntity(this, &mediaEntities[i],
> + entity = new MediaEntity(this, ent,
> iface->devnode.major,
> iface->devnode.minor);
> else
> - entity = new MediaEntity(this, &mediaEntities[i]);
> + entity = new MediaEntity(this, ent);
>
> if (!addObject(entity)) {
> delete entity;
> @@ -657,6 +667,31 @@ bool MediaDevice::populateLinks(const struct media_v2_topology &topology)
> return true;
> }
>
> +/**
> + * \brief Fixup entity flags using legacy API
(Very) minor nit :
s/using legacy/using the legacy/
> + * \param[in] entity The entity
> + *
> + * This function is used as a fallback to query entity flags using the legacy
> + * MEDIA_IOC_ENUM_ENTITIES ioctl when running on a kernel version that doesn't
> + * provide them through the MEDIA_IOC_G_TOPOLOGY ioctl.
> + */
> +void MediaDevice::fixupEntityFlags(struct media_v2_entity *entity)
> +{
> + struct media_entity_desc desc = {};
> + desc.id = entity->id;
> +
> + int ret = ioctl(fd_, MEDIA_IOC_ENUM_ENTITIES, &desc);
> + if (ret < 0) {
> + ret = -errno;
> + LOG(MediaDevice, Debug)
> + << "Failed to retrieve information for entity "
> + << entity->id << ": " << strerror(-ret);
> + return;
> + }
> +
> + entity->flags = desc.flags;
> +}
> +
> /**
> * \brief Apply \a flags to a link between two pads
> * \param link The link to apply flags to
>
--
Regards
--
Kieran
More information about the libcamera-devel
mailing list