From patchwork Thu Jan 5 04:37:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 18087 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 6ECA4C322E for ; Thu, 5 Jan 2023 04:37:59 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D29B0625E3; Thu, 5 Jan 2023 05:37:57 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1672893477; bh=XM+yPx4JuCXodROlLD2ni7MBN30gwb8J94HTJnDzkdg=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=JLrRSrlzVbxJs0lnxmmqgJhbAfo16a9NTkCPjIW4F04WM4QTtVAluTn4n8c+sIxS9 hRNdZpYtagPNfiphCPriV5MLrs6GFHL6+LeZJVBnkn1R+vW9s3mkAfiaTRPROatM4v pSbB63mi5rz6l7F+/HqKgpqwBm3YKiP8i5T9qqM8ja2aJJ9fFv4xZovVTZ39dmcv13 sVeg0Os9udhhC3YzdbaN3K4ofHjp60KQEdTdvPasNZT5H2BR5iuFiZVBnJcJEw6luy 7D/rWgo6zA2ics/G6jy7HtEtGakX+rFwBfoqZf+mvOUYu039XZJGMHWF6ymFahJk9r eKOJkrYoo2Mtg== Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9E94361F06 for ; Thu, 5 Jan 2023 05:37:55 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="HqD99PQE"; dkim-atps=neutral Received: by mail-pj1-x102b.google.com with SMTP id w4-20020a17090ac98400b002186f5d7a4cso913717pjt.0 for ; Wed, 04 Jan 2023 20:37:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0vYtodSdAt/8P9nhv9LXQF/+ifyNNCO0IObLe5XkKHM=; b=HqD99PQE3ASWBAtBobTkaprY/kaNAz687SRLdNsjHdpjkifEujZ7lPlPFUfiNLycPA 3dL2ZUHd7xcZRp/xcLIcSSGbV+adCJVxSHqWwrpcug9aeVdJZxNBv6jbUxFiEF76a+fk theVZcPQ8aUN6QfrozYhoo+Dm4DmvbyMg3kqA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0vYtodSdAt/8P9nhv9LXQF/+ifyNNCO0IObLe5XkKHM=; b=JIGmNr+zsKyTE22apDrz4pSgdGGeFAZNJDRVMcC9h2BGkZSLuaC203XLibzPyRx0BK lo/e1bzyewsw+I3+LbykPeUgNM5euJoo7nP6tJtJsNi2MuHP2KXKYiJLf5Gsj7cFatE5 cAc+zfrBhxE5qUJrILXy/vbUcHpnfApq//TtWMAfqF6f017ope4MdBbC8mA0kTZZOnIO 2+4lzfav4/UkciO/HalleKOAaxLjf0eXqalN323EJZPq519CLyMX3m0FrO+uDgpqFEkn /jXDNGAsWOBw0lh6M97oyOSbFGeE56NTSr/Hen4lX2gPuAK7ZNrx36coaFbEtQveZJ2+ 5LxQ== X-Gm-Message-State: AFqh2kq0homaf5t1j/n2w0LNrhjhd1+9IrvSRa5e6rDVPINcXu0Jrt22 TwKq6YYXPaDSCp0QvLV+VeNi3pfvPcXM5DhN X-Google-Smtp-Source: AMrXdXuw1Booce5jj/euhJl2lGV5p7OAulvFfXLMeGMJEOwgCWfa/S7IEDn8Eqom46uxZb/yB1ltVA== X-Received: by 2002:a17:902:74cc:b0:189:dd9b:66c3 with SMTP id f12-20020a17090274cc00b00189dd9b66c3mr40287870plt.11.1672893473988; Wed, 04 Jan 2023 20:37:53 -0800 (PST) Received: from chenghaoyang-low.c.googlers.com.com (46.165.189.35.bc.googleusercontent.com. [35.189.165.46]) by smtp.gmail.com with ESMTPSA id x23-20020a170902b41700b00188c5f0f9e9sm25015200plr.199.2023.01.04.20.37.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Jan 2023 20:37:53 -0800 (PST) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Jan 2023 04:37:18 +0000 Message-Id: <20230105043726.679968-2-chenghaoyang@google.com> X-Mailer: git-send-email 2.39.0.314.g84b9a713c41-goog In-Reply-To: <20230105043726.679968-1-chenghaoyang@google.com> References: <20230105043726.679968-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 1/9] libcamera: pipeline: Introduce skeleton Virtual Pipeline 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-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang , Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Provide all of the skeleton stubs to succesfully compile and register the Virtual Pipeline Handler for testing with fake data. Meson must be reconfigured to ensure that this pipeline handler is included in the selected pipelines configuration. Signed-off-by: Harvey Yang --- meson_options.txt | 2 +- src/libcamera/pipeline/virtual/meson.build | 5 + src/libcamera/pipeline/virtual/virtual.cpp | 112 +++++++++++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 src/libcamera/pipeline/virtual/meson.build create mode 100644 src/libcamera/pipeline/virtual/virtual.cpp diff --git a/meson_options.txt b/meson_options.txt index 1ba6778c..08876f4c 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -37,7 +37,7 @@ option('lc-compliance', option('pipelines', type : 'array', - choices : ['imx8-isi', 'ipu3', 'raspberrypi', 'rkisp1', 'simple', 'uvcvideo', 'vimc'], + choices : ['imx8-isi', 'ipu3', 'raspberrypi', 'rkisp1', 'simple', 'uvcvideo', 'vimc', 'virtual'], description : 'Select which pipeline handlers to include') option('qcam', diff --git a/src/libcamera/pipeline/virtual/meson.build b/src/libcamera/pipeline/virtual/meson.build new file mode 100644 index 00000000..ba7ff754 --- /dev/null +++ b/src/libcamera/pipeline/virtual/meson.build @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: CC0-1.0 + +libcamera_sources += files([ + 'virtual.cpp', +]) diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp new file mode 100644 index 00000000..09583b4e --- /dev/null +++ b/src/libcamera/pipeline/virtual/virtual.cpp @@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2022, Google Inc. + * + * fake.cpp - Pipeline handler for fake cameras + */ + +#include + +#include + +#include "libcamera/internal/pipeline_handler.h" + +namespace libcamera { + +LOG_DEFINE_CATEGORY(VIRTUAL) + +class VirtualCameraConfiguration : public CameraConfiguration +{ +public: + VirtualCameraConfiguration(); + + Status validate() override; +}; + +class PipelineHandlerVirtual : public PipelineHandler +{ +public: + PipelineHandlerVirtual(CameraManager *manager); + + std::unique_ptr generateConfiguration(Camera *camera, + const StreamRoles &roles) override; + int configure(Camera *camera, CameraConfiguration *config) override; + + int exportFrameBuffers(Camera *camera, Stream *stream, + std::vector> *buffers) override; + + int start(Camera *camera, const ControlList *controls) override; + void stopDevice(Camera *camera) override; + + int queueRequestDevice(Camera *camera, Request *request) override; + + bool match(DeviceEnumerator *enumerator) override; +}; + +VirtualCameraConfiguration::VirtualCameraConfiguration() + : CameraConfiguration() +{ +} + +CameraConfiguration::Status VirtualCameraConfiguration::validate() +{ + return Invalid; +} + +PipelineHandlerVirtual::PipelineHandlerVirtual(CameraManager *manager) + : PipelineHandler(manager) +{ +} + +std::unique_ptr PipelineHandlerVirtual::generateConfiguration(Camera *camera, + const StreamRoles &roles) +{ + (void)camera; + (void)roles; + return std::unique_ptr(nullptr); +} + +int PipelineHandlerVirtual::configure(Camera *camera, CameraConfiguration *config) +{ + (void)camera; + (void)config; + return -1; +} + +int PipelineHandlerVirtual::exportFrameBuffers(Camera *camera, Stream *stream, + std::vector> *buffers) +{ + (void)camera; + (void)stream; + (void)buffers; + return -1; +} + +int PipelineHandlerVirtual::start(Camera *camera, const ControlList *controls) +{ + (void)camera; + (void)controls; + return -1; +} + +void PipelineHandlerVirtual::stopDevice(Camera *camera) +{ + (void)camera; +} + +int PipelineHandlerVirtual::queueRequestDevice(Camera *camera, Request *request) +{ + (void)camera; + (void)request; + return -1; +} + +bool PipelineHandlerVirtual::match(DeviceEnumerator *enumerator) +{ + (void)enumerator; + return false; +} + +REGISTER_PIPELINE_HANDLER(PipelineHandlerVirtual) + +} /* namespace libcamera */ From patchwork Thu Jan 5 04:37:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 18088 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 00C55C322E for ; Thu, 5 Jan 2023 04:38:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 78CCF625E8; Thu, 5 Jan 2023 05:38:00 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1672893480; bh=TUpyjQ7lDZNCc/ppOivZyjU7TlW2mgSX8d4w4ji1yQ8=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=J/+/qmx8I5i4GgB+DEHLmN0KR1HoSnf28FMGPZPlhVvux066Zi9Band5+3GB2i7dt nTX8x62GQ/TsphY4xpN98TrFDIwkCraD6IcMFyeC6IpMk6RtlxOzBYM3YudooJF/n/ 1xG66CDzeDtp1RmGfBDwwx3nUulFrd+OCO54BCCRs2AInLUzJTDJPqfgxLoi4REbfA Fgv+8WmVp0UqEm0EJOmIfjhoCveSlyb8+qFixhc6Tsfl8lDIQO87eHrpMrI4t19xdp IGKprH7IlN8bd1pjbyqKooo6gA4+LioJZ/vQX1SBGkpUekelr9pwSt8FoKNKpaz9Mu KcJ3Wq6yQD0xg== Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 258BB625E0 for ; Thu, 5 Jan 2023 05:37:57 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="WN2MRzyj"; dkim-atps=neutral Received: by mail-pl1-x629.google.com with SMTP id 17so38291850pll.0 for ; Wed, 04 Jan 2023 20:37:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Lu1+s6tyYLkcwjuQSi7kdVu6yK/pRdKhbH99IcqAYhc=; b=WN2MRzyjz72gTMOwtJoNJ1XyntJtbCr8omFY9VhslXu01wH+y9rNU9zPOg2k2pwW5Q RR5ZqRT5Yl2HuXVf9NwAR5aKDfDHI2R2v/hlbzi/FQnBgcuV6OgXVrBONWWvkJ2tkocv 8rNTWRFSjYbE9HYhT8cIB8NjxHUjS9ALcQyAc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Lu1+s6tyYLkcwjuQSi7kdVu6yK/pRdKhbH99IcqAYhc=; b=VdiMcq8gVVNOy+ogfkRybnyGpBgvbrTSChcKNu37zkFYOFfoejdPenc2C2Sq4Nddp6 /Wra3jkQ4ooybYl0usiI5YBxyg1CvXxS6hsseGIftR7AmgyHOmZnO/tNaGsqZ7umQEKC Qy51s0yL7oMAc42n+1VUukPvzqGXG23ra40CDBlXwqkSHcKFYLCg06LYIsRglhU3Bc9i I8zcj7JDrNk+rD3/BR5mZXrem4RgWPQtDA8j0YgIhTWAkjWNsNCbdw2Bd6Fg1SX7+5kh RuWfBnMjLAQ/vl9HBjpDoSRbZ7S86NwUoRx8cU8flNx/nt7QdoIVU4ORw9lQEdamkTK+ D9cQ== X-Gm-Message-State: AFqh2kqz903Sfsa0am1OGa6eQPvxRI9Cp/U7kcYZLTvhfbnNxM7H2M4T TZREVBKHNnHu5XqxS4neNmY5+JdsVTJv7E2U X-Google-Smtp-Source: AMrXdXvPrnaNx5PR5CJD23n9nbfLfwhtAgcAH6b+DDvA8mVASc4tfn8R4MpspgcWxWYzr8o1AfZcRA== X-Received: by 2002:a17:902:a513:b0:192:fe0a:11d4 with SMTP id s19-20020a170902a51300b00192fe0a11d4mr593965plq.64.1672893475150; Wed, 04 Jan 2023 20:37:55 -0800 (PST) Received: from chenghaoyang-low.c.googlers.com.com (46.165.189.35.bc.googleusercontent.com. [35.189.165.46]) by smtp.gmail.com with ESMTPSA id x23-20020a170902b41700b00188c5f0f9e9sm25015200plr.199.2023.01.04.20.37.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Jan 2023 20:37:54 -0800 (PST) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Jan 2023 04:37:19 +0000 Message-Id: <20230105043726.679968-3-chenghaoyang@google.com> X-Mailer: git-send-email 2.39.0.314.g84b9a713c41-goog In-Reply-To: <20230105043726.679968-1-chenghaoyang@google.com> References: <20230105043726.679968-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 2/9] libcamera: Add MediaDeviceBase 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-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang , Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" To introduce a virtual MediaDevice class in the following patches, adds a base class of MediaDevice, to be used in other base classes. Signed-off-by: Harvey Yang --- include/libcamera/internal/media_device.h | 35 +---- .../libcamera/internal/media_device_base.h | 68 +++++++++ include/libcamera/internal/meson.build | 1 + src/libcamera/media_device.cpp | 97 +----------- src/libcamera/media_device_base.cpp | 140 ++++++++++++++++++ src/libcamera/meson.build | 1 + 6 files changed, 221 insertions(+), 121 deletions(-) create mode 100644 include/libcamera/internal/media_device_base.h create mode 100644 src/libcamera/media_device_base.cpp diff --git a/include/libcamera/internal/media_device.h b/include/libcamera/internal/media_device.h index eb8cfde4..0edf6b98 100644 --- a/include/libcamera/internal/media_device.h +++ b/include/libcamera/internal/media_device.h @@ -18,35 +18,26 @@ #include #include +#include "libcamera/internal/media_device_base.h" #include "libcamera/internal/media_object.h" namespace libcamera { -class MediaDevice : protected Loggable +class MediaDevice : public MediaDeviceBase { public: MediaDevice(const std::string &deviceNode); ~MediaDevice(); - bool acquire(); - void release(); - bool busy() const { return acquired_; } + bool lock() override; + void unlock() override; - bool lock(); - void unlock(); + int populate() override; - int populate(); - bool isValid() const { return valid_; } - - const std::string &driver() const { return driver_; } - const std::string &deviceNode() const { return deviceNode_; } const std::string &model() const { return model_; } unsigned int version() const { return version_; } unsigned int hwRevision() const { return hwRevision_; } - const std::vector &entities() const { return entities_; } - MediaEntity *getEntityByName(const std::string &name) const; - MediaLink *link(const std::string &sourceName, unsigned int sourceIdx, const std::string &sinkName, unsigned int sinkIdx); MediaLink *link(const MediaEntity *source, unsigned int sourceIdx, @@ -54,18 +45,13 @@ public: MediaLink *link(const MediaPad *source, const MediaPad *sink); int disableLinks(); - Signal<> disconnected; - -protected: - std::string logPrefix() const override; - private: - int open(); - void close(); + int open() override; + void close() override; MediaObject *object(unsigned int id); bool addObject(MediaObject *object); - void clear(); + void clear() override; struct media_v2_interface *findInterface(const struct media_v2_topology &topology, unsigned int entityId); @@ -77,18 +63,13 @@ private: friend int MediaLink::setEnabled(bool enable); int setupLink(const MediaLink *link, unsigned int flags); - std::string driver_; - std::string deviceNode_; std::string model_; unsigned int version_; unsigned int hwRevision_; UniqueFD fd_; - bool valid_; - bool acquired_; std::map objects_; - std::vector entities_; }; } /* namespace libcamera */ diff --git a/include/libcamera/internal/media_device_base.h b/include/libcamera/internal/media_device_base.h new file mode 100644 index 00000000..4f2d1fb7 --- /dev/null +++ b/include/libcamera/internal/media_device_base.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2022, Google Inc. + * + * media_device.h - The base class of media device handler + */ + +#pragma once + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "libcamera/internal/media_object.h" + +namespace libcamera { + +class MediaDeviceBase : protected Loggable +{ +public: + MediaDeviceBase(const std::string &deviceNode); + ~MediaDeviceBase(); + + bool acquire(); + void release(); + bool busy() const { return acquired_; } + + virtual bool lock(); + virtual void unlock(); + + virtual int populate(); + bool isValid() const { return valid_; } + + const std::string &driver() const { return driver_; } + const std::string &deviceNode() const { return deviceNode_; } + + const std::vector &entities() const { return entities_; } + MediaEntity *getEntityByName(const std::string &name) const; + + Signal<> disconnected; + +protected: + std::string logPrefix() const override; + + virtual int open() { return 0; } + virtual void close() {} + virtual void clear(); + + std::string driver_; + std::string deviceNode_; + + bool valid_; + bool acquired_; + + std::vector entities_; + +private: + bool lock_; +}; + +} /* namespace libcamera */ diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build index f8be86e0..826a241c 100644 --- a/include/libcamera/internal/meson.build +++ b/include/libcamera/internal/meson.build @@ -31,6 +31,7 @@ libcamera_internal_headers = files([ 'ipc_unixsocket.h', 'mapped_framebuffer.h', 'media_device.h', + 'media_device_base.h', 'media_object.h', 'pipeline_handler.h', 'process.h', diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp index 52c8e66e..ea0525d5 100644 --- a/src/libcamera/media_device.cpp +++ b/src/libcamera/media_device.cpp @@ -63,63 +63,13 @@ LOG_DEFINE_CATEGORY(MediaDevice) * populate() before the media graph can be queried. */ MediaDevice::MediaDevice(const std::string &deviceNode) - : deviceNode_(deviceNode), valid_(false), acquired_(false) + : MediaDeviceBase(deviceNode) { } MediaDevice::~MediaDevice() { fd_.reset(); - clear(); -} - -std::string MediaDevice::logPrefix() const -{ - return deviceNode() + "[" + driver() + "]"; -} - -/** - * \brief Claim a device for exclusive use - * - * The device claiming mechanism offers simple media device access arbitration - * between multiple users. When the media device is created, it is available to - * all users. Users can query the media graph to determine whether they can - * support the device and, if they do, claim the device for exclusive use. Other - * users are then expected to skip over media devices in use as reported by the - * busy() function. - * - * Once claimed the device shall be released by its user when not needed anymore - * by calling the release() function. Acquiring the media device opens a file - * descriptor to the device which is kept open until release() is called. - * - * Exclusive access is only guaranteed if all users of the media device abide by - * the device claiming mechanism, as it isn't enforced by the media device - * itself. - * - * \return true if the device was successfully claimed, or false if it was - * already in use - * \sa release(), busy() - */ -bool MediaDevice::acquire() -{ - if (acquired_) - return false; - - if (open()) - return false; - - acquired_ = true; - return true; -} - -/** - * \brief Release a device previously claimed for exclusive use - * \sa acquire(), busy() - */ -void MediaDevice::release() -{ - close(); - acquired_ = false; } /** @@ -290,12 +240,6 @@ done: * \return The name of the kernel driver that handles the MediaDevice */ -/** - * \fn MediaDevice::deviceNode() - * \brief Retrieve the media device node path - * \return The MediaDevice deviceNode path - */ - /** * \fn MediaDevice::model() * \brief Retrieve the media device model name @@ -320,26 +264,6 @@ done: * \return The MediaDevice hardware revision */ -/** - * \fn MediaDevice::entities() - * \brief Retrieve the list of entities in the media graph - * \return The list of MediaEntities registered in the MediaDevice - */ - -/** - * \brief Return the MediaEntity with name \a name - * \param[in] name The entity name - * \return The entity with \a name, or nullptr if no such entity is found - */ -MediaEntity *MediaDevice::getEntityByName(const std::string &name) const -{ - for (MediaEntity *e : entities_) - if (e->name() == name) - return e; - - return nullptr; -} - /** * \brief Retrieve the MediaLink connecting two pads, identified by entity * names and pad indexes @@ -453,16 +377,6 @@ int MediaDevice::disableLinks() return 0; } -/** - * \var MediaDevice::disconnected - * \brief Signal emitted when the media device is disconnected from the system - * - * This signal is emitted when the device enumerator detects that the media - * device has been removed from the system. For hot-pluggable devices this is - * usually caused by physical device disconnection, but can also result from - * driver unloading for most devices. The media device is passed as a parameter. - */ - /** * \brief Open the media device * @@ -565,14 +479,9 @@ void MediaDevice::clear() delete o.second; objects_.clear(); - entities_.clear(); - valid_ = false; -} -/** - * \var MediaDevice::entities_ - * \brief Global list of media entities in the media graph - */ + MediaDeviceBase::clear(); +} /** * \brief Find the interface associated with an entity diff --git a/src/libcamera/media_device_base.cpp b/src/libcamera/media_device_base.cpp new file mode 100644 index 00000000..12161d1a --- /dev/null +++ b/src/libcamera/media_device_base.cpp @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2022, Google Inc. + * + * media_device_base.cpp - The base class of media device handler + */ + +#include "libcamera/internal/media_device_base.h" + +namespace libcamera { + +LOG_DEFINE_CATEGORY(MediaDeviceBase) + +MediaDeviceBase::MediaDeviceBase(const std::string &deviceNode) + : deviceNode_(deviceNode), valid_(false), acquired_(false), lock_(false) +{ +} + +MediaDeviceBase::~MediaDeviceBase() +{ + clear(); +} + +/** + * \brief Claim a device for exclusive use + * + * The device claiming mechanism offers simple media device access arbitration + * between multiple users. When the media device is created, it is available to + * all users. Users can query the media graph to determine whether they can + * support the device and, if they do, claim the device for exclusive use. Other + * users are then expected to skip over media devices in use as reported by the + * busy() function. + * + * Once claimed the device shall be released by its user when not needed anymore + * by calling the release() function. Acquiring the media device opens a file + * descriptor to the device which is kept open until release() is called. + * + * Exclusive access is only guaranteed if all users of the media device abide by + * the device claiming mechanism, as it isn't enforced by the media device + * itself. + * + * \return true if the device was successfully claimed, or false if it was + * already in use + * \sa release(), busy() + */ +bool MediaDeviceBase::acquire() +{ + if (acquired_) + return false; + + if (open()) + return false; + + acquired_ = true; + return true; +} + +/** + * \brief Release a device previously claimed for exclusive use + * \sa acquire(), busy() + */ +void MediaDeviceBase::release() +{ + close(); + acquired_ = false; +} + +bool MediaDeviceBase::lock() +{ + if (lock_) + return false; + + lock_ = true; + return true; +} + +void MediaDeviceBase::unlock() +{ + lock_ = false; +} + +int MediaDeviceBase::populate() +{ + valid_ = true; + return 0; +} + +/** + * \fn MediaDeviceBase::deviceNode() + * \brief Retrieve the media device node path + * \return The MediaDeviceBase deviceNode path + */ + +/** + * \fn MediaDeviceBase::entities() + * \brief Retrieve the list of entities in the media graph + * \return The list of MediaEntities registered in the MediaDeviceBase + */ + +/** + * \brief Return the MediaEntity with name \a name + * \param[in] name The entity name + * \return The entity with \a name, or nullptr if no such entity is found + */ +MediaEntity *MediaDeviceBase::getEntityByName(const std::string &name) const +{ + for (MediaEntity *e : entities_) + if (e->name() == name) + return e; + + return nullptr; +} + +/** + * \var MediaDeviceBase::disconnected + * \brief Signal emitted when the media device is disconnected from the system + * + * This signal is emitted when the device enumerator detects that the media + * device has been removed from the system. For hot-pluggable devices this is + * usually caused by physical device disconnection, but can also result from + * driver unloading for most devices. The media device is passed as a parameter. + */ + +std::string MediaDeviceBase::logPrefix() const +{ + return deviceNode() + "[" + driver() + "]"; +} + +void MediaDeviceBase::clear() +{ + entities_.clear(); + valid_ = false; +} + +/** + * \var MediaDeviceBase::entities_ + * \brief Global list of media entities in the media graph + */ + +} /* namespace libcamera */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 0494e808..ce4c1a29 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -32,6 +32,7 @@ libcamera_sources = files([ 'ipc_unixsocket.cpp', 'mapped_framebuffer.cpp', 'media_device.cpp', + 'media_device_base.cpp', 'media_object.cpp', 'pipeline_handler.cpp', 'pixel_format.cpp', From patchwork Thu Jan 5 04:37:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 18089 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 C8CDBC3291 for ; Thu, 5 Jan 2023 04:38:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 660D7625E7; Thu, 5 Jan 2023 05:38:01 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1672893481; bh=aNPoTsAaz6S8cvpjer+u/7q8UypJB4kTfGr6+27c49s=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=w3jf3j3zy9cIGi9gypbyPQj3nHMTztSppIqaclQ8TFxWXBx1Cex06kIjLAEwDZwGk tOMHhyv/2GKkLuyy91iS+skY2/SE5GxUKHafOmykGpNvoJ9VMpEuw1p/DgZT27fusl SaPW7lr39ZPlEoylrM47+u0mgJMlhzPBhdCV7xFF21JT96VY25kbLWjGtPCxdOWs6H +ujx1ZQ0R3TRAOTFWEQG8nrdoET64X8fjfW3mzVJcioUb7eYtn8ZNgzd/4UsTGew+I ct5fmxs72SvZkGrRfWTYj8UJtXzACUBt+yX0B3p+wzLHuelb1l6vF0+JTifaHKdeES ZjKPlnmE8ilWw== Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 82406625DF for ; Thu, 5 Jan 2023 05:37:58 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="PpLPkagq"; dkim-atps=neutral Received: by mail-pj1-x1030.google.com with SMTP id o7-20020a17090a0a0700b00226c9b82c3aso870333pjo.3 for ; Wed, 04 Jan 2023 20:37:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=2dcd59yRSKL3Fk+Qlt8vuBFn/l2W1oyI0rRReM2jI7U=; b=PpLPkagqqtmb9YhCAShk7cctSzR4l09bUfF5hspxHlTzmTWZLdMTlRSCzgRi+Uy689 z1OHUYlBuTI72VE1vQQKQvX/5tPZV3b71vXkAPznGcgv5LB++34gCtioxUU+qvZURgtF UKb983nxnU1+sKib2Jaz+YV5yS7lkw2pQaKBk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2dcd59yRSKL3Fk+Qlt8vuBFn/l2W1oyI0rRReM2jI7U=; b=KGbpXI2h7sEpZTD9XJzMlMOZqp8Z+wd35RwyTotbvmta0ZIMPBZHTjF3aTi35HDaQ9 3OOtwbG10etDjM9hWDplqIUAyn+0BgFjNYjvVyRTkQni7vFU/RQoFP1gwAafbivFd0LF ifo6fWn90+ulOUIgHGV+QdSK2421kfN36bbsQ6gD0IP1fgwktAfwE85a7OUF0bqVbFjr qDaiTo/qmWVIZfj9SfWd1WrJZ4sevB7BGEXpYGKrwGxYwYwZGBIowThtTwzOgBiUHOAM cJlHYaxayYX7J5vinvd57LtTZPs54oRnQ1oko/8s5aGRAJFXQQ19Ry7xl5Ek/FaYjFHG c3mg== X-Gm-Message-State: AFqh2kopjzj7Z5aiskTGmSeZ+ct4v4Mc+i5PysBa2lud4A15PYN64odB UXxUewSdVloWTq0uWIpR3VCcOrX8pPKEfdX5 X-Google-Smtp-Source: AMrXdXtJ5/qLA8RdyuOhL5OsrgLLCdUD/QLzBG5Nlcyzt4uD0ibixtiE1yaVOlz2QfDgi3OGX9LRfw== X-Received: by 2002:a17:903:200b:b0:192:467e:7379 with SMTP id s11-20020a170903200b00b00192467e7379mr44389317pla.49.1672893476455; Wed, 04 Jan 2023 20:37:56 -0800 (PST) Received: from chenghaoyang-low.c.googlers.com.com (46.165.189.35.bc.googleusercontent.com. [35.189.165.46]) by smtp.gmail.com with ESMTPSA id x23-20020a170902b41700b00188c5f0f9e9sm25015200plr.199.2023.01.04.20.37.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Jan 2023 20:37:56 -0800 (PST) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Jan 2023 04:37:20 +0000 Message-Id: <20230105043726.679968-4-chenghaoyang@google.com> X-Mailer: git-send-email 2.39.0.314.g84b9a713c41-goog In-Reply-To: <20230105043726.679968-1-chenghaoyang@google.com> References: <20230105043726.679968-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 3/9] libcamera: Use MediaDeviceBase in base classes 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-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang , Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Use MediaDeviceBase instead of MediaDevice in other base classes like PipelineHandler and DeviceEnumerator. Signed-off-by: Harvey Yang --- .../libcamera/internal/device_enumerator.h | 12 ++++---- .../internal/device_enumerator_sysfs.h | 4 +-- .../internal/device_enumerator_udev.h | 8 ++--- include/libcamera/internal/pipeline_handler.h | 12 ++++---- src/libcamera/device_enumerator.cpp | 30 +++++++++---------- src/libcamera/device_enumerator_sysfs.cpp | 4 +-- src/libcamera/device_enumerator_udev.cpp | 4 +-- src/libcamera/pipeline/imx8-isi/imx8-isi.cpp | 2 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 4 +-- .../pipeline/raspberrypi/raspberrypi.cpp | 4 +-- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 2 +- src/libcamera/pipeline/simple/simple.cpp | 4 +-- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 2 +- src/libcamera/pipeline/vimc/vimc.cpp | 2 +- src/libcamera/pipeline_handler.cpp | 18 +++++------ 15 files changed, 56 insertions(+), 56 deletions(-) diff --git a/include/libcamera/internal/device_enumerator.h b/include/libcamera/internal/device_enumerator.h index 72ec9a60..87a2b5ce 100644 --- a/include/libcamera/internal/device_enumerator.h +++ b/include/libcamera/internal/device_enumerator.h @@ -15,7 +15,7 @@ namespace libcamera { -class MediaDevice; +class MediaDeviceBase; class DeviceMatch { @@ -24,7 +24,7 @@ public: void add(const std::string &entity); - bool match(const MediaDevice *device) const; + bool match(const MediaDeviceBase *device) const; private: std::string driver_; @@ -41,17 +41,17 @@ public: virtual int init() = 0; virtual int enumerate() = 0; - std::shared_ptr search(const DeviceMatch &dm); + std::shared_ptr search(const DeviceMatch &dm); Signal<> devicesAdded; protected: - std::unique_ptr createDevice(const std::string &deviceNode); - void addDevice(std::unique_ptr media); + std::unique_ptr createDevice(const std::string &deviceNode); + void addDevice(std::unique_ptr media); void removeDevice(const std::string &deviceNode); private: - std::vector> devices_; + std::vector> devices_; }; } /* namespace libcamera */ diff --git a/include/libcamera/internal/device_enumerator_sysfs.h b/include/libcamera/internal/device_enumerator_sysfs.h index 3e84b83f..920fd984 100644 --- a/include/libcamera/internal/device_enumerator_sysfs.h +++ b/include/libcamera/internal/device_enumerator_sysfs.h @@ -12,7 +12,7 @@ #include "libcamera/internal/device_enumerator.h" -class MediaDevice; +class MediaDeviceBase; namespace libcamera { @@ -23,7 +23,7 @@ public: int enumerate(); private: - int populateMediaDevice(MediaDevice *media); + int populateMediaDevice(MediaDeviceBase *media); std::string lookupDeviceNode(int major, int minor); }; diff --git a/include/libcamera/internal/device_enumerator_udev.h b/include/libcamera/internal/device_enumerator_udev.h index 1b3360df..a833f7a6 100644 --- a/include/libcamera/internal/device_enumerator_udev.h +++ b/include/libcamera/internal/device_enumerator_udev.h @@ -23,7 +23,7 @@ struct udev_monitor; namespace libcamera { class EventNotifier; -class MediaDevice; +class MediaDeviceBase; class MediaEntity; class DeviceEnumeratorUdev final : public DeviceEnumerator @@ -39,7 +39,7 @@ private: using DependencyMap = std::map>; struct MediaDeviceDeps { - MediaDeviceDeps(std::unique_ptr media, + MediaDeviceDeps(std::unique_ptr media, DependencyMap deps) : media_(std::move(media)), deps_(std::move(deps)) { @@ -50,12 +50,12 @@ private: return media_ == other.media_; } - std::unique_ptr media_; + std::unique_ptr media_; DependencyMap deps_; }; int addUdevDevice(struct udev_device *dev); - int populateMediaDevice(MediaDevice *media, DependencyMap *deps); + int populateMediaDevice(MediaDeviceBase *media, DependencyMap *deps); std::string lookupDeviceNode(dev_t devnum); int addV4L2Device(dev_t devnum); diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index ec4f662d..1223b1cb 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -30,7 +30,7 @@ class CameraManager; class DeviceEnumerator; class DeviceMatch; class FrameBuffer; -class MediaDevice; +class MediaDeviceBase; class PipelineHandler; class Request; @@ -42,8 +42,8 @@ public: virtual ~PipelineHandler(); virtual bool match(DeviceEnumerator *enumerator) = 0; - MediaDevice *acquireMediaDevice(DeviceEnumerator *enumerator, - const DeviceMatch &dm); + MediaDeviceBase *acquireMediaDevice(DeviceEnumerator *enumerator, + const DeviceMatch &dm); bool acquire(); void release(Camera *camera); @@ -69,7 +69,7 @@ public: protected: void registerCamera(std::shared_ptr camera); - void hotplugMediaDevice(MediaDevice *media); + void hotplugMediaDevice(MediaDeviceBase *media); virtual int queueRequestDevice(Camera *camera, Request *request) = 0; virtual void stopDevice(Camera *camera) = 0; @@ -81,13 +81,13 @@ protected: private: void unlockMediaDevices(); - void mediaDeviceDisconnected(MediaDevice *media); + void mediaDeviceDisconnected(MediaDeviceBase *media); virtual void disconnect(); void doQueueRequest(Request *request); void doQueueRequests(); - std::vector> mediaDevices_; + std::vector> mediaDevices_; std::vector> cameras_; std::queue waitingRequests_; diff --git a/src/libcamera/device_enumerator.cpp b/src/libcamera/device_enumerator.cpp index f2e055de..ed5d7af3 100644 --- a/src/libcamera/device_enumerator.cpp +++ b/src/libcamera/device_enumerator.cpp @@ -13,7 +13,7 @@ #include "libcamera/internal/device_enumerator_sysfs.h" #include "libcamera/internal/device_enumerator_udev.h" -#include "libcamera/internal/media_device.h" +#include "libcamera/internal/media_device_base.h" /** * \file device_enumerator.h @@ -25,12 +25,12 @@ * At the core of the enumeration is the DeviceEnumerator class, responsible * for enumerating all media devices in the system. It handles all interactions * with the operating system in a platform-specific way. For each media device - * found an instance of MediaDevice is created to store information about the + * found an instance of MediaDeviceBase is created to store information about the * device gathered from the kernel through the Media Controller API. * * The DeviceEnumerator can enumerate all or specific media devices in the * system. When a new media device is added the enumerator creates a - * corresponding MediaDevice instance. + * corresponding MediaDeviceBase instance. * * The enumerator supports searching among enumerated devices based on criteria * expressed in a DeviceMatch object. @@ -91,7 +91,7 @@ void DeviceMatch::add(const std::string &entity) * * \return true if the media device matches the search pattern, false otherwise */ -bool DeviceMatch::match(const MediaDevice *device) const +bool DeviceMatch::match(const MediaDeviceBase *device) const { if (driver_ != device->driver()) return false; @@ -120,7 +120,7 @@ bool DeviceMatch::match(const MediaDevice *device) const * The DeviceEnumerator class is responsible for all interactions with the * operating system related to media devices. It enumerates all media devices * in the system, and for each device found creates an instance of the - * MediaDevice class and stores it internally. The list of media devices can + * MediaDeviceBase class and stores it internally. The list of media devices can * then be searched using DeviceMatch search patterns. * * The enumerator also associates media device entities with device node paths. @@ -161,7 +161,7 @@ std::unique_ptr DeviceEnumerator::create() DeviceEnumerator::~DeviceEnumerator() { - for (const std::shared_ptr &media : devices_) { + for (const std::shared_ptr &media : devices_) { if (media->busy()) LOG(DeviceEnumerator, Error) << "Removing media device " << media->deviceNode() @@ -209,9 +209,9 @@ DeviceEnumerator::~DeviceEnumerator() * * \return Created media device instance on success, or nullptr otherwise */ -std::unique_ptr DeviceEnumerator::createDevice(const std::string &deviceNode) +std::unique_ptr DeviceEnumerator::createDevice(const std::string &deviceNode) { - std::unique_ptr media = std::make_unique(deviceNode); + std::unique_ptr media = std::make_unique(deviceNode); int ret = media->populate(); if (ret < 0) { @@ -247,7 +247,7 @@ std::unique_ptr DeviceEnumerator::createDevice(const std::string &d * This function shall be called after all members of the entities of the * media graph have been confirmed to be initialized. */ -void DeviceEnumerator::addDevice(std::unique_ptr media) +void DeviceEnumerator::addDevice(std::unique_ptr media) { LOG(DeviceEnumerator, Debug) << "Added device " << media->deviceNode() << ": " << media->driver(); @@ -263,12 +263,12 @@ void DeviceEnumerator::addDevice(std::unique_ptr media) * \param[in] deviceNode Path to the media device to remove * * Remove the media device identified by \a deviceNode previously added to the - * enumerator with addDevice(). The media device's MediaDevice::disconnected + * enumerator with addDevice(). The media device's MediaDeviceBase::disconnected * signal is emitted. */ void DeviceEnumerator::removeDevice(const std::string &deviceNode) { - std::shared_ptr media; + std::shared_ptr media; for (auto iter = devices_.begin(); iter != devices_.end(); ++iter) { if ((*iter)->deviceNode() == deviceNode) { @@ -297,14 +297,14 @@ void DeviceEnumerator::removeDevice(const std::string &deviceNode) * * Search in the enumerated media devices that are not already in use for a * match described in \a dm. If a match is found and the caller intends to use - * it the caller is responsible for acquiring the MediaDevice object and + * it the caller is responsible for acquiring the MediaDeviceBase object and * releasing it when done with it. * - * \return pointer to the matching MediaDevice, or nullptr if no match is found + * \return pointer to the matching MediaDeviceBase, or nullptr if no match is found */ -std::shared_ptr DeviceEnumerator::search(const DeviceMatch &dm) +std::shared_ptr DeviceEnumerator::search(const DeviceMatch &dm) { - for (std::shared_ptr &media : devices_) { + for (std::shared_ptr &media : devices_) { if (media->busy()) continue; diff --git a/src/libcamera/device_enumerator_sysfs.cpp b/src/libcamera/device_enumerator_sysfs.cpp index 686bb809..22bbe44f 100644 --- a/src/libcamera/device_enumerator_sysfs.cpp +++ b/src/libcamera/device_enumerator_sysfs.cpp @@ -73,7 +73,7 @@ int DeviceEnumeratorSysfs::enumerate() continue; } - std::unique_ptr media = createDevice(devnode); + std::unique_ptr media = createDevice(devnode); if (!media) continue; @@ -93,7 +93,7 @@ int DeviceEnumeratorSysfs::enumerate() return 0; } -int DeviceEnumeratorSysfs::populateMediaDevice(MediaDevice *media) +int DeviceEnumeratorSysfs::populateMediaDevice(MediaDeviceBase *media) { /* Associate entities to device node paths. */ for (MediaEntity *entity : media->entities()) { diff --git a/src/libcamera/device_enumerator_udev.cpp b/src/libcamera/device_enumerator_udev.cpp index 5317afbd..8be8a8d2 100644 --- a/src/libcamera/device_enumerator_udev.cpp +++ b/src/libcamera/device_enumerator_udev.cpp @@ -76,7 +76,7 @@ int DeviceEnumeratorUdev::addUdevDevice(struct udev_device *dev) return -ENODEV; if (!strcmp(subsystem, "media")) { - std::unique_ptr media = + std::unique_ptr media = createDevice(udev_device_get_devnode(dev)); if (!media) return -ENODEV; @@ -193,7 +193,7 @@ done: return 0; } -int DeviceEnumeratorUdev::populateMediaDevice(MediaDevice *media, DependencyMap *deps) +int DeviceEnumeratorUdev::populateMediaDevice(MediaDeviceBase *media, DependencyMap *deps) { std::set children; diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp index 0c67e35d..f41e10c3 100644 --- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp +++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp @@ -865,7 +865,7 @@ bool PipelineHandlerISI::match(DeviceEnumerator *enumerator) dm.add("mxc_isi.0"); dm.add("mxc_isi.0.capture"); - isiDev_ = acquireMediaDevice(enumerator, dm); + isiDev_ = dynamic_cast(acquireMediaDevice(enumerator, dm)); if (!isiDev_) return false; diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index e4d79ea4..c3f3c815 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -923,11 +923,11 @@ bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator) imgu_dm.add("ipu3-imgu 1 viewfinder"); imgu_dm.add("ipu3-imgu 1 3a stat"); - cio2MediaDev_ = acquireMediaDevice(enumerator, cio2_dm); + cio2MediaDev_ = dynamic_cast(acquireMediaDevice(enumerator, cio2_dm)); if (!cio2MediaDev_) return false; - imguMediaDev_ = acquireMediaDevice(enumerator, imgu_dm); + imguMediaDev_ = dynamic_cast(acquireMediaDevice(enumerator, imgu_dm)); if (!imguMediaDev_) return false; diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 8569df17..355cd556 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -1160,7 +1160,7 @@ int PipelineHandlerRPi::queueRequestDevice(Camera *camera, Request *request) bool PipelineHandlerRPi::match(DeviceEnumerator *enumerator) { DeviceMatch unicam("unicam"); - MediaDevice *unicamDevice = acquireMediaDevice(enumerator, unicam); + MediaDevice *unicamDevice = dynamic_cast(acquireMediaDevice(enumerator, unicam)); if (!unicamDevice) { LOG(RPI, Debug) << "Unable to acquire a Unicam instance"; @@ -1168,7 +1168,7 @@ bool PipelineHandlerRPi::match(DeviceEnumerator *enumerator) } DeviceMatch isp("bcm2835-isp"); - MediaDevice *ispDevice = acquireMediaDevice(enumerator, isp); + MediaDevice *ispDevice = dynamic_cast(acquireMediaDevice(enumerator, isp)); if (!ispDevice) { LOG(RPI, Debug) << "Unable to acquire ISP instance"; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index eb9ad65c..c14711ef 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -1146,7 +1146,7 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) dm.add("rkisp1_stats"); dm.add("rkisp1_params"); - media_ = acquireMediaDevice(enumerator, dm); + media_ = dynamic_cast(acquireMediaDevice(enumerator, dm)); if (!media_) return false; diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index a32de7f3..e6f4fad3 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -1391,7 +1391,7 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) for (const SimplePipelineInfo &inf : supportedDevices) { DeviceMatch dm(inf.driver); - media_ = acquireMediaDevice(enumerator, dm); + media_ = dynamic_cast(acquireMediaDevice(enumerator, dm)); if (media_) { info = &inf; break; @@ -1403,7 +1403,7 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) for (const auto &[name, streams] : info->converters) { DeviceMatch converterMatch(name); - converter_ = acquireMediaDevice(enumerator, converterMatch); + converter_ = dynamic_cast(acquireMediaDevice(enumerator, converterMatch)); if (converter_) { numStreams = streams; break; diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 277465b7..b97ec95e 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -389,7 +389,7 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) MediaDevice *media; DeviceMatch dm("uvcvideo"); - media = acquireMediaDevice(enumerator, dm); + media = dynamic_cast(acquireMediaDevice(enumerator, dm)); if (!media) return false; diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 204f5ad7..0aaaa628 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -454,7 +454,7 @@ bool PipelineHandlerVimc::match(DeviceEnumerator *enumerator) dm.add("RGB/YUV Input"); dm.add("Scaler"); - MediaDevice *media = acquireMediaDevice(enumerator, dm); + MediaDevice *media = dynamic_cast(acquireMediaDevice(enumerator, dm)); if (!media) return false; diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index cfade490..613698a1 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -73,7 +73,7 @@ PipelineHandler::PipelineHandler(CameraManager *manager) PipelineHandler::~PipelineHandler() { - for (std::shared_ptr media : mediaDevices_) + for (std::shared_ptr media : mediaDevices_) media->release(); } @@ -126,10 +126,10 @@ PipelineHandler::~PipelineHandler() * * \return A pointer to the matching MediaDevice, or nullptr if no match is found */ -MediaDevice *PipelineHandler::acquireMediaDevice(DeviceEnumerator *enumerator, - const DeviceMatch &dm) +MediaDeviceBase *PipelineHandler::acquireMediaDevice(DeviceEnumerator *enumerator, + const DeviceMatch &dm) { - std::shared_ptr media = enumerator->search(dm); + std::shared_ptr media = enumerator->search(dm); if (!media) return nullptr; @@ -170,7 +170,7 @@ bool PipelineHandler::acquire() return true; } - for (std::shared_ptr &media : mediaDevices_) { + for (std::shared_ptr &media : mediaDevices_) { if (!media->lock()) { unlockMediaDevices(); return false; @@ -223,7 +223,7 @@ void PipelineHandler::releaseDevice([[maybe_unused]] Camera *camera) void PipelineHandler::unlockMediaDevices() { - for (std::shared_ptr &media : mediaDevices_) + for (std::shared_ptr &media : mediaDevices_) media->unlock(); } @@ -556,7 +556,7 @@ void PipelineHandler::registerCamera(std::shared_ptr camera) * to the camera. */ std::vector devnums; - for (const std::shared_ptr &media : mediaDevices_) { + for (const std::shared_ptr &media : mediaDevices_) { for (const MediaEntity *entity : media->entities()) { if (entity->pads().size() == 1 && (entity->pads()[0]->flags() & MEDIA_PAD_FL_SINK) && @@ -582,7 +582,7 @@ void PipelineHandler::registerCamera(std::shared_ptr camera) * handler gets notified and automatically disconnects all the cameras it has * registered without requiring any manual intervention. */ -void PipelineHandler::hotplugMediaDevice(MediaDevice *media) +void PipelineHandler::hotplugMediaDevice(MediaDeviceBase *media) { media->disconnected.connect(this, [=]() { mediaDeviceDisconnected(media); }); } @@ -590,7 +590,7 @@ void PipelineHandler::hotplugMediaDevice(MediaDevice *media) /** * \brief Slot for the MediaDevice disconnected signal */ -void PipelineHandler::mediaDeviceDisconnected(MediaDevice *media) +void PipelineHandler::mediaDeviceDisconnected(MediaDeviceBase *media) { media->disconnected.disconnect(this); From patchwork Thu Jan 5 04:37:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 18090 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 C8E0EC322E for ; Thu, 5 Jan 2023 04:38:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6B54D625EC; Thu, 5 Jan 2023 05:38:03 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1672893483; bh=GuNBnM8YIli9LjDmGBD2BKFpxdW99EHNF6km73MzBEI=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=u1/es4ChIgZtCt9EpCE3YapZIRfEMY8Yne92OQBPvV9P+HjMC+dAFo6njLQuEWhl6 P5O1vYaLdRhFVCQaKhmqsae9Y43TH7csvUPkaSmS/1yYnt38TpwZWongig3vPuLS5J 8aJ8a+EI6JPwPFzrFJ8FSez+QxoD30/SvfI3GOIxMd1L3lvQ45cBtSrYjhOeZDLQT5 Y89K4h8viLNiuz+/M97badTCIVyifxj3unMsTM/swrSZra30fDBs64ZefI7YP6bcDr HilVM6u+an8tox90fRtCMIprx5u8F/tBySy7oAl0EEN3yErFLY6dwU+23GPUcMeqDh eIOAx1p82Onzg== Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6C001625E6 for ; Thu, 5 Jan 2023 05:37:59 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="FvOQpoWh"; dkim-atps=neutral Received: by mail-pj1-x1031.google.com with SMTP id o8-20020a17090a9f8800b00223de0364beso840675pjp.4 for ; Wed, 04 Jan 2023 20:37:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Mg6Iz7qLMP0weZtSTHRkUsspe/eNv2wxFErm5THQt1M=; b=FvOQpoWhCU7f3uF8oZKbJvOCvKj8kmWkNYAU+pseX/U7h5BdFPgEryZIRkBP13TLQ6 kXnikD+buvsqqQTHdmuw331ZkredczNA7VPO7x8CyYP7kInY27+bU86eDaxrMJv1RuAr IfBFe7vSxoTUQOOTA3gW/35LLv+bfcpuMT7AI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Mg6Iz7qLMP0weZtSTHRkUsspe/eNv2wxFErm5THQt1M=; b=jpS69gus/hVdP6LUAPLjUeUZhw3CCVlg2WdzbXAu3i3gfjO5Gpv8hMPdt/C/6XFZpx JlFLNJqgSQbiDy64IHWJwqHuh0hxrbBlkSzXjy9GtBPrBrZsXbBFXgeAlM926ulCYZOn KyHTiXLKcrl9TJWwjLh96OCbZe6Jrm+kW9oFNdgZlbWO41XDrx3K7zhX6wbVa8BcQFNt Bkl+D5eYhSWJp89U3T3kdyMZCsos2BjrOogc+BXC4+9KBo/wzA70QuT+VqKgDsnUhWv7 HJXoujz8kDY9KrPyL+1HPt0rvdpDjm4e2Mn5DKAPL2lt2Cl7rbLhtiBoFE+Mf2YIsO/x P1TQ== X-Gm-Message-State: AFqh2kqRAPQCGV4u2XxYDKqR6u/0XPNN1hbFHhnBcoKxRUKQVadv60sV mJucqrnDQKVly/cCG0a2jvufetzpOo7xoliF X-Google-Smtp-Source: AMrXdXs3lDNnYgemXmBtGBAx681x2UDcEf5dYsJa8qLN76tVCU1ZEaVfCevhedisAvpp/QP3TUpt3g== X-Received: by 2002:a17:902:ccc1:b0:189:5ff5:eb92 with SMTP id z1-20020a170902ccc100b001895ff5eb92mr66563977ple.39.1672893477838; Wed, 04 Jan 2023 20:37:57 -0800 (PST) Received: from chenghaoyang-low.c.googlers.com.com (46.165.189.35.bc.googleusercontent.com. [35.189.165.46]) by smtp.gmail.com with ESMTPSA id x23-20020a170902b41700b00188c5f0f9e9sm25015200plr.199.2023.01.04.20.37.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Jan 2023 20:37:57 -0800 (PST) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Jan 2023 04:37:21 +0000 Message-Id: <20230105043726.679968-5-chenghaoyang@google.com> X-Mailer: git-send-email 2.39.0.314.g84b9a713c41-goog In-Reply-To: <20230105043726.679968-1-chenghaoyang@google.com> References: <20230105043726.679968-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 4/9] libcamera: Add MediaDeviceVirtual 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-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang , Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add a dummy class MediaDeviceVirtual, which will be used in the virtual pipeline handler and unit tests. Signed-off-by: Harvey Yang --- .../libcamera/internal/media_device_virtual.h | 21 ++++++++++++++++++ include/libcamera/internal/meson.build | 1 + src/libcamera/media_device_virtual.cpp | 22 +++++++++++++++++++ src/libcamera/meson.build | 1 + 4 files changed, 45 insertions(+) create mode 100644 include/libcamera/internal/media_device_virtual.h create mode 100644 src/libcamera/media_device_virtual.cpp diff --git a/include/libcamera/internal/media_device_virtual.h b/include/libcamera/internal/media_device_virtual.h new file mode 100644 index 00000000..f1b48b20 --- /dev/null +++ b/include/libcamera/internal/media_device_virtual.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2022, Google Inc. + * + * media_device.h - Media device handler + */ + +#pragma once + +#include "libcamera/internal/media_device_base.h" + +namespace libcamera { + +class MediaDeviceVirtual : public MediaDeviceBase +{ +public: + MediaDeviceVirtual(const std::string &deviceNode); + ~MediaDeviceVirtual(); +}; + +} /* namespace libcamera */ diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build index 826a241c..9deebd01 100644 --- a/include/libcamera/internal/meson.build +++ b/include/libcamera/internal/meson.build @@ -32,6 +32,7 @@ libcamera_internal_headers = files([ 'mapped_framebuffer.h', 'media_device.h', 'media_device_base.h', + 'media_device_virtual.h', 'media_object.h', 'pipeline_handler.h', 'process.h', diff --git a/src/libcamera/media_device_virtual.cpp b/src/libcamera/media_device_virtual.cpp new file mode 100644 index 00000000..ce06a0da --- /dev/null +++ b/src/libcamera/media_device_virtual.cpp @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2022, Google Inc. + * + * media_device.h - Media device handler + */ + +#include "libcamera/internal/media_device_virtual.h" + +namespace libcamera { + +LOG_DEFINE_CATEGORY(MediaDeviceVirtual) + +MediaDeviceVirtual::MediaDeviceVirtual(const std::string &deviceNode) + : MediaDeviceBase(deviceNode) +{ + driver_ = "virtual"; +} + +MediaDeviceVirtual::~MediaDeviceVirtual() = default; + +} /* namespace libcamera */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index ce4c1a29..e0927aee 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -33,6 +33,7 @@ libcamera_sources = files([ 'mapped_framebuffer.cpp', 'media_device.cpp', 'media_device_base.cpp', + 'media_device_virtual.cpp', 'media_object.cpp', 'pipeline_handler.cpp', 'pixel_format.cpp', From patchwork Thu Jan 5 04:37:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 18091 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 A1221C3291 for ; Thu, 5 Jan 2023 04:38:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 20612625EF; Thu, 5 Jan 2023 05:38:04 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1672893484; bh=MiBEvbXlz+1BGq21sH77k9hUxEq8grZsBfiZJbRKcxU=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=FznFSNpl+QAoUc2UHr9lv9vUoB2RZ3tT2mbPjqOQw/uwNDyz7sVTC31SOVOA6Q4Wt l6gjRYbVrmmngWeTWlSljNchTPHdM8A4Av+sKakqAqszeqQAD4Zr76Obiz2mGlKDB7 um6CqAVoFpG0751sp5GnJJpAskZuJv2DSlHZBJ9q3zeiTSZoKvQxwbxgPWbxQ/WwhP ah7fKsfb9p2KHNYiXV1NUxSsdpkhK70kx2xHCENm1j3b/J1oBzx7DlNxmeH74p3c6p mg9N/b4ANytTCcLi0D7AzSeQsmgE1zY8vKfQSzdfTj2NbYW46eNx2vDBPd5BJ3yveG Fde86hKgRDB9w== Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C2FCE625EB for ; Thu, 5 Jan 2023 05:38:00 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="mgnmjeTc"; dkim-atps=neutral Received: by mail-pj1-x102d.google.com with SMTP id v23so38656979pju.3 for ; Wed, 04 Jan 2023 20:38:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=E+5l/E5dTt8O4fLT9DI1XkChOsHxPPry4q2+/5TrVVc=; b=mgnmjeTcBGuzyQIdRZ8iFTVtqhALDHFNBNlrK1hBmXuCiVlLFjt4986uaRWtil0wXH At1K3ps7t17OX1oBe9hahZ1CXkPudC0vbYfdQox3tCBwY1+LqdezQrspn9A5x82b+mJL LQKdPnRRYIH7Xz1V6FFRC7G6cIaxKYJaUaWps= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=E+5l/E5dTt8O4fLT9DI1XkChOsHxPPry4q2+/5TrVVc=; b=hGFG0FKlraeqU/9K2LsaY4uHdMo/CSZV/ktZ8Bl7O3dWXMNnP1hTb0rSOw9tZf6XQE +MzwxrolTqShQ+GXvm1p4B/WlfzPn9JqPZuSPdH5aLVUjVBSv5GeS2/VFDEW9JWaCSTg lbaWQ2qwJkp7gcvkFCEBdhYzNV6eEafY00vD/c6OB+jo6FIIDn/OZ++ewfScpHRNqKd5 dhOMV9gzeffu3jivsjdRDB95HoI4JwCTzdi4t1H5RD9Ke23s9MqBgvcspm9DmraDx0mS PcSsBMCyrU0hxUBUnWBnQxCv5uiejTg5MJm9n0GIZo2gbAr6hX/Nw2psKKH7Li93f7t6 NuDA== X-Gm-Message-State: AFqh2kpAi/eTSeS+6rht6yDF7heCWPLoN0t3e8q6BkElLQNbmPy/cVrZ +Z9ynusMtbB4aKdoDvZik6oBW6fosTftEcfL X-Google-Smtp-Source: AMrXdXvheJDHcDMNIN7hvtKw0KqudVs7YWUrGsYtLiJAz+B1uyGIJSYhsqIbViNl5ZBSdt/mOowk9g== X-Received: by 2002:a17:902:ab1a:b0:192:9924:ce7e with SMTP id ik26-20020a170902ab1a00b001929924ce7emr25846518plb.55.1672893479162; Wed, 04 Jan 2023 20:37:59 -0800 (PST) Received: from chenghaoyang-low.c.googlers.com.com (46.165.189.35.bc.googleusercontent.com. [35.189.165.46]) by smtp.gmail.com with ESMTPSA id x23-20020a170902b41700b00188c5f0f9e9sm25015200plr.199.2023.01.04.20.37.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Jan 2023 20:37:58 -0800 (PST) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Jan 2023 04:37:22 +0000 Message-Id: <20230105043726.679968-6-chenghaoyang@google.com> X-Mailer: git-send-email 2.39.0.314.g84b9a713c41-goog In-Reply-To: <20230105043726.679968-1-chenghaoyang@google.com> References: <20230105043726.679968-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 5/9] libcamera: pipeline: virtual: Add MediaDeviceVirtual 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-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang , Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add a dummy MediaDeviceVirtual in PipelineHandlerVirtual::match, to avoid having no MediaDevice in the pipeline handler. Signed-off-by: Harvey Yang --- include/libcamera/internal/device_enumerator.h | 2 +- include/libcamera/internal/pipeline_handler.h | 2 +- src/libcamera/pipeline/virtual/virtual.cpp | 9 +++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/libcamera/internal/device_enumerator.h b/include/libcamera/internal/device_enumerator.h index 87a2b5ce..e5eb3e94 100644 --- a/include/libcamera/internal/device_enumerator.h +++ b/include/libcamera/internal/device_enumerator.h @@ -41,13 +41,13 @@ public: virtual int init() = 0; virtual int enumerate() = 0; + void addDevice(std::unique_ptr media); std::shared_ptr search(const DeviceMatch &dm); Signal<> devicesAdded; protected: std::unique_ptr createDevice(const std::string &deviceNode); - void addDevice(std::unique_ptr media); void removeDevice(const std::string &deviceNode); private: diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index 1223b1cb..09004365 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -77,6 +77,7 @@ protected: virtual void releaseDevice(Camera *camera); CameraManager *manager_; + std::vector> mediaDevices_; private: void unlockMediaDevices(); @@ -87,7 +88,6 @@ private: void doQueueRequest(Request *request); void doQueueRequests(); - std::vector> mediaDevices_; std::vector> cameras_; std::queue waitingRequests_; diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp index 09583b4e..6221196c 100644 --- a/src/libcamera/pipeline/virtual/virtual.cpp +++ b/src/libcamera/pipeline/virtual/virtual.cpp @@ -9,6 +9,7 @@ #include +#include "libcamera/internal/media_device_virtual.h" #include "libcamera/internal/pipeline_handler.h" namespace libcamera { @@ -41,6 +42,9 @@ public: int queueRequestDevice(Camera *camera, Request *request) override; bool match(DeviceEnumerator *enumerator) override; + +private: + std::shared_ptr mediaDeviceVirtual_; }; VirtualCameraConfiguration::VirtualCameraConfiguration() @@ -54,7 +58,7 @@ CameraConfiguration::Status VirtualCameraConfiguration::validate() } PipelineHandlerVirtual::PipelineHandlerVirtual(CameraManager *manager) - : PipelineHandler(manager) + : PipelineHandler(manager), mediaDeviceVirtual_(new MediaDeviceVirtual("virtual")) { } @@ -104,7 +108,8 @@ int PipelineHandlerVirtual::queueRequestDevice(Camera *camera, Request *request) bool PipelineHandlerVirtual::match(DeviceEnumerator *enumerator) { (void)enumerator; - return false; + mediaDevices_.push_back(mediaDeviceVirtual_); + return false; // Prevent infinite loops for now } REGISTER_PIPELINE_HANDLER(PipelineHandlerVirtual) From patchwork Thu Jan 5 04:37:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 18092 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 7CA83C322E for ; Thu, 5 Jan 2023 04:38:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EE5D3625F3; Thu, 5 Jan 2023 05:38:04 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1672893485; bh=8tx+Ta0U0Hr9zT1hQ96lmBQ3IGWjpjxzTmFKfRIMDKg=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=Ey6nUb+yTXakdoR461aYr4l2gcX6I9ZuAB7LbH+SvC2FJyphnDGr+nSWWUHICQOOy v/LWLM3vSbhPsmh9lM5Q36i8DV2itkyOmzvtIs/aGU6Bbg8Hl4I0KQ2Bb9ITiiIsFz AvlHHDGxsL1ARnkT+KHlfOmv5VsazRfG8VTAS5dEzMbL1mv7SwFcgQKP/Fq1YtUCJ/ CsnSVE4ySBDdZBubVc/E35yae2z95H6iG7EI+vE0jRiwciQKZMPF5437/7XUXD18as I9Rx6BbVwfTG/B2zmSHNquje+i2ZjE7tkjSyxWJ4e+5WUkI8NQwlNWYjeja7/uByU4 AFjzvot5Kpi3A== Received: from mail-pj1-x102f.google.com (mail-pj1-x102f.google.com [IPv6:2607:f8b0:4864:20::102f]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 19F73625E0 for ; Thu, 5 Jan 2023 05:38:02 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="TBcRpZwk"; dkim-atps=neutral Received: by mail-pj1-x102f.google.com with SMTP id v13-20020a17090a6b0d00b00219c3be9830so865525pjj.4 for ; Wed, 04 Jan 2023 20:38:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=J6oOo866++nJiEAfXkWSZqYz/D100v7GE53q9RtFW/E=; b=TBcRpZwkWEaAL96hfM/DeXb8hSg0nhZ90DbLyVVId7M7oDiwYvYJE7U6TEBGu9HuN8 /Rbv2ayz/95DxtqsPNDrCcNdVo4Atd8h5HxtX4mgDjVnkU+KTegO5nLKdmvXHAQ9+A0h iMNO5FM5BEILtzAmGH+j83w8bYXUx5/8AIKdM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=J6oOo866++nJiEAfXkWSZqYz/D100v7GE53q9RtFW/E=; b=7V/UbFwE1r/ZaZPCmepZLheVz2HjXAwR7OxfpM2i5etv85TiSyYA498vmrWCIAOkAQ bViIadpWI9p/or5/kXPDg41PQKiK0gERIDe+EeuKrkPVM0g1HzRNAPdfBxVv6uLTfTIm et6cNMZVNY12lG2nOZ249iijNVbofoenMDwsm0GM3EQHfmNwy/4P4N8oKBEzS/VY6322 rDWmY9x4GAojUhxHYbaQQIWSEv5gqh7TdPMSKh7RBtoliZjgrL6shPLK54JHQDhqzR1T JydJnNwnfhSkBXGmmiI4jikXU1erb9W0SCzHiBS/exte0/jG8/pC5YPkkXsT/ThCnKmr Y9DA== X-Gm-Message-State: AFqh2krjQha5JCrw4zpXA3RsJLUvmBzcHuSeqbShsQsa7aIfmuQQssEd 6ZpKO3ntCTk+FnKrwRw2rHY4QMUV+6UzQ4S5 X-Google-Smtp-Source: AMrXdXunX/QN9W0rb/VT/5iuhm8gnNJTtb3Dx6EfOzXqh0blEpiumX8Xa015uJYc+bpNqd7vHNPHZQ== X-Received: by 2002:a17:903:1c3:b0:192:903f:7ac9 with SMTP id e3-20020a17090301c300b00192903f7ac9mr47906740plh.42.1672893480306; Wed, 04 Jan 2023 20:38:00 -0800 (PST) Received: from chenghaoyang-low.c.googlers.com.com (46.165.189.35.bc.googleusercontent.com. [35.189.165.46]) by smtp.gmail.com with ESMTPSA id x23-20020a170902b41700b00188c5f0f9e9sm25015200plr.199.2023.01.04.20.37.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Jan 2023 20:38:00 -0800 (PST) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Jan 2023 04:37:23 +0000 Message-Id: <20230105043726.679968-7-chenghaoyang@google.com> X-Mailer: git-send-email 2.39.0.314.g84b9a713c41-goog In-Reply-To: <20230105043726.679968-1-chenghaoyang@google.com> References: <20230105043726.679968-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 6/9] libcamera: pipeline: virtual: Create a 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-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang , Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Create a VirtualCameraData inheriting from the CameraData to handle camera specific data, and use it to create and register the camera with the CameraManager. This can now be tested to see that the camera becomes available to applications: """ build/src/apps/cam/cam -l [550:47:04.505850647] [1969734] INFO IPAManager ipa_manager.cpp:143 libcamera is not installed. Adding ... to the IPA search path [550:47:04.509307667] [1969734] INFO Camera camera_manager.cpp:293 libcamera v0.0.1+54-55fecb4d-dirty (2022-12-01T05:47:11+00:00) Available cameras: 1: (Virtual0) """ Signed-off-by: Harvey Yang --- src/libcamera/pipeline/virtual/virtual.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp index 6221196c..ba77d757 100644 --- a/src/libcamera/pipeline/virtual/virtual.cpp +++ b/src/libcamera/pipeline/virtual/virtual.cpp @@ -9,6 +9,7 @@ #include +#include "libcamera/internal/camera.h" #include "libcamera/internal/media_device_virtual.h" #include "libcamera/internal/pipeline_handler.h" @@ -16,6 +17,19 @@ namespace libcamera { LOG_DEFINE_CATEGORY(VIRTUAL) +class VirtualCameraData : public Camera::Private +{ +public: + VirtualCameraData(PipelineHandler *pipe) + : Camera::Private(pipe) + { + } + + ~VirtualCameraData() = default; + + Stream stream_; +}; + class VirtualCameraConfiguration : public CameraConfiguration { public: @@ -109,6 +123,14 @@ bool PipelineHandlerVirtual::match(DeviceEnumerator *enumerator) { (void)enumerator; mediaDevices_.push_back(mediaDeviceVirtual_); + + std::unique_ptr data = std::make_unique(this); + /* Create and register the camera. */ + std::set streams{ &data->stream_ }; + const std::string id = "Virtual0"; + std::shared_ptr camera = Camera::create(std::move(data), id, streams); + registerCamera(std::move(camera)); + return false; // Prevent infinite loops for now } From patchwork Thu Jan 5 04:37:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 18093 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 B84C6C322E for ; Thu, 5 Jan 2023 04:38:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 70FD1625E4; Thu, 5 Jan 2023 05:38:07 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1672893487; bh=APeQXA7xUzqatN2KHkXdArmpDV/MRE+qbbFiX/hrdv8=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=23G6OdybxcmqwyYPVYFrt5S9BmPySA+oWuJqcnp1GypJfmOt/kLhnI36HxlX9fdOo sSvH0l5VKfySDju4tSOiVTcLfb1OeX9OtWjexhJoLcKNkCK1pkLnSFTy0u6tTQ0Ckg SrH3OHlypZNfejUs0zUb/u5Utxi3o9jVIBUf/zP4a/GhHeKIedghfn28YRzI0ORsbH zbZBZl7Dd92OjiHs3ILa84bKrApQ590jXvJh56rycfLlXqmiH7SA3gYJ/uIm44DEVF LdvvApU8AMzPGeDQA1qdscAW225wpI+Xo/UrCSJi6fGhUq3s8snuYhuRE3SJBAmsTb UWbDRtSeDNjpw== Received: from mail-pl1-x62b.google.com (mail-pl1-x62b.google.com [IPv6:2607:f8b0:4864:20::62b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 425AF625E0 for ; Thu, 5 Jan 2023 05:38:03 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="Fi2lJI5k"; dkim-atps=neutral Received: by mail-pl1-x62b.google.com with SMTP id p24so15732750plw.11 for ; Wed, 04 Jan 2023 20:38:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=xZUF8kLRelIKfAN12rHK0VQVbiYV9PuXYXL0Rf+v8Rk=; b=Fi2lJI5kCGbH/7HWTgP9co2eC3tW/3DNU86amBvu+zkExsN3gbWMKYlCznv/PFeFVj lkTeFS6e2NopgqEEoE9YxyTmuCbM5EmjMRI0rWTCY4l5nMFICRjwFyMbJ0X2PQRu6jfC nyc19F77u/u0LV3JMGqZppcbBQbVW0bzhkH9Y= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=xZUF8kLRelIKfAN12rHK0VQVbiYV9PuXYXL0Rf+v8Rk=; b=VQ962qSUziS2oR2KhpQ0HylcN8X95b/I8xaM7XUmegN0zXiO3tl2rTSKrHq3EdptC/ 9aL+qsP3osArZB6734dYCSCrok0MruPLjyPyTS6z5J8p4eU/ZRxkf4aXzn5L2CjHFyfE wt+81IHpFQktTwd0Ty5qCvaTCKPNfhPrX5Rwg+25Y3JV8XOAR1e+uenSqcwrhiCEQLiz 3DPTK4sxw5e/WMlXpCudU3Bcw+xznB4Q/LyK9eO1Er5qpfwFyhf37txyHeNmJSt00tbc swOWZe2LIIVJrmugs4cIHz4rBj8f6WOMknaGPMaGta9cP2RBhzqpX0yp/Yq30qnYwKiP 6jGw== X-Gm-Message-State: AFqh2kp/fNC04++H1oPD9XQcn5GT6IeowYK0BsD971nyNUznZ9Qpn1g2 /2l/V2YBnK8blmpBg8/dZBKvSYX1dfVwNjHH X-Google-Smtp-Source: AMrXdXtErhSQyT6DVZILd0e27UaMzOCyd4pEOUzNGEKs3Diu2aUpVaSg/bPswrloVdWVEXthuPdXOA== X-Received: by 2002:a17:902:ccc1:b0:189:5ff5:eb92 with SMTP id z1-20020a170902ccc100b001895ff5eb92mr66564137ple.39.1672893481480; Wed, 04 Jan 2023 20:38:01 -0800 (PST) Received: from chenghaoyang-low.c.googlers.com.com (46.165.189.35.bc.googleusercontent.com. [35.189.165.46]) by smtp.gmail.com with ESMTPSA id x23-20020a170902b41700b00188c5f0f9e9sm25015200plr.199.2023.01.04.20.38.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Jan 2023 20:38:01 -0800 (PST) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Jan 2023 04:37:24 +0000 Message-Id: <20230105043726.679968-8-chenghaoyang@google.com> X-Mailer: git-send-email 2.39.0.314.g84b9a713c41-goog In-Reply-To: <20230105043726.679968-1-chenghaoyang@google.com> References: <20230105043726.679968-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 7/9] libcamera: pipeline: virtual: Generate and validate StreamConfigurations 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-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang , Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Implement the support for Generating and Validating the streams the Camera can provide. Currently use only one camera with fixed configuration. Will add a configuration file to specify virtual cameras. In |PipelineHandlerVirtual::configure|, nothing needs to be done. Test the configurations can be generated and reported with cam -I: """ build/src/apps/cam/cam -c 1 -I [45:19:28.901456135] [2611530] INFO IPAManager ipa_manager.cpp:143 libcamera is not installed. Adding '/usr/local/google/home/chenghaoyang/cros2/src/third_party/libcamera/build/src /ipa' to the IPA search path [45:19:28.904364465] [2611530] INFO Camera camera_manager.cpp:293 libcamera v0.0.1+56-4f4554fa-dirty (2022-12-07T06:55:04+00:00) Using camera Virtual0 as cam0 0: 1920x1080-NV12 * Pixelformat: NV12 (1280x720)-(1920x1080)/(+1,+1) - 1280x720 - 1280x800 - 1360x768 - 1366x768 - 1440x900 - 1280x1024 - 1536x864 - 1280x1080 - 1600x900 - 1400x1050 - 1680x1050 - 1920x1080 """ Signed-off-by: Harvey Yang --- src/libcamera/pipeline/virtual/virtual.cpp | 140 +++++++++++++++++++-- 1 file changed, 132 insertions(+), 8 deletions(-) diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp index ba77d757..ef2901e7 100644 --- a/src/libcamera/pipeline/virtual/virtual.cpp +++ b/src/libcamera/pipeline/virtual/virtual.cpp @@ -8,6 +8,7 @@ #include #include +#include #include "libcamera/internal/camera.h" #include "libcamera/internal/media_device_virtual.h" @@ -20,6 +21,11 @@ LOG_DEFINE_CATEGORY(VIRTUAL) class VirtualCameraData : public Camera::Private { public: + struct Resolution { + Size size; + std::vector frame_rates; + std::vector formats; + }; VirtualCameraData(PipelineHandler *pipe) : Camera::Private(pipe) { @@ -27,15 +33,22 @@ public: ~VirtualCameraData() = default; + std::vector supportedResolutions_; + Stream stream_; }; class VirtualCameraConfiguration : public CameraConfiguration { public: - VirtualCameraConfiguration(); + static constexpr unsigned int kBufferCount = 4; // 4~6 + + VirtualCameraConfiguration(VirtualCameraData *data); Status validate() override; + +private: + const VirtualCameraData *data_; }; class PipelineHandlerVirtual : public PipelineHandler @@ -58,17 +71,56 @@ public: bool match(DeviceEnumerator *enumerator) override; private: + VirtualCameraData *cameraData(Camera *camera) + { + return static_cast(camera->_d()); + } + std::shared_ptr mediaDeviceVirtual_; }; -VirtualCameraConfiguration::VirtualCameraConfiguration() - : CameraConfiguration() +VirtualCameraConfiguration::VirtualCameraConfiguration(VirtualCameraData *data) + : CameraConfiguration(), data_(data) { } CameraConfiguration::Status VirtualCameraConfiguration::validate() { - return Invalid; + Status status = Valid; + + if (config_.empty()) { + LOG(VIRTUAL, Error) << "Empty config"; + return Invalid; + } + + // TODO: check if we should limit |config_.size()| + + Size maxSize; + for (const auto &resolution : data_->supportedResolutions_) + maxSize = std::max(maxSize, resolution.size); + + for (StreamConfiguration &cfg : config_) { + // TODO: check |cfg.pixelFormat|. + + bool found = false; + for (const auto &resolution : data_->supportedResolutions_) { + if (resolution.size.width >= cfg.size.width && resolution.size.height >= cfg.size.height) { + found = true; + break; + } + } + + if (!found) { + cfg.size = maxSize; + status = Adjusted; + } + + cfg.setStream(const_cast(&data_->stream_)); + + cfg.bufferCount = VirtualCameraConfiguration::kBufferCount; + } + + return status; } PipelineHandlerVirtual::PipelineHandlerVirtual(CameraManager *manager) @@ -79,16 +131,81 @@ PipelineHandlerVirtual::PipelineHandlerVirtual(CameraManager *manager) std::unique_ptr PipelineHandlerVirtual::generateConfiguration(Camera *camera, const StreamRoles &roles) { - (void)camera; - (void)roles; - return std::unique_ptr(nullptr); + VirtualCameraData *data = cameraData(camera); + auto config = + std::make_unique(data); + + if (roles.empty()) + return config; + + Size minSize, sensorResolution; + for (const auto &resolution : data->supportedResolutions_) { + if (minSize.isNull() || minSize > resolution.size) + minSize = resolution.size; + + sensorResolution = std::max(sensorResolution, resolution.size); + } + + for (const StreamRole role : roles) { + std::map> streamFormats; + unsigned int bufferCount; + PixelFormat pixelFormat; + + switch (role) { + case StreamRole::StillCapture: + pixelFormat = formats::NV12; + bufferCount = VirtualCameraConfiguration::kBufferCount; + streamFormats[pixelFormat] = { { minSize, sensorResolution } }; + + break; + + case StreamRole::Raw: { + // TODO: check + pixelFormat = formats::SBGGR10; + bufferCount = VirtualCameraConfiguration::kBufferCount; + streamFormats[pixelFormat] = { { minSize, sensorResolution } }; + + break; + } + + case StreamRole::Viewfinder: + case StreamRole::VideoRecording: { + pixelFormat = formats::NV12; + bufferCount = VirtualCameraConfiguration::kBufferCount; + streamFormats[pixelFormat] = { { minSize, sensorResolution } }; + + break; + } + + default: + LOG(VIRTUAL, Error) + << "Requested stream role not supported: " << role; + config.reset(); + return config; + } + + StreamFormats formats(streamFormats); + StreamConfiguration cfg(formats); + cfg.size = sensorResolution; + cfg.pixelFormat = pixelFormat; + cfg.bufferCount = bufferCount; + config->addConfiguration(cfg); + } + + if (config->validate() == CameraConfiguration::Invalid) { + config.reset(); + return config; + } + + return config; } int PipelineHandlerVirtual::configure(Camera *camera, CameraConfiguration *config) { (void)camera; (void)config; - return -1; + // Nothing to be done. + return 0; } int PipelineHandlerVirtual::exportFrameBuffers(Camera *camera, Stream *stream, @@ -124,7 +241,14 @@ bool PipelineHandlerVirtual::match(DeviceEnumerator *enumerator) (void)enumerator; mediaDevices_.push_back(mediaDeviceVirtual_); + // TODO: Add virtual cameras according to a config file. + std::unique_ptr data = std::make_unique(this); + + data->supportedResolutions_.resize(2); + data->supportedResolutions_[0] = { .size = Size(1920, 1080), .frame_rates = { 30 }, .formats = { "YCbCr_420_888" } }; + data->supportedResolutions_[1] = { .size = Size(1280, 720), .frame_rates = { 30, 60 }, .formats = { "YCbCr_420_888" } }; + /* Create and register the camera. */ std::set streams{ &data->stream_ }; const std::string id = "Virtual0"; From patchwork Thu Jan 5 04:37:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 18094 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 4CC1EC3291 for ; Thu, 5 Jan 2023 04:38:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 08999625F1; Thu, 5 Jan 2023 05:38:08 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1672893488; bh=mr5Sbr6Ad9FB1rrja5XwMm7+L+S22BtkUvzG9n9Aj04=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=PnSUeEMpZZXtz8DZrFohMknjUyY2Nd8g8RxrI88+SahCAEUeUy9X2yGSM8/j8MBVv 10hOGE9SOsPesmKTSBWiNffUOHGw/yXMV0Ky2ZrizjqUwhQpKZyn5L+eynlcfLwO+R oudl8l8DCNRTdeujIj2vLhaET34LcFathtxahSHsOnvVOK32kEJ9UW2v22dZTK7Ikj CPtc36DWx1xjklAEIxmMOB4m6DIQprN3fyEPZTTptKCPGO6kc/fp+dPPgDnBTkPbzW lyJjaGWEd9viYyH7wHx6blOE1TC9/KM3pUEU0qUnhmeOQpoDoBHM0kTuLhBcYXCB9q q6o0iNRVsvusw== Received: from mail-pj1-x1036.google.com (mail-pj1-x1036.google.com [IPv6:2607:f8b0:4864:20::1036]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6340B625F1 for ; Thu, 5 Jan 2023 05:38:03 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="ZQCkgI8I"; dkim-atps=neutral Received: by mail-pj1-x1036.google.com with SMTP id c2-20020a17090a020200b00226c762ed23so861829pjc.5 for ; Wed, 04 Jan 2023 20:38:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=hd42uG5tbVV4XTVn78gvQUXhPXrwSqPdQZFKksMQ2iI=; b=ZQCkgI8IG7n/XNiVoqiKsdRh9foZTg6vaeNRwZZwHcJvaZWHldWKtnbbrcRlbCPg/2 i9g1feXk4h4awnGT4t7RDwN/Mav+p5H06ufdMv7VCptfwGr82TIE+tBqwJFhUxTquwr2 wcgT6NH/BiPrc3VCitvdU73hiUfOFNvHojLdA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hd42uG5tbVV4XTVn78gvQUXhPXrwSqPdQZFKksMQ2iI=; b=hq0gG2EYuQpEGYyJQMtuF7vsZxefuRBW6W8verK0KAaumEds33N+Ykiz5DmunSCLOV u8CebLY/yZwr4p/MI74uHo0rtAmFnDqSFlAp9W50944GSp52+3TJkwOeMWZPRwUYLT2c DrS1qiQuJy+tyUScxGwi05ea+mpIOSwCkbtGgMOaHyCBB6NWXXrp0Lp20jryYVGbIbgU 5e8Zk1I5/LoADnp+DKblAf1DEepaKAuKCkM5VpHltoRyvt3Isbp3cgoevp4FKKikOlmq PS3bpe28WOrAJ6CXnYdQqJ1u0Ow65b/7SriyaXcfGcmE5BSN1IwSAi9WOwdpcIfhIlUC s7Ag== X-Gm-Message-State: AFqh2krJ83M+KKKB9rJaT4yAB/wOY8Kl9UsMFjDg/ikguXpvQm/EnIjw PeSRu0JyBlEBR/UZ93hT0VlabSg8GS9KxN9O X-Google-Smtp-Source: AMrXdXv7NvyAuNyUyTkT5Y1BoB23gB1p87N74+GkXypPpOAKGIqLtMGx5VdRwgJKvCDa/KSU5QHRqA== X-Received: by 2002:a05:6a21:99a4:b0:a3:94cd:1435 with SMTP id ve36-20020a056a2199a400b000a394cd1435mr81893332pzb.38.1672893482748; Wed, 04 Jan 2023 20:38:02 -0800 (PST) Received: from chenghaoyang-low.c.googlers.com.com (46.165.189.35.bc.googleusercontent.com. [35.189.165.46]) by smtp.gmail.com with ESMTPSA id x23-20020a170902b41700b00188c5f0f9e9sm25015200plr.199.2023.01.04.20.38.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Jan 2023 20:38:02 -0800 (PST) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Jan 2023 04:37:25 +0000 Message-Id: <20230105043726.679968-9-chenghaoyang@google.com> X-Mailer: git-send-email 2.39.0.314.g84b9a713c41-goog In-Reply-To: <20230105043726.679968-1-chenghaoyang@google.com> References: <20230105043726.679968-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 8/9] libcamera: pipeline: virtual: Queue requests 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-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang , Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" [todo Use UDMA to allocate buffers in the exportFrameBuffers API] [todo Read frames from the virtual video if any] Currently we only use external buffers and complete them immediately with green frames. Signed-off-by: Harvey Yang --- src/libcamera/pipeline/virtual/virtual.cpp | 29 +++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp index ef2901e7..db6fe14c 100644 --- a/src/libcamera/pipeline/virtual/virtual.cpp +++ b/src/libcamera/pipeline/virtual/virtual.cpp @@ -8,6 +8,8 @@ #include #include +#include +#include #include #include "libcamera/internal/camera.h" @@ -18,6 +20,17 @@ namespace libcamera { LOG_DEFINE_CATEGORY(VIRTUAL) +uint64_t CurrentTimestamp() +{ + struct timespec ts; + if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) { + LOG(VIRTUAL, Error) << "Get clock time fails"; + return 0; + } + + return ts.tv_sec * 1'000'000'000LL + ts.tv_nsec; +} + class VirtualCameraData : public Camera::Private { public: @@ -214,6 +227,7 @@ int PipelineHandlerVirtual::exportFrameBuffers(Camera *camera, Stream *stream, (void)camera; (void)stream; (void)buffers; + // TODO: Use UDMA to allocate buffers. return -1; } @@ -221,19 +235,28 @@ int PipelineHandlerVirtual::start(Camera *camera, const ControlList *controls) { (void)camera; (void)controls; - return -1; + // TODO: Start reading the virtual video if any. + return 0; } void PipelineHandlerVirtual::stopDevice(Camera *camera) { (void)camera; + // TODO: Reset the virtual video if any. } int PipelineHandlerVirtual::queueRequestDevice(Camera *camera, Request *request) { (void)camera; - (void)request; - return -1; + + // TODO: Read from the virtual video if any. + for (auto it : request->buffers()) + completeBuffer(request, it.second); + + request->metadata().set(controls::SensorTimestamp, CurrentTimestamp()); + completeRequest(request); + + return 0; } bool PipelineHandlerVirtual::match(DeviceEnumerator *enumerator) From patchwork Thu Jan 5 04:37:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 18095 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 CE0F3C3292 for ; Thu, 5 Jan 2023 04:38:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 82307625FD; Thu, 5 Jan 2023 05:38:08 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1672893488; bh=CkyxTn6n0AAiFnrLaW8GKfez29P9A54x6SYJExejOi8=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=tESrlmipitcSczRytIDNxe48RRPrdb/G3R9+VoHslbGeW65+ntOmaLNTn5yYpQk4S z0MqSHjlQn9Kw0SAdFN/6juLdko3yQKdvFrSgkdflRsrCdJcH5AOXvW5AtU37EO2IW zW+y5GPVSA5gusbkj+4rCAjt4zbOK9upvgCqAvr60RrDGwj+LGU2WZjkfth9JW30NM xr6/I/WK1Lhkf+7FE8K6IIeZKjTJO6XqI8hoZ+aFHpfhUoRRHnNmVPCe8KJ2n9yGAP WfhvyRB85zMXlnHzeVd9lRnva7qfqPhL9VIPjx32vpDda39CkHc5qvHqYfxyQZC0PQ RP/53nX0x8zHA== Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B6552625E0 for ; Thu, 5 Jan 2023 05:38:05 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="T6JohQQM"; dkim-atps=neutral Received: by mail-pj1-x102b.google.com with SMTP id q64so209644pjq.4 for ; Wed, 04 Jan 2023 20:38:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=rtUHUJiSnMDtdnPKjGrXewZAUK+DgyGNd3X25jltl2g=; b=T6JohQQMeHEIMcOvMl/ZkK8spCppWZZQzl9j+v2HUyl+qcXnV4M/acUasBTJBtUtP4 mWDSp3kI+OYWsvOQgXIkQSn9ttywIhNOlRp/Z9f8c9OhRF2FBJKeZrpE9rrNtu6HtTqM LovOaAh3dbcdbT4iWnZiQkDK04D+wbhTGs0Wc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rtUHUJiSnMDtdnPKjGrXewZAUK+DgyGNd3X25jltl2g=; b=Lt9zcJBMmoImtlRkIMboJ+Xmu2YKvbGfcO9CUDzz98SPn4D6Q/pBAV8axNYBoe6lEg ezekf3zS+XE5FRyjIdlvXefYG0L3D4Wct1HizQsPqQi9KvSNyrNctfIaw5Poc2Fmuf9s 8b9LdonuyJvX9c8kn6CASMhPr0CV0KEKFioMfZZBjxFXMXi0UJYbYElOWlVoywGdX2Co 6++NoDecqXEC0UOLkwLV6Ezs2rQ2chd9RhmnTdmUAI6aFDJYxHjw7r958tm7YcsdlBFU JIX5s5X7zluvlHIRNcdKh3+lFk2awk7F8bYTkpXQXsOBEFsPEhw1qstrhN9a0lt0oNVj mBJA== X-Gm-Message-State: AFqh2krEr24BC5sTs2JSPDwRNs6KoVdsYrluq9UWjKnZDVQPmwRGkEoF VDscLcjkTjpZOuqyxpMKdCEzoerAExOp9PvE X-Google-Smtp-Source: AMrXdXtZCFrJ/K5cGmK5YRegqrARLHLek9MGmFIBNK5uV6f8XFqsGZNbTptog3hExRoBjtNn4BlqFQ== X-Received: by 2002:a17:903:264b:b0:185:441e:90b4 with SMTP id je11-20020a170903264b00b00185441e90b4mr44776090plb.26.1672893483887; Wed, 04 Jan 2023 20:38:03 -0800 (PST) Received: from chenghaoyang-low.c.googlers.com.com (46.165.189.35.bc.googleusercontent.com. [35.189.165.46]) by smtp.gmail.com with ESMTPSA id x23-20020a170902b41700b00188c5f0f9e9sm25015200plr.199.2023.01.04.20.38.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Jan 2023 20:38:03 -0800 (PST) X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Jan 2023 04:37:26 +0000 Message-Id: <20230105043726.679968-10-chenghaoyang@google.com> X-Mailer: git-send-email 2.39.0.314.g84b9a713c41-goog In-Reply-To: <20230105043726.679968-1-chenghaoyang@google.com> References: <20230105043726.679968-1-chenghaoyang@google.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 9/9] libcamera: pipeline: virtual: Set camera properties & controls 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-Patchwork-Original-From: Harvey Yang via libcamera-devel From: Cheng-Hao Yang Reply-To: Harvey Yang Cc: Harvey Yang , Harvey Yang Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Initialize the CameraData properties with Location, Model, and PixelArrayActiveAreas, and the control attribute: FrameDurationLimits. Updating `/etc/camera/libcamera/camera_hal.yaml` on a chromebook DUT is required to find the virtual camera with id `Virtual0`. Signed-off-by: Harvey Yang --- src/libcamera/pipeline/virtual/virtual.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp index db6fe14c..d56989b2 100644 --- a/src/libcamera/pipeline/virtual/virtual.cpp +++ b/src/libcamera/pipeline/virtual/virtual.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "libcamera/internal/camera.h" #include "libcamera/internal/media_device_virtual.h" @@ -20,6 +21,10 @@ namespace libcamera { LOG_DEFINE_CATEGORY(VIRTUAL) +static const ControlInfoMap::Map VirtualControls = { + { &controls::draft::PipelineDepth, ControlInfo(2, 3) }, +}; + uint64_t CurrentTimestamp() { struct timespec ts; @@ -272,6 +277,16 @@ bool PipelineHandlerVirtual::match(DeviceEnumerator *enumerator) data->supportedResolutions_[0] = { .size = Size(1920, 1080), .frame_rates = { 30 }, .formats = { "YCbCr_420_888" } }; data->supportedResolutions_[1] = { .size = Size(1280, 720), .frame_rates = { 30, 60 }, .formats = { "YCbCr_420_888" } }; + data->properties_.set(properties::Location, properties::CameraLocationFront); + data->properties_.set(properties::Model, "Virtual Video Device"); + data->properties_.set(properties::PixelArrayActiveAreas, { Rectangle(Size(1920, 1080)) }); + + // TODO: Set FrameDurationLimits based on config. + ControlInfoMap::Map controls = VirtualControls; + int64_t min_frame_duration = 30, max_frame_duration = 60; + controls[&controls::FrameDurationLimits] = ControlInfo(min_frame_duration, max_frame_duration); + data->controlInfo_ = ControlInfoMap(std::move(controls), controls::controls); + /* Create and register the camera. */ std::set streams{ &data->stream_ }; const std::string id = "Virtual0";