From patchwork Thu Aug 5 22:24:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 13237 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 CF089C323B for ; Thu, 5 Aug 2021 22:25:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4D3A16880D; Fri, 6 Aug 2021 00:25:01 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="UPGz/zFT"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B47CA68822 for ; Fri, 6 Aug 2021 00:24:57 +0200 (CEST) Received: from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5BFD7E1A for ; Fri, 6 Aug 2021 00:24:57 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1628202297; bh=qtwKVVw6o3QY11H21TZbG8ItJRpU+4xczObphMxatmc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=UPGz/zFTrZ3+Z+n44zntNRs6Yl8RoLOKrYtXt+SYrh3iyi0HgsqK/8uYbMTHOTCK1 VVsS6gKkBRL0LE1wOIi1YtK2DKz3p5JKNVqDBosRZvn1yt7ApYVCAGRrJJliAFbr6K BhuebcnahO7L7M7dmdgWuPfb10cX0t00eCTpVbsA= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 6 Aug 2021 01:24:32 +0300 Message-Id: <20210805222436.6263-7-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210805222436.6263-1-laurent.pinchart@ideasonboard.com> References: <20210805222436.6263-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 06/10] libcamera: pipeline: simple: Open all video devices at match() time 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" Move opening of video devices at match() time, the same way as subdevs are opened, to make the handling of V4L2 video devices and subdevices more consistent. Signed-off-by: Laurent Pinchart --- src/libcamera/pipeline/simple/simple.cpp | 67 ++++++++++++------------ 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 6b808bfbe6fa..17ef3f43ad41 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -82,14 +82,12 @@ LOG_DEFINE_CATEGORY(SimplePipeline) * handled by this heuristic. * * Once the camera data instances have been created, the match() function - * creates a V4L2Subdevice instance for each entity used by any of the cameras - * and stores the instances in SimplePipelineHandler::subdevs_, accessible by - * the SimpleCameraData class through the SimplePipelineHandler::subdev() - * function. This avoids duplication of subdev instances between different - * cameras when the same entity is used in multiple paths. A similar mechanism - * is used for V4L2VideoDevice instances, but instances are in this case created - * on demand when accessed through SimplePipelineHandler::video() instead of all - * in one go at initialization time. + * creates a V4L2VideoDevice or V4L2Subdevice instance for each entity used by + * any of the cameras and stores them in SimplePipelineHandler::entities_, + * accessible by the SimpleCameraData class through the + * SimplePipelineHandler::subdev() and SimplePipelineHandler::video() functions. + * This avoids duplication of subdev instances between different cameras when + * the same entity is used in multiple paths. * * Finally, all camera data instances are initialized to gather information * about the possible pipeline configurations for the corresponding camera. If @@ -397,10 +395,7 @@ int SimpleCameraData::init() int ret; video_ = pipe->video(entities_.back().entity); - if (!video_) { - LOG(SimplePipeline, Error) << "Failed to open video device"; - return -ENODEV; - } + ASSERT(video_); /* * Setup links first as some subdev drivers take active links into @@ -1069,24 +1064,44 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) /* * Insert all entities in the global entities list. Create and open - * V4L2Subdevice instances for each entity corresponding to a V4L2 - * subdevice. + * V4L2VideoDevice and V4L2Subdevice instances for the corresponding + * entities. */ for (MediaEntity *entity : entities) { + std::unique_ptr video; std::unique_ptr subdev; + int ret; - if (entity->type() == MediaEntity::Type::V4L2Subdevice) { + switch (entity->type()) { + case MediaEntity::Type::V4L2VideoDevice: + video = std::make_unique(entity); + ret = video->open(); + if (ret < 0) { + LOG(SimplePipeline, Error) + << "Failed to open " << video->deviceNode() + << ": " << strerror(-ret); + return false; + } + + video->bufferReady.connect(this, &SimplePipelineHandler::bufferReady); + break; + + case MediaEntity::Type::V4L2Subdevice: subdev = std::make_unique(entity); - int ret = subdev->open(); + ret = subdev->open(); if (ret < 0) { LOG(SimplePipeline, Error) << "Failed to open " << subdev->deviceNode() << ": " << strerror(-ret); return false; } + break; + + default: + break; } - entities_[entity] = { nullptr, std::move(subdev) }; + entities_[entity] = { std::move(video), std::move(subdev) }; } /* Initialize each pipeline and register a corresponding camera. */ @@ -1113,27 +1128,11 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) V4L2VideoDevice *SimplePipelineHandler::video(const MediaEntity *entity) { - /* - * Return the V4L2VideoDevice corresponding to the media entity, either - * as a previously constructed device if available from the cache, or - * by constructing a new one. - */ - auto iter = entities_.find(entity); if (iter == entities_.end()) return nullptr; - EntityData &data = iter->second; - if (data.video) - return data.video.get(); - - data.video = std::make_unique(entity); - if (data.video->open() < 0) - return nullptr; - - data.video->bufferReady.connect(this, &SimplePipelineHandler::bufferReady); - - return data.video.get(); + return iter->second.video.get(); } V4L2Subdevice *SimplePipelineHandler::subdev(const MediaEntity *entity)