From patchwork Wed Aug 20 13:23:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Scally X-Patchwork-Id: 24166 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id CFA32BD87C for ; Wed, 20 Aug 2025 13:23:44 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5D0C6692E5; Wed, 20 Aug 2025 15:23:40 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="sCBZBU9m"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 048BF6142C for ; Wed, 20 Aug 2025 15:23:37 +0200 (CEST) Received: from mail.ideasonboard.com (cpc141996-chfd3-2-0-cust928.12-3.cable.virginm.net [86.13.91.161]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3FA24B0B; Wed, 20 Aug 2025 15:22:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1755696158; bh=QsJiDoh1KBHgRuOEwcExXG5glWOhBMzyXXI5IhXstns=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sCBZBU9mF5Rvx+8vbO10mWj8rIghQ/lI9zH/oM11XrpCDabMnmNlT0QZ6SIMwksMO BHhpl9YwXpAvQ6AXnWLrsvK4Z9nL+FRp5gXGejUuqnqsFVkGQ1qKdg4WYHVRG6Ibj5 0bzYHWwFWkvT/7A0Gb/ZkH2yE/gmNuYB0h0IvrHs= From: Daniel Scally To: libcamera-devel@lists.libcamera.org Cc: dan.scally@ideasonboard.com Subject: [PATCH 1/3] libcamera: media_device: Expand return values for populateEntities() Date: Wed, 20 Aug 2025 14:23:14 +0100 Message-ID: <20250820132316.1033443-2-dan.scally@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250820132316.1033443-1-dan.scally@ideasonboard.com> References: <20250820132316.1033443-1-dan.scally@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" At the moment populateEntities() just returns true or false to indicate success or failure. Although the populate() function assumes that the topology is settled once the version number stops incrementing, that's not guaranteed to be the case. One indicator that it's likely to increase again in the future is the absence of interfaces for an entity, which would only be created for V4L2 subdevices once the v4l2-async framework had run to completion. Update populateEntities() to return -EAGAIN in the event an entity has no associated interface yet and pass that error out from populate to indicate to callers that they should re-try the population at a later time. Signed-off-by: Daniel Scally --- include/libcamera/internal/media_device.h | 2 +- src/libcamera/media_device.cpp | 27 ++++++++++++++--------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/include/libcamera/internal/media_device.h b/include/libcamera/internal/media_device.h index b3a48b98d..d3c5eaa02 100644 --- a/include/libcamera/internal/media_device.h +++ b/include/libcamera/internal/media_device.h @@ -70,7 +70,7 @@ private: struct media_v2_interface *findInterface(const struct media_v2_topology &topology, unsigned int entityId); - bool populateEntities(const struct media_v2_topology &topology); + int populateEntities(const struct media_v2_topology &topology); bool populatePads(const struct media_v2_topology &topology); bool populateLinks(const struct media_v2_topology &topology); void fixupEntityFlags(struct media_v2_entity *entity); diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp index 353f34a81..6d58f09eb 100644 --- a/src/libcamera/media_device.cpp +++ b/src/libcamera/media_device.cpp @@ -257,12 +257,13 @@ int MediaDevice::populate() } /* Populate entities, pads and links. */ - if (populateEntities(topology) && - populatePads(topology) && - populateLinks(topology)) - valid_ = true; + if (!(ret = populateEntities(topology))) { + if (populatePads(topology) && populateLinks(topology)) + valid_ = true; + else + ret = -EINVAL; + } - ret = 0; done: close(); @@ -271,10 +272,8 @@ done: delete[] pads; delete[] links; - if (!valid_) { + if (!valid_) clear(); - return -EINVAL; - } return ret; } @@ -618,7 +617,7 @@ struct media_v2_interface *MediaDevice::findInterface(const struct media_v2_topo * For each entity in the media graph create a MediaEntity and store a * reference in the media device objects map and entities list. */ -bool MediaDevice::populateEntities(const struct media_v2_topology &topology) +int MediaDevice::populateEntities(const struct media_v2_topology &topology) { struct media_v2_entity *mediaEntities = reinterpret_cast (topology.ptr_entities); @@ -639,17 +638,23 @@ bool MediaDevice::populateEntities(const struct media_v2_topology &topology) */ struct media_v2_interface *iface = findInterface(topology, ent->id); + if (!iface) { + LOG(MediaDevice, Debug) + << "Entity " << ent->name << " has no interface yet"; + return -EAGAIN; + } + MediaEntity *entity = new MediaEntity(this, ent, iface); if (!addObject(entity)) { delete entity; - return false; + return -EINVAL; } entities_.push_back(entity); } - return true; + return 0; } bool MediaDevice::populatePads(const struct media_v2_topology &topology)