From 2cde99032f2495c0d38c38c5e826320d0e9823eb Mon Sep 17 00:00:00 2001 From: Daniel Scally Date: Thu, 3 Mar 2022 23:49:50 +0000 Subject: libcamera: media_device: Handle ancillary links in populateLinks() The populateLinks() function can't currently handle ancillary links which causes an error to be thrown in process() when the MediaObject cannot be cast to a MediaPad. Add explicit handling for the different link types, creating either pad-2-pad links or else storing the pointer to the ancillary device MediaEntity in the ancillaryEntities_ member of the primary. Reviewed-by: Laurent Pinchart Signed-off-by: Daniel Scally Reviewed-by: Jean-Michel Hautbois Signed-off-by: Kieran Bingham --- src/libcamera/media_device.cpp | 64 +++++++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 16 deletions(-) (limited to 'src/libcamera/media_device.cpp') diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp index 941f86c2..7c94da9e 100644 --- a/src/libcamera/media_device.cpp +++ b/src/libcamera/media_device.cpp @@ -683,40 +683,72 @@ bool MediaDevice::populateLinks(const struct media_v2_topology &topology) (topology.ptr_links); for (unsigned int i = 0; i < topology.num_links; ++i) { - /* We only care about pad-2-pad links here. */ - if ((mediaLinks[i].flags & MEDIA_LNK_FL_LINK_TYPE) != - MEDIA_LNK_FL_DATA_LINK) + if ((mediaLinks[i].flags & MEDIA_LNK_FL_LINK_TYPE) == + MEDIA_LNK_FL_INTERFACE_LINK) continue; - /* Store references to source and sink pads in the link. */ + /* Look up the source and sink objects. */ unsigned int source_id = mediaLinks[i].source_id; - MediaPad *source = dynamic_cast - (object(source_id)); + MediaObject *source = object(source_id); if (!source) { LOG(MediaDevice, Error) - << "Failed to find pad with id: " + << "Failed to find MediaObject with id " << source_id; return false; } unsigned int sink_id = mediaLinks[i].sink_id; - MediaPad *sink = dynamic_cast - (object(sink_id)); + MediaObject *sink = object(sink_id); if (!sink) { LOG(MediaDevice, Error) - << "Failed to find pad with id: " + << "Failed to find MediaObject with id " << sink_id; return false; } - MediaLink *link = new MediaLink(&mediaLinks[i], source, sink); - if (!addObject(link)) { - delete link; - return false; + switch (mediaLinks[i].flags & MEDIA_LNK_FL_LINK_TYPE) { + case MEDIA_LNK_FL_DATA_LINK: { + MediaPad *sourcePad = dynamic_cast(source); + MediaPad *sinkPad = dynamic_cast(sink); + if (!source || !sink) { + LOG(MediaDevice, Error) + << "Source or sink is not a pad"; + return false; + } + + MediaLink *link = new MediaLink(&mediaLinks[i], + sourcePad, sinkPad); + if (!addObject(link)) { + delete link; + return false; + } + + link->source()->addLink(link); + link->sink()->addLink(link); + + break; } - source->addLink(link); - sink->addLink(link); + case MEDIA_LNK_FL_ANCILLARY_LINK: { + MediaEntity *primary = dynamic_cast(source); + MediaEntity *ancillary = dynamic_cast(sink); + if (!primary || !ancillary) { + LOG(MediaDevice, Error) + << "Source or sink is not an entity"; + return false; + } + + primary->addAncillaryEntity(ancillary); + + break; + } + + default: + LOG(MediaDevice, Warning) + << "Unknown media link type"; + + break; + } } return true; -- cgit v1.2.1