From patchwork Wed Nov 6 17:35:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 21817 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 B5453BDB13 for ; Wed, 6 Nov 2024 17:37:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7CD0965434; Wed, 6 Nov 2024 18:37:01 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="ZtJ07MjL"; dkim-atps=neutral Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EDFEF653C5 for ; Wed, 6 Nov 2024 18:36:58 +0100 (CET) Received: by mail-pj1-x1029.google.com with SMTP id 98e67ed59e1d1-2e2e8c8915eso44585a91.3 for ; Wed, 06 Nov 2024 09:36:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1730914617; x=1731519417; darn=lists.libcamera.org; 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=Mmt8xNR5TxiZqXeDF8uJiF4BykrrWATBKTdFJk8Vzrs=; b=ZtJ07MjLf62Atw6UGhoM3rA9J9NrCIowYn8jLGUYfy9zx/l6rV634V0DwKOw7skW2H 8xK1cMN4r5OQyRgra7y54BjFMk1pKqyuGZHRb1aK2csdmWzuwN5jGboLxAFlcByOGcIT sfJjfELiu0zXxT4+ph0IH8V11qIdkbrdpW5ng= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730914617; x=1731519417; 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=Mmt8xNR5TxiZqXeDF8uJiF4BykrrWATBKTdFJk8Vzrs=; b=Oo8rcutls0KHsx1TGqVaMsHWwZHQ3I4mBTRI1FM8BkZhA9+6v3vSbX6sX0Y0xCn+mP g8a1ULcwsiwk1Iz8XRr35aWBWmnH2maIePBdcPeFwpTvVckTZbct26gr4lDww6z/jSwZ xr+kTPbjA4y22bvZFwuIvBz+iRy4rggGBpH/lc9ot0PECK4zwkCpTS9kV9CRt+dtA45X xPEVK12R1aRFfw+pYwwKjrVRlkbTQ0ToH/Opp1mB4pmarPRrYuPKpIBUzuU49r1nL0X7 4aV+fUh+fSpE3NkLO4GnGgjweAGBo+XBTcVIi+5sBctw1BoQvWQ+BlFrDKZjIhYQLoxu 4Bkw== X-Gm-Message-State: AOJu0Yxd4bvQNWZ7CDTV/4pOMws5YePtQBwM8rWwVmjHQUzfprPR52Et FmFFoT+DSpLQC+epVYpW9rpvNvxl1Xl/nmT6rCTZ+Mwwh4LBZrcD9QbakzUOsXQj62KUH8py7n8 CRQ== X-Google-Smtp-Source: AGHT+IH0rfbi8j7rz+6zFSEtfZIyZ5nIlOyk3OpgrnjzvE8+0P9ULOCO6SHfr8mSNO1/O3HxddZLwA== X-Received: by 2002:a17:90b:1bd2:b0:2e0:9d3e:bc2a with SMTP id 98e67ed59e1d1-2e94c51c5f2mr27980288a91.32.1730914617094; Wed, 06 Nov 2024 09:36:57 -0800 (PST) Received: from chenghaoyang-low.c.googlers.com.com (27.247.221.35.bc.googleusercontent.com. [35.221.247.27]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2e99a5f98a8sm1793400a91.38.2024.11.06.09.36.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Nov 2024 09:36:56 -0800 (PST) From: Harvey Yang To: libcamera-devel@lists.libcamera.org Cc: Han-Lin Chen , Harvey Yang Subject: [PATCH v2 1/1] libcamera: Add request API support for media controller device Date: Wed, 6 Nov 2024 17:35:32 +0000 Message-ID: <20241106173651.2859827-2-chenghaoyang@chromium.org> X-Mailer: git-send-email 2.47.0.199.ga7371fff76-goog In-Reply-To: <20241106173651.2859827-1-chenghaoyang@chromium.org> References: <20241106173651.2859827-1-chenghaoyang@chromium.org> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Han-Lin Chen This patch adds `allocateRequest` with MEDIA_IOC_REQUEST_ALLOC in MediaDevice, and introduces class MediaDevice::Request that allows users to queue the request and be notified when the request is recycled. Signed-off-by: Han-Lin Chen Co-developed-by: Harvey Yang --- include/libcamera/internal/media_device.h | 26 ++++++ src/libcamera/media_device.cpp | 106 ++++++++++++++++++++++ 2 files changed, 132 insertions(+) diff --git a/include/libcamera/internal/media_device.h b/include/libcamera/internal/media_device.h index e412d3a0b..c7ac76440 100644 --- a/include/libcamera/internal/media_device.h +++ b/include/libcamera/internal/media_device.h @@ -13,6 +13,7 @@ #include +#include #include #include #include @@ -24,6 +25,29 @@ namespace libcamera { class MediaDevice : protected Loggable { public: + class Request : protected Loggable + { + public: + Request(MediaDevice *mediaDevice, UniqueFD fd); + + int queueRequest(); + + int fd() const { return fd_.get(); } + + Signal recycled_; + + protected: + std::string logPrefix() const override; + + private: + void reinit(); + + MediaDevice *mediaDevice_; + UniqueFD fd_; + + EventNotifier eventNotifier_; + }; + MediaDevice(const std::string &deviceNode); ~MediaDevice(); @@ -53,6 +77,8 @@ public: MediaLink *link(const MediaPad *source, const MediaPad *sink); int disableLinks(); + std::unique_ptr allocateRequest(); + Signal<> disconnected; protected: diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp index d71dad74d..f25d05043 100644 --- a/src/libcamera/media_device.cpp +++ b/src/libcamera/media_device.cpp @@ -55,6 +55,91 @@ LOG_DEFINE_CATEGORY(MediaDevice) * managers to claim media devices they support during enumeration. */ +/** + * \class MediaDevice::Request + * \brief The request from a MediaDevice that supports request API + */ + +/** + * \brief Construct a MediaDevice::Request + * \param[in] mediaDevice The MediaDevice instance that allocate this request + * \param[in] fd The request's fild descriptor + */ +MediaDevice::Request::Request(MediaDevice *mediaDevice, UniqueFD fd) + : mediaDevice_(mediaDevice), fd_(std::move(fd)), + eventNotifier_(fd_.get(), EventNotifier::Type::Exception) +{ + eventNotifier_.activated.connect(this, &MediaDevice::Request::reinit); +} + +std::string MediaDevice::Request::logPrefix() const +{ + return mediaDevice_->logPrefix() + " Request"; +} + +/** + * \brief Queue a request to the media device + * + * A request needs to be re-init'ed before being queued again. This class will + * notify the user with signal `recycled` when the request is re-init'ed. + * + * \sa reinit() + * + * \return 0 on success or a negative error code otherwise + */ +int MediaDevice::Request::queueRequest() +{ + int requestFd = fd_.get(); + int ret = ioctl(requestFd, MEDIA_REQUEST_IOC_QUEUE, NULL); + if (ret) { + LOG(MediaDevice, Error) << "QueueRequest fd " << requestFd + << "failed: " << strerror(-ret); + return ret; + } + + eventNotifier_.setEnabled(true); + + return ret; +} + +/** + * \fn int MediaDevice::Request::fd() + * \return The request's file descriptor in int + */ + +/** + * \var MediaDevice::Request::recycled_ + * \brief The signal to notify the user when this request is recycled and ready + * to be queued again + * + * After this request is queued with `queueRequest()`, the user needs to wait + * for signal `recycled_` being emitted, before queueing this request again. + */ + +/** + * \brief Re-init a request + * + * This function recycles a request that was queued before. It's triggered when + * `eventNotifier_` confirms the file descriptor is completed. + * + * \sa queueRequest() + */ +void MediaDevice::Request::reinit() +{ + eventNotifier_.setEnabled(false); + + int requestFd = fd_.get(); + int ret = ::ioctl(requestFd, MEDIA_REQUEST_IOC_REINIT, NULL); + if (ret) { + LOG(MediaDevice, Error) << "The request " << requestFd + << " is queued but not yet completed: " + << strerror(-ret); + return; + } + + recycled_.emit(this); +} + /** * \brief Construct a MediaDevice * \param[in] deviceNode The media device node path @@ -828,4 +913,25 @@ int MediaDevice::setupLink(const MediaLink *link, unsigned int flags) return 0; } +/** + * \brief Allocate a request from the media device + * + * This function returns a request containing a file descriptor if the + * MediaDevice supports request API. + * + * \return A request on success or nullptr otherwise + */ +std::unique_ptr MediaDevice::allocateRequest() +{ + int fd; + int ret = ioctl(fd_.get(), MEDIA_IOC_REQUEST_ALLOC, &fd); + if (ret) { + LOG(MediaDevice, Error) << "Allocate request failed " + << strerror(-ret); + return nullptr; + } + + return std::make_unique(this, UniqueFD(fd)); +} + } /* namespace libcamera */