From patchwork Fri Jun 5 12:03:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 3943 X-Patchwork-Delegate: paul.elder@ideasonboard.com Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3A69F603C7 for ; Fri, 5 Jun 2020 14:03:17 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="W0x342Av"; dkim-atps=neutral Received: from emerald.amanokami.net (fs76eef344.knge213.ap.nuro.jp [118.238.243.68]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id CD4AE27C; Fri, 5 Jun 2020 14:03:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1591358596; bh=lobqqmc9Jtl07BVnUpIMg5OT3j5WNsAfiVZJL6m/DEA=; h=From:To:Cc:Subject:Date:From; b=W0x342AvdbmSS443GJg11akMCtzfmkU3/Bmwu80nBPyit+hxoC657/FLHeUHBcCLC HLQ1pAHOcSEdRg4QMon5d8AbOnrt+CsvFDnOPV5lXSsWbx2MhdytvrtUc9xv36sNhM +B9YWGBb56kkAGQLQ6EGBS4sx27Ho8LczC27g8lQ= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Fri, 5 Jun 2020 21:03:06 +0900 Message-Id: <20200605120306.25529-1-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH] libcamera: CameraManager, PipelineHandler: Allow multiple devnums per camera 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: , X-List-Received-Date: Fri, 05 Jun 2020 12:03:17 -0000 The V4L2 compatibility layer uses devnum to match video device nodes to libcamera Cameras. Some pipeline handlers don't report a devnum for their camera, which prevents the V4L2 compatibility layer from matching video device nodes to these cameras. To fix this, we first allow the camera manager to map multiple devnums to a camera. Next, if the pipeline handler doesn't report a devnum for a camera, then walk the media device and entity list and tell the camera manager to map every one of these devnums to the camera. We considered walking the media entity list and taking the devnum from just the one with the default flag set, but we found that some drivers (eg. vimc) don't set this flag for any entity. Signed-off-by: Paul Elder Reviewed-by: Niklas Söderlund --- include/libcamera/camera_manager.h | 3 ++- src/libcamera/camera_manager.cpp | 14 ++++++++------ src/libcamera/pipeline_handler.cpp | 12 +++++++++++- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/include/libcamera/camera_manager.h b/include/libcamera/camera_manager.h index 079f848a..6095b799 100644 --- a/include/libcamera/camera_manager.h +++ b/include/libcamera/camera_manager.h @@ -34,7 +34,8 @@ public: std::shared_ptr get(const std::string &name); std::shared_ptr get(dev_t devnum); - void addCamera(std::shared_ptr camera, dev_t devnum); + void addCamera(std::shared_ptr camera, + std::vector devnums); void removeCamera(Camera *camera); static const std::string &version() { return version_; } diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp index da806fa7..fa0bd6a0 100644 --- a/src/libcamera/camera_manager.cpp +++ b/src/libcamera/camera_manager.cpp @@ -36,7 +36,8 @@ public: Private(CameraManager *cm); int start(); - void addCamera(std::shared_ptr &camera, dev_t devnum); + void addCamera(std::shared_ptr &camera, + std::vector devnums); void removeCamera(Camera *camera); /* @@ -168,7 +169,7 @@ void CameraManager::Private::cleanup() } void CameraManager::Private::addCamera(std::shared_ptr &camera, - dev_t devnum) + std::vector devnums) { MutexLocker locker(mutex_); @@ -183,7 +184,7 @@ void CameraManager::Private::addCamera(std::shared_ptr &camera, cameras_.push_back(std::move(camera)); - if (devnum) { + for (dev_t devnum : devnums) { unsigned int index = cameras_.size() - 1; camerasByDevnum_[devnum] = cameras_[index]; } @@ -374,7 +375,7 @@ std::shared_ptr CameraManager::get(dev_t devnum) /** * \brief Add a camera to the camera manager * \param[in] camera The camera to be added - * \param[in] devnum The device number to associate with \a camera + * \param[in] devnums The device numbers to associate with \a camera * * This function is called by pipeline handlers to register the cameras they * handle with the camera manager. Registered cameras are immediately made @@ -385,11 +386,12 @@ std::shared_ptr CameraManager::get(dev_t devnum) * * \context This function shall be called from the CameraManager thread. */ -void CameraManager::addCamera(std::shared_ptr camera, dev_t devnum) +void CameraManager::addCamera(std::shared_ptr camera, + std::vector devnums) { ASSERT(Thread::current() == p_.get()); - p_->addCamera(camera, devnum); + p_->addCamera(camera, devnums); } /** diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 53aeebdc..b3824a5f 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -502,7 +502,17 @@ void PipelineHandler::registerCamera(std::shared_ptr camera, data->camera_ = camera.get(); cameraData_[camera.get()] = std::move(data); cameras_.push_back(camera); - manager_->addCamera(std::move(camera), devnum); + + std::vector devnums; + if (devnum != 0) + devnums.push_back(devnum); + else + for (const std::shared_ptr media : mediaDevices_) + for (const MediaEntity *entity : media->entities()) + devnums.push_back(makedev(entity->deviceMajor(), + entity->deviceMinor())); + + manager_->addCamera(std::move(camera), devnums); } /**