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',