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 <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Scally <djrscally@gmail.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Daniel Scally 2022-03-03 23:49:50 +00:00 committed by Kieran Bingham
parent ccc28b8b30
commit 2cde99032f

View file

@ -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<MediaPad *>
(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<MediaPad *>
(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<MediaPad *>(source);
MediaPad *sinkPad = dynamic_cast<MediaPad *>(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<MediaEntity *>(source);
MediaEntity *ancillary = dynamic_cast<MediaEntity *>(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;