libcamera: media_device: Fallback to legacy ioctls on older kernels
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.
Fixes: 67d313240c
("libcamera: pipeline: uvcvideo: create a V4L2Device for the default video entity")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
ac0a3d7fb6
commit
e4d2dcc549
2 changed files with 41 additions and 3 deletions
|
@ -56,6 +56,8 @@ private:
|
||||||
std::string driver_;
|
std::string driver_;
|
||||||
std::string deviceNode_;
|
std::string deviceNode_;
|
||||||
std::string model_;
|
std::string model_;
|
||||||
|
unsigned int version_;
|
||||||
|
|
||||||
int fd_;
|
int fd_;
|
||||||
bool valid_;
|
bool valid_;
|
||||||
bool acquired_;
|
bool acquired_;
|
||||||
|
@ -72,6 +74,7 @@ private:
|
||||||
bool populateEntities(const struct media_v2_topology &topology);
|
bool populateEntities(const struct media_v2_topology &topology);
|
||||||
bool populatePads(const struct media_v2_topology &topology);
|
bool populatePads(const struct media_v2_topology &topology);
|
||||||
bool populateLinks(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);
|
friend int MediaLink::setEnabled(bool enable);
|
||||||
int setupLink(const MediaLink *link, unsigned int flags);
|
int setupLink(const MediaLink *link, unsigned int flags);
|
||||||
|
|
|
@ -167,6 +167,7 @@ int MediaDevice::open()
|
||||||
|
|
||||||
driver_ = info.driver;
|
driver_ = info.driver;
|
||||||
model_ = info.model;
|
model_ = info.model;
|
||||||
|
version_ = info.media_version;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -553,20 +554,29 @@ bool MediaDevice::populateEntities(const struct media_v2_topology &topology)
|
||||||
(topology.ptr_entities);
|
(topology.ptr_entities);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < topology.num_entities; ++i) {
|
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
|
* Find the interface linked to this entity to get the device
|
||||||
* node major and minor numbers.
|
* node major and minor numbers.
|
||||||
*/
|
*/
|
||||||
struct media_v2_interface *iface =
|
struct media_v2_interface *iface =
|
||||||
findInterface(topology, mediaEntities[i].id);
|
findInterface(topology, ent->id);
|
||||||
|
|
||||||
MediaEntity *entity;
|
MediaEntity *entity;
|
||||||
if (iface)
|
if (iface)
|
||||||
entity = new MediaEntity(this, &mediaEntities[i],
|
entity = new MediaEntity(this, ent,
|
||||||
iface->devnode.major,
|
iface->devnode.major,
|
||||||
iface->devnode.minor);
|
iface->devnode.minor);
|
||||||
else
|
else
|
||||||
entity = new MediaEntity(this, &mediaEntities[i]);
|
entity = new MediaEntity(this, ent);
|
||||||
|
|
||||||
if (!addObject(entity)) {
|
if (!addObject(entity)) {
|
||||||
delete entity;
|
delete entity;
|
||||||
|
@ -657,6 +667,31 @@ bool MediaDevice::populateLinks(const struct media_v2_topology &topology)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Fixup entity flags using the legacy API
|
||||||
|
* \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
|
* \brief Apply \a flags to a link between two pads
|
||||||
* \param link The link to apply flags to
|
* \param link The link to apply flags to
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue