summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Scally <djrscally@gmail.com>2022-03-03 23:49:50 +0000
committerKieran Bingham <kieran.bingham@ideasonboard.com>2022-03-15 17:20:59 +0000
commit2cde99032f2495c0d38c38c5e826320d0e9823eb (patch)
treedc9ec86773daf4b996fd61e0ddf6d4a1cf0fed0e
parentccc28b8b30e57c5f1ebaa1b7bf79a61910b4e139 (diff)
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>
-rw-r--r--src/libcamera/media_device.cpp64
1 files changed, 48 insertions, 16 deletions
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<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;