[libcamera-devel] [PATCH v4 3/9] libcamera: media_device: Handle ancillary links in populateLinks()
Daniel Scally
djrscally at gmail.com
Mon Jan 31 23:33:24 CET 2022
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.
Signed-off-by: Daniel Scally <djrscally at gmail.com>
---
Changes in v4:
- Added some error checking to confirm that the casts to pad or entity
return valid pointers (Laurent)
Changes in v3:
- Split out the new macro
- Fixed some style errors and comments
- Added a default case
src/libcamera/media_device.cpp | 67 ++++++++++++++++++++++++++--------
1 file changed, 51 insertions(+), 16 deletions(-)
diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp
index 941f86c2..a008383a 100644
--- a/src/libcamera/media_device.cpp
+++ b/src/libcamera/media_device.cpp
@@ -683,40 +683,75 @@ 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)
+ /*
+ * Skip links between entities and interfaces: interfaces are
+ * not created as MediaObjects at this time, so the source and
+ * sink pointers would never be found.
+ */
+ 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;
+ }
+ 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";
- source->addLink(link);
- sink->addLink(link);
+ break;
+ }
}
return true;
--
2.25.1
More information about the libcamera-devel
mailing list