From patchwork Tue Jan 14 18:21:51 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22562 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 14C95C3301 for ; Tue, 14 Jan 2025 18:21:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C5A1F68543; Tue, 14 Jan 2025 19:21:57 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="G3Q3044Q"; dkim-atps=neutral Received: from mail-40133.protonmail.ch (mail-40133.protonmail.ch [185.70.40.133]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 85EC1607D6 for ; Tue, 14 Jan 2025 19:21:56 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1736878916; x=1737138116; bh=NLjxsPX3DNGK0sbo8UlmfLPb+Cw+1t5rXtAnv/p/uTE=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=G3Q3044QE4bAjYuWrDxkQe0BCCU4KGrfLQN1f9z/aEWBEkzj5pV9/nNAcmKD4SpAz 5WszKuu80A/K0oyeUZ+YECYODsQHcziUOABHoVaBwlV+wvT8dcos7wbfrnoG4qPlMG RkZta06YkO8HS9fM939aNy1VdX5YMRErCAZSkgsbbYeKhVTWOVOmcM01lOEgOGGrD2 9jCrmqpznglN3dnyJvVzsBfsyKOahAMVvx+j5gs/TntRyVv9dODyt8L9cjxwd60dR6 xr6/lCgTUicSPaoWtb+qgIywwoRJdHjxTSudUwA1+6E3NjKUc3ieIgjMaaf2rR+PQ6 HBjuiKkUrjWwA== Date: Tue, 14 Jan 2025 18:21:51 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [RFC PATCH v2 01/16] apps: common: event_loop: Take callbacks by rvalue ref Message-ID: <20250114182143.1773762-2-pobrn@protonmail.com> In-Reply-To: <20250114182143.1773762-1-pobrn@protonmail.com> References: <20250114182143.1773762-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: e11c87e32cb03fc8f9e9dbdb4dd0fc53c1898d08 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" Using a const lvalue reference to `std::function<>` is not ideal because it forces a copy to happen. Use an rvalue reference and `std::move()` to avoid that. Signed-off-by: Barnabás Pőcze --- src/apps/common/event_loop.cpp | 16 ++++++++-------- src/apps/common/event_loop.h | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/apps/common/event_loop.cpp b/src/apps/common/event_loop.cpp index f7f9afa0c..bc8cf17ab 100644 --- a/src/apps/common/event_loop.cpp +++ b/src/apps/common/event_loop.cpp @@ -50,20 +50,20 @@ void EventLoop::exit(int code) event_base_loopbreak(base_); } -void EventLoop::callLater(const std::function &func) +void EventLoop::callLater(std::function &&func) { { std::unique_lock locker(lock_); - calls_.push_back(func); + calls_.push_back(std::move(func)); } event_base_once(base_, -1, EV_TIMEOUT, dispatchCallback, this, nullptr); } void EventLoop::addFdEvent(int fd, EventType type, - const std::function &callback) + std::function &&callback) { - std::unique_ptr event = std::make_unique(callback); + std::unique_ptr event = std::make_unique(std::move(callback)); short events = (type & Read ? EV_READ : 0) | (type & Write ? EV_WRITE : 0) | EV_PERSIST; @@ -85,9 +85,9 @@ void EventLoop::addFdEvent(int fd, EventType type, } void EventLoop::addTimerEvent(const std::chrono::microseconds period, - const std::function &callback) + std::function &&callback) { - std::unique_ptr event = std::make_unique(callback); + std::unique_ptr event = std::make_unique(std::move(callback)); event->event_ = event_new(base_, -1, EV_PERSIST, &EventLoop::Event::dispatch, event.get()); if (!event->event_) { @@ -131,8 +131,8 @@ void EventLoop::dispatchCall() call(); } -EventLoop::Event::Event(const std::function &callback) - : callback_(callback), event_(nullptr) +EventLoop::Event::Event(std::function &&callback) + : callback_(std::move(callback)), event_(nullptr) { } diff --git a/src/apps/common/event_loop.h b/src/apps/common/event_loop.h index ef129b9aa..d7d012c76 100644 --- a/src/apps/common/event_loop.h +++ b/src/apps/common/event_loop.h @@ -33,18 +33,18 @@ public: int exec(); void exit(int code = 0); - void callLater(const std::function &func); + void callLater(std::function &&func); void addFdEvent(int fd, EventType type, - const std::function &handler); + std::function &&handler); using duration = std::chrono::steady_clock::duration; void addTimerEvent(const std::chrono::microseconds period, - const std::function &handler); + std::function &&handler); private: struct Event { - Event(const std::function &callback); + Event(std::function &&callback); ~Event(); static void dispatch(int fd, short events, void *arg); From patchwork Tue Jan 14 18:21:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22563 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 317EDC3301 for ; Tue, 14 Jan 2025 18:22:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DF992607D6; Tue, 14 Jan 2025 19:22:01 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="wcvcfo2e"; dkim-atps=neutral Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 727C2607D6 for ; Tue, 14 Jan 2025 19:22:00 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1736878920; x=1737138120; bh=Wp0RmpD70etEE/ATtJn2G0hd/QRpYx4CwO+U0XCuJ6k=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=wcvcfo2eu8JSAuxCoZkalj+Gkk538dRzk5XvYjaDSzT9LiU9wonw4OAvplp7d+Wm4 dDd+DGgS/60o5fTMNa0Z4gx1f5GlWCHC93rzVWCIxxOFasBxi72gNUK9PTqhMIggbl QW9iHzzRU5tDTneqsh4zzdekNwITuxenK+ksXLwhEA3hD0feJg1ksppynxqzujZzSz TJexHeg41IYfiYjpIgG7CWBPylOvWWqT4l32F9KoUwgHdcKpXMqXzYOFdg0DqaCMcJ oSUMyLNTuRYOJUzMKsQ6MP3gAZ/sMoFg79LEbnADypDbSwVuc4VE7SL5zJ5ImvrXN0 xoG7Imo1FXzjQ== Date: Tue, 14 Jan 2025 18:21:56 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [RFC PATCH v2 02/16] apps: common: event_loop: Disable copy/move Message-ID: <20250114182143.1773762-3-pobrn@protonmail.com> In-Reply-To: <20250114182143.1773762-1-pobrn@protonmail.com> References: <20250114182143.1773762-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 3cfc531000f31e2f60431b00f7d9423fd4939cad 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" The compiler generated functions are not appropriate, so delete the copy/move constructor/assignment to avoid potential issues. Signed-off-by: Barnabás Pőcze --- src/apps/common/event_loop.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/apps/common/event_loop.h b/src/apps/common/event_loop.h index d7d012c76..4e8dd0a46 100644 --- a/src/apps/common/event_loop.h +++ b/src/apps/common/event_loop.h @@ -13,6 +13,8 @@ #include #include +#include + #include struct event_base; @@ -43,8 +45,11 @@ public: std::function &&handler); private: + LIBCAMERA_DISABLE_COPY_AND_MOVE(EventLoop) + struct Event { Event(std::function &&callback); + LIBCAMERA_DISABLE_COPY_AND_MOVE(Event) ~Event(); static void dispatch(int fd, short events, void *arg); From patchwork Tue Jan 14 18:22:01 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22564 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 BD6C8C3301 for ; Tue, 14 Jan 2025 18:22:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7800D6854A; Tue, 14 Jan 2025 19:22:07 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="uzbjIayn"; dkim-atps=neutral Received: from mail-40133.protonmail.ch (mail-40133.protonmail.ch [185.70.40.133]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CE787607D6 for ; Tue, 14 Jan 2025 19:22:06 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1736878926; x=1737138126; bh=O1CQWalgQFzFWQZzwARSpGSVXVcoPm81HjvhNzkX9yg=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=uzbjIaynEQ923pr9PPXrhCth60agpkHPivNQISkfMScnHo67mMr9f3tiRQTb/ymVH f8zambcxBZV+D/5+kJ9wt/VVbmV0A6fhzMyOZOih4GUY2JXvtneQz5oAogMG8WAaxn 2ZhN0S3CRxM3qdKo4ugD9t9tsPafH7qeO/DruGPMmhAQ1TlahYa9rOWoRmNhA245T9 mjigiUZOIGQTAr1FpTGcMQrLOIqPq7dmNTUrk6ypVYacnMcKHe9XvBIWUTxFF3fKsR I6/b6pho9M/3qfC/XxsVQ7tyGvRivk7TNqPIQBAZ/Ps0QHRMR9nAu1iSj0CuC99Y54 kTiOFFatgNgug== Date: Tue, 14 Jan 2025 18:22:01 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [RFC PATCH v2 03/16] apps: common: event_loop: Use `std::deque` instead of `std::list` Message-ID: <20250114182143.1773762-4-pobrn@protonmail.com> In-Reply-To: <20250114182143.1773762-1-pobrn@protonmail.com> References: <20250114182143.1773762-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: b67cac3cb6bbdbf9e36f2555012229351243e0bc 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" Deque has fast pop_front and push_back operations while making fewer allocations for the same number of elements as an `std::list`. So use an `std::deque` for storing the deferred calls of the loop. Signed-off-by: Barnabás Pőcze --- src/apps/common/event_loop.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/apps/common/event_loop.h b/src/apps/common/event_loop.h index 4e8dd0a46..760075885 100644 --- a/src/apps/common/event_loop.h +++ b/src/apps/common/event_loop.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include #include @@ -63,7 +64,8 @@ private: struct event_base *base_; int exitCode_; - std::list> calls_; + std::deque> calls_; + std::list> events_; std::mutex lock_; From patchwork Tue Jan 14 18:22:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22565 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 9B288C3301 for ; Tue, 14 Jan 2025 18:22:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 531F46854C; Tue, 14 Jan 2025 19:22:13 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="YtVt2fNB"; dkim-atps=neutral Received: from mail-10630.protonmail.ch (mail-10630.protonmail.ch [79.135.106.30]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5F0D7607D6 for ; Tue, 14 Jan 2025 19:22:11 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1736878930; x=1737138130; bh=NSMHeTnI4K52UGXlbwGm11XKs7nSUJCQPrWb2OYN1lI=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=YtVt2fNBftK0P05kLFVaDLHTXTEZ5Zvam8Hd/4q33PhaTZxY4h24kKNd1NZgaP1lU i7Vsj+Hozko+ibxRHukPpkUyoDWqlI1xxyxF/0wRM29Tm69ce88dLzdoTzt4XpdYNn Bl0kj88q4FvOhe/lwdALgcsARQjiB/IMhCi0jPFD8t8uo+WXcWK2zuMxfleobxx+on O95DhyGKORxWVGZtAnKvDFQokMl7qxxkRO0qpUmXuXSfr9ZXUC0hhEsOvxQ3NaIGRH itSZvtuTtV+Qkk2MIx3y4bvozdY5XeCYvfz9CybjC2l6f/zfLsmsODaBLhW+v7RcmW Q8MmJE+lgrk0g== Date: Tue, 14 Jan 2025 18:22:05 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [RFC PATCH v2 04/16] apps: common: event_loop: Use single event source for deferred calls Message-ID: <20250114182143.1773762-5-pobrn@protonmail.com> In-Reply-To: <20250114182143.1773762-1-pobrn@protonmail.com> References: <20250114182143.1773762-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 2eccf59ec2fea8f02dd4317feac02a6d2686145c 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" Instead of calling `event_base_once()` every time a deferred call is added to the loop, create an event source at construction, and simply trigger that when a new deferred call is scheduled. Signed-off-by: Barnabás Pőcze --- src/apps/common/event_loop.cpp | 48 +++++++++++++++++----------------- src/apps/common/event_loop.h | 5 +--- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/apps/common/event_loop.cpp b/src/apps/common/event_loop.cpp index bc8cf17ab..b6230f4ba 100644 --- a/src/apps/common/event_loop.cpp +++ b/src/apps/common/event_loop.cpp @@ -21,12 +21,35 @@ EventLoop::EventLoop() evthread_use_pthreads(); base_ = event_base_new(); instance_ = this; + + callsTrigger_ = event_new(base_, -1, EV_PERSIST, [](evutil_socket_t, short, void *closure) { + auto *self = static_cast(closure); + + for (;;) { + std::function call; + + { + std::lock_guard locker(self->lock_); + if (self->calls_.empty()) + break; + + call = std::move(self->calls_.front()); + self->calls_.pop_front(); + } + + call(); + } + }, this); + assert(callsTrigger_); + event_add(callsTrigger_, nullptr); } EventLoop::~EventLoop() { instance_ = nullptr; + event_free(callsTrigger_); + events_.clear(); event_base_free(base_); libevent_global_shutdown(); @@ -57,7 +80,7 @@ void EventLoop::callLater(std::function &&func) calls_.push_back(std::move(func)); } - event_base_once(base_, -1, EV_TIMEOUT, dispatchCallback, this, nullptr); + event_active(callsTrigger_, 0, 0); } void EventLoop::addFdEvent(int fd, EventType type, @@ -108,29 +131,6 @@ void EventLoop::addTimerEvent(const std::chrono::microseconds period, events_.push_back(std::move(event)); } -void EventLoop::dispatchCallback([[maybe_unused]] evutil_socket_t fd, - [[maybe_unused]] short flags, void *param) -{ - EventLoop *loop = static_cast(param); - loop->dispatchCall(); -} - -void EventLoop::dispatchCall() -{ - std::function call; - - { - std::unique_lock locker(lock_); - if (calls_.empty()) - return; - - call = calls_.front(); - calls_.pop_front(); - } - - call(); -} - EventLoop::Event::Event(std::function &&callback) : callback_(std::move(callback)), event_(nullptr) { diff --git a/src/apps/common/event_loop.h b/src/apps/common/event_loop.h index 760075885..aac5ed3cc 100644 --- a/src/apps/common/event_loop.h +++ b/src/apps/common/event_loop.h @@ -65,11 +65,8 @@ private: int exitCode_; std::deque> calls_; + ::event *callsTrigger_ = nullptr; std::list> events_; std::mutex lock_; - - static void dispatchCallback(evutil_socket_t fd, short flags, - void *param); - void dispatchCall(); }; From patchwork Tue Jan 14 18:22:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22566 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 4764BC3301 for ; Tue, 14 Jan 2025 18:22:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0391E6854A; Tue, 14 Jan 2025 19:22:19 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="rC0OLE2N"; dkim-atps=neutral Received: from mail-10630.protonmail.ch (mail-10630.protonmail.ch [79.135.106.30]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7DA1768543 for ; Tue, 14 Jan 2025 19:22:17 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1736878936; x=1737138136; bh=4KsJUL43WBdIJl+z/IPEcU7jqnKztejvM2uOv6LYFvA=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=rC0OLE2NlJyn2+EMUl2GadB2ZtXuVU2UcS+pXFmlW5CZ2zPjtddEB1bFgBXCLGKlo DhA9KCattS5xw0xZZP3Ysa+LBUt2HmCGK+69nAiS/Uk0VgekeN/IP4dkEGrABERE0d 6v1U/t3fWPqbWwnoj1jO1VjUKtmurqGrKRDvzr85ydN6AV8V2Hi3IuaVTZRVwCBNGw GkRIGuq3GK1ewZ0NsJT/V1uWf7XGS7PnlkZ5TDOuJ66ckefdx5cbpS6woiWjJcd8pv V0qRfLvR+HtcmQ0TNwZ1wbBmykr8X5LuUdIP8fhN8U9/CYST1dHpJ1R5r41/11jx2R YfzkCy6LIl/ow== Date: Tue, 14 Jan 2025 18:22:10 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Cc: Jacopo Mondi , Paul Elder Subject: [RFC PATCH v2 05/16] apps: lc-compliance: Initialize `CameraManager` pointer in `Environment` Message-ID: <20250114182143.1773762-6-pobrn@protonmail.com> In-Reply-To: <20250114182143.1773762-1-pobrn@protonmail.com> References: <20250114182143.1773762-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 42a4e038021d5e82c75ed42c7fc4578d6a698b6f 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" Do not leave it unitialized. Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi Reviewed-by: Paul Elder --- src/apps/lc-compliance/environment.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/lc-compliance/environment.h b/src/apps/lc-compliance/environment.h index 543e5372f..834c722ef 100644 --- a/src/apps/lc-compliance/environment.h +++ b/src/apps/lc-compliance/environment.h @@ -23,5 +23,5 @@ private: Environment() = default; std::string cameraId_; - libcamera::CameraManager *cm_; + libcamera::CameraManager *cm_ = nullptr; }; From patchwork Tue Jan 14 18:22:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22567 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 CBB83C3301 for ; Tue, 14 Jan 2025 18:22:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8933B6854C; Tue, 14 Jan 2025 19:22:22 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="ys2mpOZw"; dkim-atps=neutral Received: from mail-40131.protonmail.ch (mail-40131.protonmail.ch [185.70.40.131]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 813EE6854C for ; Tue, 14 Jan 2025 19:22:20 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1736878939; x=1737138139; bh=0rY4KHEuGtq2y0k1dwL7rGGG5orpcUyUEQkaWHddg3w=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=ys2mpOZwE/zayQHEXpwbAkWffHbHA5I4sbh1sEzZfqvdW957j7qdoKpuPv9WcfiP0 xxJ2prSxYidCzrQ279RplEIGiBcNemXDG0p0ki+AV1uB3ig43ocJL2kM8d8zqnPO8U STHnoTLu+RCxnkA6lN+gmXhjD3Y5RKwBRxQxJZU1kgIihJYjWFXu/HJfmJWTBglXSY 16noLQh+VXY+fudU3zlTEKgNs8oGWasqPKj7C2EGO+Fk9joWlZa6I1nAtfBtdND2aQ xa5gt0car4gMGgDXWG2DEKgesmrvBg/saM+aZgDLEn/Y+UEaaWYMZ2Sp9Arhv0dPf7 1dUXe6IyCKeRQ== Date: Tue, 14 Jan 2025 18:22:17 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Cc: Jacopo Mondi , Paul Elder Subject: [RFC PATCH v2 06/16] apps: lc-compliance: Put tests into anonymous namespace Message-ID: <20250114182143.1773762-7-pobrn@protonmail.com> In-Reply-To: <20250114182143.1773762-1-pobrn@protonmail.com> References: <20250114182143.1773762-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 44f9a8a737ff09879c188a6b2e681b818006bc53 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" There is no reason for these symbols to be global. Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi Reviewed-by: Paul Elder --- src/apps/lc-compliance/tests/capture_test.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/apps/lc-compliance/tests/capture_test.cpp b/src/apps/lc-compliance/tests/capture_test.cpp index ad3a1da2f..db196a949 100644 --- a/src/apps/lc-compliance/tests/capture_test.cpp +++ b/src/apps/lc-compliance/tests/capture_test.cpp @@ -14,6 +14,8 @@ #include "environment.h" +namespace { + using namespace libcamera; const std::vector NUMREQUESTS = { 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 }; @@ -134,3 +136,5 @@ INSTANTIATE_TEST_SUITE_P(CaptureTests, testing::Combine(testing::ValuesIn(ROLES), testing::ValuesIn(NUMREQUESTS)), SingleStream::nameParameters); + +} /* namespace */ From patchwork Tue Jan 14 18:22:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22568 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 42440C3301 for ; Tue, 14 Jan 2025 18:22:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 09AFB6854E; Tue, 14 Jan 2025 19:22:28 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="gXLkZyTr"; dkim-atps=neutral Received: from mail-10629.protonmail.ch (mail-10629.protonmail.ch [79.135.106.29]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F1D166854C for ; Tue, 14 Jan 2025 19:22:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1736878946; x=1737138146; bh=MNLSu6mkLawqXE/2yDtVn/bcBeJOWkgvPwdl+gHqEfg=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=gXLkZyTrXPi9XEVzL7IKybHegq1RN1oqe6JPtGBdGidkl/V23KEcqncflgpKQocdj AmtD8UOOZZL7YTGh1gYZBnhua2zU5k1Rz9/tQb7/bGlXqExBxYaJSLseHo0MqVdvia iVIQNeRAe2MWsxkHqIy3DVfNDJ4TFEiVN/Z4XTTR2r1liL6tpvnXvgf871an5gMlle /DmvdUF+zVAxTtdD+U/6+dxhohAD12gDsXc5xTyjchYbXd3gs2a45+Z0baqxzXFDkW ESKr/bPBv/eC6TYqfbMNhrmG6LfbOq3R56a4b8FVN6GGXO/qh7pnmYRClln0aLDEm3 gntonyXNhYNGw== Date: Tue, 14 Jan 2025 18:22:22 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Cc: Laurent Pinchart Subject: [RFC PATCH v2 07/16] apps: lc-compliance: Optimize `std::shared_ptr` usage Message-ID: <20250114182143.1773762-8-pobrn@protonmail.com> In-Reply-To: <20250114182143.1773762-1-pobrn@protonmail.com> References: <20250114182143.1773762-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 2f282c01c417d9e32df0d5981dc2dd730a2b16ab 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" Avoid unnecessary copies and try to move construct `std::shared_ptr` whenever possible. Signed-off-by: Barnabás Pőcze Reviewed-by: Laurent Pinchart --- src/apps/lc-compliance/helpers/capture.cpp | 8 ++++---- src/apps/lc-compliance/main.cpp | 4 +--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/apps/lc-compliance/helpers/capture.cpp b/src/apps/lc-compliance/helpers/capture.cpp index 90c1530ba..d1dafb6cf 100644 --- a/src/apps/lc-compliance/helpers/capture.cpp +++ b/src/apps/lc-compliance/helpers/capture.cpp @@ -12,8 +12,8 @@ using namespace libcamera; Capture::Capture(std::shared_ptr camera) - : loop_(nullptr), camera_(camera), - allocator_(std::make_unique(camera)) + : loop_(nullptr), camera_(std::move(camera)), + allocator_(std::make_unique(camera_)) { } @@ -72,7 +72,7 @@ void Capture::stop() /* CaptureBalanced */ CaptureBalanced::CaptureBalanced(std::shared_ptr camera) - : Capture(camera) + : Capture(std::move(camera)) { } @@ -144,7 +144,7 @@ void CaptureBalanced::requestComplete(Request *request) /* CaptureUnbalanced */ CaptureUnbalanced::CaptureUnbalanced(std::shared_ptr camera) - : Capture(camera) + : Capture(std::move(camera)) { } diff --git a/src/apps/lc-compliance/main.cpp b/src/apps/lc-compliance/main.cpp index 3f1d2a61b..98f2573d0 100644 --- a/src/apps/lc-compliance/main.cpp +++ b/src/apps/lc-compliance/main.cpp @@ -50,8 +50,6 @@ static void listCameras(CameraManager *cm) static int initCamera(CameraManager *cm, OptionsParser::Options options) { - std::shared_ptr camera; - int ret = cm->start(); if (ret) { std::cout << "Failed to start camera manager: " @@ -66,7 +64,7 @@ static int initCamera(CameraManager *cm, OptionsParser::Options options) } const std::string &cameraId = options[OptCamera]; - camera = cm->get(cameraId); + std::shared_ptr camera = cm->get(cameraId); if (!camera) { std::cout << "Camera " << cameraId << " not found, available cameras:" << std::endl; listCameras(cm); From patchwork Tue Jan 14 18:22:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22569 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 097B1C3301 for ; Tue, 14 Jan 2025 18:22:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AF4BB6854C; Tue, 14 Jan 2025 19:22:32 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="o7J4qkTh"; dkim-atps=neutral Received: from mail-10629.protonmail.ch (mail-10629.protonmail.ch [79.135.106.29]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B36D5684E4 for ; Tue, 14 Jan 2025 19:22:31 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1736878951; x=1737138151; bh=wkrIB4YgmYKmQEgNV1q7PTX5QcDbokZN9TquUHAcD+I=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=o7J4qkThVbmGwAdTOExh27PS+mUmb7qrQM7xP99ncN5UHSZCufW8/wrWhT6iEkiD5 AP2w526Xc2YLBt6VsAY7NzEdw063HPzxUupi9PaDq/0qOMMuRfcyjdsPO+XALyONgx 17QaNkQFN2JUCS3umEjulkoVMHDF3+AUs6G4/bFyzwO19eMt/kNQMpEIB+jL2LE9gU pP/0u2upZeVdO9FGwGFdIO4D165RvpsHeK0UoHvgo4xIR+6FSFT9m4LsoOiJXVFIzH tmKxQLTRqwy8zcsySOpSX+HpKCNb7bURrVB2vvlUDfAh2ZaUoMHD/8HfyykUCzNZ87 xGHeKiy+NeuRQ== Date: Tue, 14 Jan 2025 18:22:28 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Cc: Jacopo Mondi , Paul Elder Subject: [RFC PATCH v2 08/16] apps: lc-compliance: Remove redundant getter call Message-ID: <20250114182143.1773762-9-pobrn@protonmail.com> In-Reply-To: <20250114182143.1773762-1-pobrn@protonmail.com> References: <20250114182143.1773762-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 6e36770f0607cdcefc1c740cdd70c334b17daec6 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" Smart pointers overload `operator->()`, no reason to use `get()`. Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi Reviewed-by: Paul Elder --- src/apps/lc-compliance/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/lc-compliance/main.cpp b/src/apps/lc-compliance/main.cpp index 98f2573d0..cdd0bd515 100644 --- a/src/apps/lc-compliance/main.cpp +++ b/src/apps/lc-compliance/main.cpp @@ -45,7 +45,7 @@ class ThrowListener : public testing::EmptyTestEventListener static void listCameras(CameraManager *cm) { for (const std::shared_ptr &cam : cm->cameras()) - std::cout << "- " << cam.get()->id() << std::endl; + std::cout << "- " << cam->id() << std::endl; } static int initCamera(CameraManager *cm, OptionsParser::Options options) From patchwork Tue Jan 14 18:22:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22570 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 B8E0EC3301 for ; Tue, 14 Jan 2025 18:22:38 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6E6F46854A; Tue, 14 Jan 2025 19:22:38 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="qbWgplmp"; dkim-atps=neutral Received: from mail-10628.protonmail.ch (mail-10628.protonmail.ch [79.135.106.28]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8D2A668536 for ; Tue, 14 Jan 2025 19:22:36 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1736878955; x=1737138155; bh=dFg6NaZS/ejGUsUCrx8TsDPmCurA3lVC80DO2Jz8mEs=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=qbWgplmpWDqduPvprWedWTbhAtZ+NXTEnr7EjHYI/Zv3LcZg1Jai/wz+fQqMVLl5P wta7EQtHIQ0pnmj4WP44VJXy1/GS+i4Dae5S5Sod4cvDLV1cjU7Hr2HByH+0LoNbPg f+g0OupdoYvyVMGBOv5eS0k2HlkRlXw80jT9/cF6n0q8asfnsO+1h04C/Rx6MwZwJG /icxYREuqedPsIq9s3jxxqG7nGPzNJBnAa7yOjDw9VcEhg5AkGKQwjfY5NjnF1HRq6 IbGn8+fbAJ1g4kFVUuiiIJQ0rvZNuaBosB9J9r+ZuARY0XMHZa7/feZi4HmHWfyrPh Tf8QCtXZ/FfjQ== Date: Tue, 14 Jan 2025 18:22:32 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Cc: Jacopo Mondi , Paul Elder Subject: [RFC PATCH v2 09/16] apps: lc-compliance: Don't allocate `FrameBufferAllocator` dynamically Message-ID: <20250114182143.1773762-10-pobrn@protonmail.com> In-Reply-To: <20250114182143.1773762-1-pobrn@protonmail.com> References: <20250114182143.1773762-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 85c058acd4f6844cbe1d43d9caf70ef40a8e09da 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" There is no reason to do so. Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi Reviewed-by: Paul Elder --- src/apps/lc-compliance/helpers/capture.cpp | 12 ++++++------ src/apps/lc-compliance/helpers/capture.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/apps/lc-compliance/helpers/capture.cpp b/src/apps/lc-compliance/helpers/capture.cpp index d1dafb6cf..91c4d4400 100644 --- a/src/apps/lc-compliance/helpers/capture.cpp +++ b/src/apps/lc-compliance/helpers/capture.cpp @@ -13,7 +13,7 @@ using namespace libcamera; Capture::Capture(std::shared_ptr camera) : loop_(nullptr), camera_(std::move(camera)), - allocator_(std::make_unique(camera_)) + allocator_(camera_) { } @@ -45,7 +45,7 @@ void Capture::configure(StreamRole role) void Capture::start() { Stream *stream = config_->at(0).stream(); - int count = allocator_->allocate(stream); + int count = allocator_.allocate(stream); ASSERT_GE(count, 0) << "Failed to allocate buffers"; EXPECT_EQ(count, config_->at(0).bufferCount) << "Allocated less buffers than expected"; @@ -57,7 +57,7 @@ void Capture::start() void Capture::stop() { - if (!config_ || !allocator_->allocated()) + if (!config_ || !allocator_.allocated()) return; camera_->stop(); @@ -66,7 +66,7 @@ void Capture::stop() Stream *stream = config_->at(0).stream(); requests_.clear(); - allocator_->free(stream); + allocator_.free(stream); } /* CaptureBalanced */ @@ -81,7 +81,7 @@ void CaptureBalanced::capture(unsigned int numRequests) start(); Stream *stream = config_->at(0).stream(); - const std::vector> &buffers = allocator_->buffers(stream); + const std::vector> &buffers = allocator_.buffers(stream); /* No point in testing less requests then the camera depth. */ if (buffers.size() > numRequests) { @@ -153,7 +153,7 @@ void CaptureUnbalanced::capture(unsigned int numRequests) start(); Stream *stream = config_->at(0).stream(); - const std::vector> &buffers = allocator_->buffers(stream); + const std::vector> &buffers = allocator_.buffers(stream); captureCount_ = 0; captureLimit_ = numRequests; diff --git a/src/apps/lc-compliance/helpers/capture.h b/src/apps/lc-compliance/helpers/capture.h index 19b6927c6..a4cc3a99e 100644 --- a/src/apps/lc-compliance/helpers/capture.h +++ b/src/apps/lc-compliance/helpers/capture.h @@ -30,7 +30,7 @@ protected: EventLoop *loop_; std::shared_ptr camera_; - std::unique_ptr allocator_; + libcamera::FrameBufferAllocator allocator_; std::unique_ptr config_; std::vector> requests_; }; From patchwork Tue Jan 14 18:22:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22571 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 3D5C3C3301 for ; Tue, 14 Jan 2025 18:22:44 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EF41268521; Tue, 14 Jan 2025 19:22:43 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="yefhomab"; dkim-atps=neutral Received: from mail-10631.protonmail.ch (mail-10631.protonmail.ch [79.135.106.31]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 13CB468521 for ; Tue, 14 Jan 2025 19:22:42 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1736878961; x=1737138161; bh=kxP38QZSOBzAjSi5XVjbBN6zbKB0FhK1k+izhC27p3Q=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=yefhomab9Yh0Ylb/susA+aXba5/Z6OnEtbBH/8kHrbnk/mBg41qFXZVpv4645mtWO EBEIpMqoV0HvKvOokhTzh8XHZ4PEo11lgB1+kXnzyEIAJScv5xoIrCp/i1vMWAgAEx 3/1tBmZ7kTtqtPXmQS4iAXpTl7kWKNFDsX0lvzENx6jgJm73n4JoR83VeYFGisWK6z 7JaanB4PAtvXfd8/8NoNPKiI3QnWEovmP4lHWWf6RWTtcg5VLBU209cCYngw8r7dcV 6jr/49GCNm2jNelw/y3dC1TQOA/atkkD9YuI+jhXaf3qq9evOwnCpeuZhRM3Pra5Co nWPO1cFe8dibA== Date: Tue, 14 Jan 2025 18:22:37 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Cc: Jacopo Mondi , Paul Elder , Laurent Pinchart Subject: [RFC PATCH v2 10/16] apps: lc-compliance: Use `std::vector` for argument array Message-ID: <20250114182143.1773762-11-pobrn@protonmail.com> In-Reply-To: <20250114182143.1773762-1-pobrn@protonmail.com> References: <20250114182143.1773762-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 8f3260dec7bc043f529ad786d4e2c72ceb95d0b5 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" Just use an `std::vector` to store the arguments passed to `InitGoogleTest()`. This removes the need for the map and the separate `argc` variable used for size-keeping. Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi Reviewed-by: Paul Elder Reviewed-by: Laurent Pinchart --- src/apps/lc-compliance/main.cpp | 36 +++++++++------------------------ 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/src/apps/lc-compliance/main.cpp b/src/apps/lc-compliance/main.cpp index cdd0bd515..e9f0ffbb5 100644 --- a/src/apps/lc-compliance/main.cpp +++ b/src/apps/lc-compliance/main.cpp @@ -80,45 +80,27 @@ static int initCamera(CameraManager *cm, OptionsParser::Options options) static int initGtestParameters(char *arg0, OptionsParser::Options options) { - const std::map gtestFlags = { { "list", "--gtest_list_tests" }, - { "filter", "--gtest_filter" } }; - - int argc = 0; + std::vector argv; std::string filterParam; - /* - * +2 to have space for both the 0th argument that is needed but not - * used and the null at the end. - */ - char **argv = new char *[(gtestFlags.size() + 2)]; - if (!argv) - return -ENOMEM; - - argv[0] = arg0; - argc++; + argv.push_back(arg0); - if (options.isSet(OptList)) { - argv[argc] = const_cast(gtestFlags.at("list").c_str()); - argc++; - } + if (options.isSet(OptList)) + argv.push_back("--gtest_list_tests"); if (options.isSet(OptFilter)) { /* * The filter flag needs to be passed as a single parameter, in * the format --gtest_filter=filterStr */ - filterParam = gtestFlags.at("filter") + "=" + - static_cast(options[OptFilter]); - - argv[argc] = const_cast(filterParam.c_str()); - argc++; + filterParam = "--gtest_filter=" + options[OptFilter].toString(); + argv.push_back(filterParam.c_str()); } - argv[argc] = nullptr; - - ::testing::InitGoogleTest(&argc, argv); + argv.push_back(nullptr); - delete[] argv; + int argc = argv.size(); + ::testing::InitGoogleTest(&argc, const_cast(argv.data())); return 0; } From patchwork Tue Jan 14 18:22:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22572 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 C2F77C3304 for ; Tue, 14 Jan 2025 18:22:48 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 80CBB68556; Tue, 14 Jan 2025 19:22:48 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="yWw7bc9u"; dkim-atps=neutral Received: from mail-10631.protonmail.ch (mail-10631.protonmail.ch [79.135.106.31]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5C39A68521 for ; Tue, 14 Jan 2025 19:22:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1736878966; x=1737138166; bh=b1nRaO0Gq/kw6LhMHcq7NAG0CN+eORVXlDvYE8KaTsA=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=yWw7bc9uwIhtvw1veowc0M1jFkswHXdBdR29F4DnZsa8prkwm+DjU7uAXYjxcZpkl CvSxqgJje180hiYSrOhz1006fjcYdahT6x8L7vrBmx4LbQ38Di1LYDlg3NNvyVBksg Ru4k+DzSpayjCpkQ3DF61fUTner2M2G2faYUOtV96Ox6PtTgrhKKpBII9SKWYHOVeE 0hiBMHyJVSCbtqpEN5zTyfn2FSt2HxBbzmZ5SZ6o8CIjIOBgVrOuMtDBR5IHB2M0Z8 hU7P/E21x448I3U1wr0ZtCt6vUHjVtptmDQykw7zKo9ACRsDAxIAmYmb5AnrMMAUpG FduFJbrKjAyLA== Date: Tue, 14 Jan 2025 18:22:42 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Cc: Jacopo Mondi , Paul Elder Subject: [RFC PATCH v2 11/16] apps: lc-compliance: Use array instead of `std::vector` Message-ID: <20250114182143.1773762-12-pobrn@protonmail.com> In-Reply-To: <20250114182143.1773762-1-pobrn@protonmail.com> References: <20250114182143.1773762-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: dfa4dca7f7e210a5f7bc19d5bc441ba82753e057 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" There is no reason to use `std::vector` for this static data, a simple array will do fine. Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi Reviewed-by: Paul Elder --- src/apps/lc-compliance/tests/capture_test.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/apps/lc-compliance/tests/capture_test.cpp b/src/apps/lc-compliance/tests/capture_test.cpp index db196a949..97465a612 100644 --- a/src/apps/lc-compliance/tests/capture_test.cpp +++ b/src/apps/lc-compliance/tests/capture_test.cpp @@ -18,8 +18,9 @@ namespace { using namespace libcamera; -const std::vector NUMREQUESTS = { 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 }; -const std::vector ROLES = { +const int NUMREQUESTS[] = { 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 }; + +const StreamRole ROLES[] = { StreamRole::Raw, StreamRole::StillCapture, StreamRole::VideoRecording, From patchwork Tue Jan 14 18:22:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22573 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 4981DC3304 for ; Tue, 14 Jan 2025 18:22:53 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 073F968545; Tue, 14 Jan 2025 19:22:53 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="whD6m168"; dkim-atps=neutral Received: from mail-10631.protonmail.ch (mail-10631.protonmail.ch [79.135.106.31]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BFD1E68521 for ; Tue, 14 Jan 2025 19:22:50 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1736878970; x=1737138170; bh=tmCTVUWVvSTdiqZyWSIPZBhQc6EskgTjxCnrRw+re4Q=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=whD6m168pxvavQD0DFP6VqvjzkxPRcpxlwpzTRQFYLFq0JDPLcB/qS+WvkaB74oR1 cF6c2K+jlr0QV+EBFXwO3u9oDHtu0m/UPz2fi4fJBjap/+/EER8DU5S0wXg06Qetp0 r+7YOITDH+/CaSrqZzaNe//JCPVISxWVAwVEhteOk04qxpNPSFp13A9IId8GghWD5a 74niS4iTWjVVS76oHZrfcmUMcgL2cxqQy8s8ZNXo2M95SBme4O7PKtAKBo1kF5TBI9 p2zig8gvhBdlsQZg7mdet4+DdwXdWaUC+vuljva6xvy7Cq0nuVA7qn0o7bMv2Hq1C0 nnGnA7BOKv7EA== Date: Tue, 14 Jan 2025 18:22:47 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [RFC PATCH v2 12/16] apps: lc-compliance: Add message to `GTEST_SKIP()` Message-ID: <20250114182143.1773762-13-pobrn@protonmail.com> In-Reply-To: <20250114182143.1773762-1-pobrn@protonmail.com> References: <20250114182143.1773762-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 8c5bb2fa7ee2c35ca8236f68d94a9139c71bdcf4 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" Just like other gtest macros, `GTEST_SKIP()` returns an object to which a formatted message can be added using the usual `<<` stream operator. So use it instead of printing to `std::cout`. Signed-off-by: Barnabás Pőcze --- src/apps/lc-compliance/helpers/capture.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/apps/lc-compliance/helpers/capture.cpp b/src/apps/lc-compliance/helpers/capture.cpp index 91c4d4400..43db15d2d 100644 --- a/src/apps/lc-compliance/helpers/capture.cpp +++ b/src/apps/lc-compliance/helpers/capture.cpp @@ -26,10 +26,8 @@ void Capture::configure(StreamRole role) { config_ = camera_->generateConfiguration({ role }); - if (!config_) { - std::cout << "Role not supported by camera" << std::endl; - GTEST_SKIP(); - } + if (!config_) + GTEST_SKIP() << "Role not supported by camera"; if (config_->validate() != CameraConfiguration::Valid) { config_.reset(); @@ -85,10 +83,8 @@ void CaptureBalanced::capture(unsigned int numRequests) /* No point in testing less requests then the camera depth. */ if (buffers.size() > numRequests) { - std::cout << "Camera needs " + std::to_string(buffers.size()) - + " requests, can't test only " - + std::to_string(numRequests) << std::endl; - GTEST_SKIP(); + GTEST_SKIP() << "Camera needs " << buffers.size() + << " requests, can't test only " << numRequests; } queueCount_ = 0; From patchwork Tue Jan 14 18:22:52 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22574 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 DD056C3304 for ; Tue, 14 Jan 2025 18:22:57 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 94F946855A; Tue, 14 Jan 2025 19:22:57 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="RZPN5acL"; dkim-atps=neutral Received: from mail-10631.protonmail.ch (mail-10631.protonmail.ch [79.135.106.31]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0E99368545 for ; Tue, 14 Jan 2025 19:22:56 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1736878975; x=1737138175; bh=E+py5E6exHA7vmIVT5/mIvHYdzZID/idMKiZtx4c04c=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=RZPN5acLeBv1ObHP2AwTudZE17Isx+KEXE2cXopsbKX3NqAb6bOc7GHNSNJBZWFzR 9pf3xJ+LZXOy2iECt5axmMi3Wt+s/fCUS3yMvw50ObwVrF45l4x0H3qzpLGHU81ReO bKezO9K0CZFnWBUF8kgJxBw4m7Xc+dS2/5C0TvGS2MDozUTXO6sgUNJLlcM5sixnd6 a7S/WdUA0ozIZI3gkRTDGEqn8N6z003EqaXWnYWdazh+SgeA37bafJqqf95v+iL/BI qJ+shldLf6etSBBMvGTjLCXgt3TN3+5oW9hgYU2HA3ObOM9F+qd95pY4WgHSl0GdMU bmtra5hq9eJFg== Date: Tue, 14 Jan 2025 18:22:52 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [RFC PATCH v2 13/16] apps: lc-compliance: Merge `CaptureBalanced` and `CaptureUnbalanced` Message-ID: <20250114182143.1773762-14-pobrn@protonmail.com> In-Reply-To: <20250114182143.1773762-1-pobrn@protonmail.com> References: <20250114182143.1773762-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: fa7a49b0d387bee46118ff57d8b9e4fbfba14841 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" The above two classes implement very similar, in fact, the only essential difference is how many requests are queued. `CaptureBalanced` queues a predetermined number of requests, while `CaptureUnbalanced` queues requests without limit. This can be addressed by introducing a "capture" and a "queue" limit into the `Capture` class, which determine at most how many requests can be queued, and how many request completions are expected before stopping. Signed-off-by: Barnabás Pőcze --- src/apps/lc-compliance/helpers/capture.cpp | 141 +++++++----------- src/apps/lc-compliance/helpers/capture.h | 50 ++----- src/apps/lc-compliance/tests/capture_test.cpp | 12 +- 3 files changed, 71 insertions(+), 132 deletions(-) diff --git a/src/apps/lc-compliance/helpers/capture.cpp b/src/apps/lc-compliance/helpers/capture.cpp index 43db15d2d..77e87c9e4 100644 --- a/src/apps/lc-compliance/helpers/capture.cpp +++ b/src/apps/lc-compliance/helpers/capture.cpp @@ -7,12 +7,14 @@ #include "capture.h" +#include + #include using namespace libcamera; Capture::Capture(std::shared_ptr camera) - : loop_(nullptr), camera_(std::move(camera)), + : camera_(std::move(camera)), allocator_(camera_) { } @@ -40,153 +42,110 @@ void Capture::configure(StreamRole role) } } -void Capture::start() +void Capture::run(unsigned int captureLimit, std::optional queueLimit) { - Stream *stream = config_->at(0).stream(); - int count = allocator_.allocate(stream); + assert(!queueLimit || captureLimit <= *queueLimit); - ASSERT_GE(count, 0) << "Failed to allocate buffers"; - EXPECT_EQ(count, config_->at(0).bufferCount) << "Allocated less buffers than expected"; + captureLimit_ = captureLimit; + queueLimit_ = queueLimit; - camera_->requestCompleted.connect(this, &Capture::requestComplete); + captureCount_ = queueCount_ = 0; - ASSERT_EQ(camera_->start(), 0) << "Failed to start camera"; -} + EventLoop loop; + loop_ = &loop; -void Capture::stop() -{ - if (!config_ || !allocator_.allocated()) - return; + start(); + prepareRequests(queueLimit_); - camera_->stop(); + for (const auto &request : requests_) + queueRequest(request.get()); - camera_->requestCompleted.disconnect(this); + EXPECT_EQ(loop_->exec(), 0); - Stream *stream = config_->at(0).stream(); - requests_.clear(); - allocator_.free(stream); -} + stop(); -/* CaptureBalanced */ + loop_ = nullptr; -CaptureBalanced::CaptureBalanced(std::shared_ptr camera) - : Capture(std::move(camera)) -{ + EXPECT_LE(captureLimit_, captureCount_); + EXPECT_LE(captureCount_, queueCount_); + EXPECT_TRUE(!queueLimit_ || queueCount_ <= *queueLimit_); } -void CaptureBalanced::capture(unsigned int numRequests) +void Capture::prepareRequests(std::optional queueLimit) { - start(); + assert(config_); + assert(requests_.empty()); Stream *stream = config_->at(0).stream(); const std::vector> &buffers = allocator_.buffers(stream); /* No point in testing less requests then the camera depth. */ - if (buffers.size() > numRequests) { + if (queueLimit && *queueLimit < buffers.size()) { GTEST_SKIP() << "Camera needs " << buffers.size() - << " requests, can't test only " << numRequests; + << " requests, can't test only " << *queueLimit; } - queueCount_ = 0; - captureCount_ = 0; - captureLimit_ = numRequests; - - /* Queue the recommended number of requests. */ for (const std::unique_ptr &buffer : buffers) { std::unique_ptr request = camera_->createRequest(); ASSERT_TRUE(request) << "Can't create request"; ASSERT_EQ(request->addBuffer(stream, buffer.get()), 0) << "Can't set buffer for request"; - ASSERT_EQ(queueRequest(request.get()), 0) << "Failed to queue request"; - requests_.push_back(std::move(request)); } - - /* Run capture session. */ - loop_ = new EventLoop(); - loop_->exec(); - stop(); - delete loop_; - - ASSERT_EQ(captureCount_, captureLimit_); } -int CaptureBalanced::queueRequest(Request *request) +int Capture::queueRequest(libcamera::Request *request) { - queueCount_++; - if (queueCount_ > captureLimit_) + if (queueLimit_ && queueCount_ >= *queueLimit_) return 0; - return camera_->queueRequest(request); + if (int ret = camera_->queueRequest(request); ret < 0) + return ret; + + queueCount_ += 1; + return 0; } -void CaptureBalanced::requestComplete(Request *request) +void Capture::requestComplete(Request *request) { - EXPECT_EQ(request->status(), Request::Status::RequestComplete) - << "Request didn't complete successfully"; - captureCount_++; if (captureCount_ >= captureLimit_) { loop_->exit(0); return; } + EXPECT_EQ(request->status(), Request::Status::RequestComplete) + << "Request didn't complete successfully"; + request->reuse(Request::ReuseBuffers); if (queueRequest(request)) loop_->exit(-EINVAL); } -/* CaptureUnbalanced */ - -CaptureUnbalanced::CaptureUnbalanced(std::shared_ptr camera) - : Capture(std::move(camera)) -{ -} - -void CaptureUnbalanced::capture(unsigned int numRequests) +void Capture::start() { - start(); - Stream *stream = config_->at(0).stream(); - const std::vector> &buffers = allocator_.buffers(stream); - - captureCount_ = 0; - captureLimit_ = numRequests; - - /* Queue the recommended number of requests. */ - for (const std::unique_ptr &buffer : buffers) { - std::unique_ptr request = camera_->createRequest(); - ASSERT_TRUE(request) << "Can't create request"; - - ASSERT_EQ(request->addBuffer(stream, buffer.get()), 0) << "Can't set buffer for request"; - - ASSERT_EQ(camera_->queueRequest(request.get()), 0) << "Failed to queue request"; + int count = allocator_.allocate(stream); - requests_.push_back(std::move(request)); - } + ASSERT_GE(count, 0) << "Failed to allocate buffers"; + EXPECT_EQ(count, config_->at(0).bufferCount) << "Allocated less buffers than expected"; - /* Run capture session. */ - loop_ = new EventLoop(); - int status = loop_->exec(); - stop(); - delete loop_; + camera_->requestCompleted.connect(this, &Capture::requestComplete); - ASSERT_EQ(status, 0); + ASSERT_EQ(camera_->start(), 0) << "Failed to start camera"; } -void CaptureUnbalanced::requestComplete(Request *request) +void Capture::stop() { - captureCount_++; - if (captureCount_ >= captureLimit_) { - loop_->exit(0); + if (!config_ || !allocator_.allocated()) return; - } - EXPECT_EQ(request->status(), Request::Status::RequestComplete) - << "Request didn't complete successfully"; + camera_->stop(); - request->reuse(Request::ReuseBuffers); - if (camera_->queueRequest(request)) - loop_->exit(-EINVAL); + camera_->requestCompleted.disconnect(this); + + Stream *stream = config_->at(0).stream(); + requests_.clear(); + allocator_.free(stream); } diff --git a/src/apps/lc-compliance/helpers/capture.h b/src/apps/lc-compliance/helpers/capture.h index a4cc3a99e..173421fd2 100644 --- a/src/apps/lc-compliance/helpers/capture.h +++ b/src/apps/lc-compliance/helpers/capture.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include @@ -16,51 +17,30 @@ class Capture { public: + Capture(std::shared_ptr camera); + ~Capture(); + void configure(libcamera::StreamRole role); + void run(unsigned int captureLimit, std::optional queueLimit = {}); -protected: - Capture(std::shared_ptr camera); - virtual ~Capture(); +private: + LIBCAMERA_DISABLE_COPY_AND_MOVE(Capture) void start(); void stop(); - virtual void requestComplete(libcamera::Request *request) = 0; - - EventLoop *loop_; + void prepareRequests(std::optional queueLimit = {}); + int queueRequest(libcamera::Request *request); + void requestComplete(libcamera::Request *request); std::shared_ptr camera_; libcamera::FrameBufferAllocator allocator_; std::unique_ptr config_; std::vector> requests_; -}; - -class CaptureBalanced : public Capture -{ -public: - CaptureBalanced(std::shared_ptr camera); - - void capture(unsigned int numRequests); - -private: - int queueRequest(libcamera::Request *request); - void requestComplete(libcamera::Request *request) override; - - unsigned int queueCount_; - unsigned int captureCount_; - unsigned int captureLimit_; -}; - -class CaptureUnbalanced : public Capture -{ -public: - CaptureUnbalanced(std::shared_ptr camera); - - void capture(unsigned int numRequests); - -private: - void requestComplete(libcamera::Request *request) override; - unsigned int captureCount_; - unsigned int captureLimit_; + EventLoop *loop_ = nullptr; + unsigned int captureLimit_ = 0; + std::optional queueLimit_; + unsigned int captureCount_ = 0; + unsigned int queueCount_ = 0; }; diff --git a/src/apps/lc-compliance/tests/capture_test.cpp b/src/apps/lc-compliance/tests/capture_test.cpp index 97465a612..93bed48f0 100644 --- a/src/apps/lc-compliance/tests/capture_test.cpp +++ b/src/apps/lc-compliance/tests/capture_test.cpp @@ -87,11 +87,11 @@ TEST_P(SingleStream, Capture) { auto [role, numRequests] = GetParam(); - CaptureBalanced capture(camera_); + Capture capture(camera_); capture.configure(role); - capture.capture(numRequests); + capture.run(numRequests, numRequests); } /* @@ -106,12 +106,12 @@ TEST_P(SingleStream, CaptureStartStop) auto [role, numRequests] = GetParam(); unsigned int numRepeats = 3; - CaptureBalanced capture(camera_); + Capture capture(camera_); capture.configure(role); for (unsigned int starts = 0; starts < numRepeats; starts++) - capture.capture(numRequests); + capture.run(numRequests, numRequests); } /* @@ -125,11 +125,11 @@ TEST_P(SingleStream, UnbalancedStop) { auto [role, numRequests] = GetParam(); - CaptureUnbalanced capture(camera_); + Capture capture(camera_); capture.configure(role); - capture.capture(numRequests); + capture.run(numRequests); } INSTANTIATE_TEST_SUITE_P(CaptureTests, From patchwork Tue Jan 14 18:22:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22575 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 A7DDBC3304 for ; Tue, 14 Jan 2025 18:23:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5204A6855D; Tue, 14 Jan 2025 19:23:02 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="ZYWdK5Oq"; dkim-atps=neutral Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6199268521 for ; Tue, 14 Jan 2025 19:23:01 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1736878980; x=1737138180; bh=0jgw0oHmttS1F984ihn3jien+MTBhFzi/r9j8a3qC1E=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=ZYWdK5OqRGM5XemR3AXN7dCXW6m3YYWQo+jsuUV5JP+cn0YpjALVSi+jipd9W+wsn fK5elcwbwBCarnhImu3F0pCWQb+/1pXxq0GKXQdgRJxq3LdtwLRwE4kplX9QsOq8O1 RpFeQpFgzsvifzVbtTsYGRsjOw8PKokt3QVI37z0q6FK3EaT4ixXFCm+PbhSoNiHQ5 /GkLpswPDaHr559B/5OHrhY23E0RG4uOWfAdBtn4wqsicNd+CO199OZkt+zE0Vpt6f I49IzPrAPYIGeQBdt2HCEsKycOe5XpashW5p6frpR7I//8LhUwNeN18VZyxfbxs36C CRUB5v/VHwZ+w== Date: Tue, 14 Jan 2025 18:22:56 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Cc: Jacopo Mondi Subject: [RFC PATCH v2 14/16] apps: lc-compliance: Support multiple streams in helpers Message-ID: <20250114182143.1773762-15-pobrn@protonmail.com> In-Reply-To: <20250114182143.1773762-1-pobrn@protonmail.com> References: <20250114182143.1773762-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 670339bc1091abef1cd1c4c165e587de1f14abba 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" Prepare to add a test suite for capture operations with multiple streams. Modify the Capture helper class to support multiple roles and streams in the configure() and capture() operations. Multi-stream support will be added in next patches. Co-developed-by: Jacopo Mondi Signed-off-by: Jacopo Mondi Signed-off-by: Barnabás Pőcze --- src/apps/lc-compliance/helpers/capture.cpp | 77 +++++++++++++++---- src/apps/lc-compliance/helpers/capture.h | 2 +- src/apps/lc-compliance/tests/capture_test.cpp | 6 +- 3 files changed, 66 insertions(+), 19 deletions(-) diff --git a/src/apps/lc-compliance/helpers/capture.cpp b/src/apps/lc-compliance/helpers/capture.cpp index 77e87c9e4..dbaff4138 100644 --- a/src/apps/lc-compliance/helpers/capture.cpp +++ b/src/apps/lc-compliance/helpers/capture.cpp @@ -24,13 +24,31 @@ Capture::~Capture() stop(); } -void Capture::configure(StreamRole role) +void Capture::configure(libcamera::Span roles) { - config_ = camera_->generateConfiguration({ role }); + assert(!roles.empty()); + + config_ = camera_->generateConfiguration(roles); if (!config_) GTEST_SKIP() << "Role not supported by camera"; + ASSERT_EQ(config_->size(), roles.size()) << "Unexpected number of streams in configuration"; + + /* + * Set the buffers count to the largest value across all streams. + * \todo: Should all streams from a Camera have the same buffer count ? + */ + auto largest = + std::max_element(config_->begin(), config_->end(), + [](const StreamConfiguration &l, const StreamConfiguration &r) + { return l.bufferCount < r.bufferCount; }); + + assert(largest != config_->end()); + + for (auto &cfg : *config_) + cfg.bufferCount = largest->bufferCount; + if (config_->validate() != CameraConfiguration::Valid) { config_.reset(); FAIL() << "Configuration not valid"; @@ -76,20 +94,36 @@ void Capture::prepareRequests(std::optional queueLimit) assert(config_); assert(requests_.empty()); - Stream *stream = config_->at(0).stream(); - const std::vector> &buffers = allocator_.buffers(stream); + std::size_t maxBuffers = 0; + + for (const auto &cfg : *config_) { + const auto &buffers = allocator_.buffers(cfg.stream()); + ASSERT_FALSE(buffers.empty()) << "Zero buffers allocated for stream"; + + maxBuffers = std::max(maxBuffers, buffers.size()); + } /* No point in testing less requests then the camera depth. */ - if (queueLimit && *queueLimit < buffers.size()) { - GTEST_SKIP() << "Camera needs " << buffers.size() + if (queueLimit && *queueLimit < maxBuffers) { + GTEST_SKIP() << "Camera needs " << maxBuffers << " requests, can't test only " << *queueLimit; } - for (const std::unique_ptr &buffer : buffers) { - std::unique_ptr request = camera_->createRequest(); + for (std::size_t i = 0; i < maxBuffers; i++) { + std::unique_ptr request = camera_->createRequest(i); ASSERT_TRUE(request) << "Can't create request"; - ASSERT_EQ(request->addBuffer(stream, buffer.get()), 0) << "Can't set buffer for request"; + for (const auto &cfg : *config_) { + Stream *stream = cfg.stream(); + const auto &buffers = allocator_.buffers(stream); + assert(!buffers.empty()); + + if (i >= buffers.size()) + continue; + + ASSERT_EQ(request->addBuffer(stream, buffers[i].get()), 0) + << "Can't add buffer to request"; + } requests_.push_back(std::move(request)); } @@ -125,11 +159,19 @@ void Capture::requestComplete(Request *request) void Capture::start() { - Stream *stream = config_->at(0).stream(); - int count = allocator_.allocate(stream); + assert(config_); + assert(!config_->empty()); + assert(!allocator_.allocated()); + + for (const auto &cfg : *config_) { + Stream *stream = cfg.stream(); + int count = allocator_.allocate(stream); + + ASSERT_GE(count, 0) << "Failed to allocate buffers"; + EXPECT_EQ(count, cfg.bufferCount) << "Allocated less buffers than expected"; + } - ASSERT_GE(count, 0) << "Failed to allocate buffers"; - EXPECT_EQ(count, config_->at(0).bufferCount) << "Allocated less buffers than expected"; + ASSERT_TRUE(allocator_.allocated()); camera_->requestCompleted.connect(this, &Capture::requestComplete); @@ -145,7 +187,12 @@ void Capture::stop() camera_->requestCompleted.disconnect(this); - Stream *stream = config_->at(0).stream(); requests_.clear(); - allocator_.free(stream); + + for (const auto &cfg : *config_) { + int ret = allocator_.free(cfg.stream()); + EXPECT_EQ(ret, 0) << "Failed to free buffers associated with stream"; + } + + EXPECT_FALSE(allocator_.allocated()); } diff --git a/src/apps/lc-compliance/helpers/capture.h b/src/apps/lc-compliance/helpers/capture.h index 173421fd2..391184ad6 100644 --- a/src/apps/lc-compliance/helpers/capture.h +++ b/src/apps/lc-compliance/helpers/capture.h @@ -20,7 +20,7 @@ public: Capture(std::shared_ptr camera); ~Capture(); - void configure(libcamera::StreamRole role); + void configure(libcamera::Span roles); void run(unsigned int captureLimit, std::optional queueLimit = {}); private: diff --git a/src/apps/lc-compliance/tests/capture_test.cpp b/src/apps/lc-compliance/tests/capture_test.cpp index 93bed48f0..147e17019 100644 --- a/src/apps/lc-compliance/tests/capture_test.cpp +++ b/src/apps/lc-compliance/tests/capture_test.cpp @@ -89,7 +89,7 @@ TEST_P(SingleStream, Capture) Capture capture(camera_); - capture.configure(role); + capture.configure(std::array{ role }); capture.run(numRequests, numRequests); } @@ -108,7 +108,7 @@ TEST_P(SingleStream, CaptureStartStop) Capture capture(camera_); - capture.configure(role); + capture.configure(std::array{ role }); for (unsigned int starts = 0; starts < numRepeats; starts++) capture.run(numRequests, numRequests); @@ -127,7 +127,7 @@ TEST_P(SingleStream, UnbalancedStop) Capture capture(camera_); - capture.configure(role); + capture.configure(std::array{ role }); capture.run(numRequests); } From patchwork Tue Jan 14 18:23:00 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22576 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 3C609C3304 for ; Tue, 14 Jan 2025 18:23:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EF51468556; Tue, 14 Jan 2025 19:23:06 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="DtnysL+o"; dkim-atps=neutral Received: from mail-4316.protonmail.ch (mail-4316.protonmail.ch [185.70.43.16]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4DB9768556 for ; Tue, 14 Jan 2025 19:23:05 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1736878984; x=1737138184; bh=nbqBgzGncn5KaKwNqAT9+CCuXrHBvoA3i5chd4mG0iA=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=DtnysL+oNxwE6zVZLeZiaS+V6M12/ttJxB8aYMqbYigLxPhJ3oCMQXqJMjmTqnpmg Fb/8lOghZF1fxwPMToFVQYDjeoacPIrUIRftEmjoLdhoiZ4Et6es8R7L1Ov/GaRTKH n5C9ugwUohWGubBPKBuHym37gREX/LwXVYBWn73MWJ81RGe5m3xBHlo4DMdZNrqemv Lie1SwHHlpD6zGhn9LrrJ7KKyDcoGYBPt1doyx0+Bn1DTpitIM7K88qi8O+6NxtJi5 0alnp8FHgVfFYOTdLQdQAUAO0pAzlhoW8ncJ/QuDHUJq7I465V5IRp/d4Kzz6ZzhmA tvFZZCUa3R4vA== Date: Tue, 14 Jan 2025 18:23:00 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Cc: Jacopo Mondi Subject: [RFC PATCH v2 15/16] apps: lc-compliance: Add multi-stream tests Message-ID: <20250114182143.1773762-16-pobrn@protonmail.com> In-Reply-To: <20250114182143.1773762-1-pobrn@protonmail.com> References: <20250114182143.1773762-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 79f0e69d04502e961355423dc1d53b4274f5ce8c 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" Rename the `SingleStream` test to `SimpleCapture`, and extend it to support using multiple roles. And instantiate another test suite from the `SimpleCapture` test that tests multiple streams in one capture session. Co-developed-by: Jacopo Mondi Signed-off-by: Jacopo Mondi Signed-off-by: Barnabás Pőcze --- src/apps/lc-compliance/tests/capture_test.cpp | 85 +++++++++++-------- 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/src/apps/lc-compliance/tests/capture_test.cpp b/src/apps/lc-compliance/tests/capture_test.cpp index 147e17019..db1d52fc9 100644 --- a/src/apps/lc-compliance/tests/capture_test.cpp +++ b/src/apps/lc-compliance/tests/capture_test.cpp @@ -8,7 +8,7 @@ #include "capture.h" -#include +#include #include @@ -18,19 +18,10 @@ namespace { using namespace libcamera; -const int NUMREQUESTS[] = { 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 }; - -const StreamRole ROLES[] = { - StreamRole::Raw, - StreamRole::StillCapture, - StreamRole::VideoRecording, - StreamRole::Viewfinder -}; - -class SingleStream : public testing::TestWithParam> +class SimpleCapture : public testing::TestWithParam, int>> { public: - static std::string nameParameters(const testing::TestParamInfo &info); + static std::string nameParameters(const testing::TestParamInfo &info); protected: void SetUp() override; @@ -43,7 +34,7 @@ protected: * We use gtest's SetUp() and TearDown() instead of constructor and destructor * in order to be able to assert on them. */ -void SingleStream::SetUp() +void SimpleCapture::SetUp() { Environment *env = Environment::get(); @@ -52,7 +43,7 @@ void SingleStream::SetUp() ASSERT_EQ(camera_->acquire(), 0); } -void SingleStream::TearDown() +void SimpleCapture::TearDown() { if (!camera_) return; @@ -61,19 +52,17 @@ void SingleStream::TearDown() camera_.reset(); } -std::string SingleStream::nameParameters(const testing::TestParamInfo &info) +std::string SimpleCapture::nameParameters(const testing::TestParamInfo &info) { - std::map rolesMap = { - { StreamRole::Raw, "Raw" }, - { StreamRole::StillCapture, "StillCapture" }, - { StreamRole::VideoRecording, "VideoRecording" }, - { StreamRole::Viewfinder, "Viewfinder" } - }; + const auto &[roles, numRequests] = info.param; + std::ostringstream ss; - std::string roleName = rolesMap[std::get<0>(info.param)]; - std::string numRequestsName = std::to_string(std::get<1>(info.param)); + for (StreamRole r : roles) + ss << r << '_'; - return roleName + "_" + numRequestsName; + ss << '_' << numRequests; + + return std::move(ss).str(); } /* @@ -83,13 +72,13 @@ std::string SingleStream::nameParameters(const testing::TestParamInfo SINGLEROLES[] = { + { StreamRole::Raw, }, + { StreamRole::StillCapture, }, + { StreamRole::VideoRecording, }, + { StreamRole::Viewfinder, }, +}; + +const std::vector MULTIROLES[] = { + { StreamRole::Raw, StreamRole::StillCapture }, + { StreamRole::Raw, StreamRole::VideoRecording }, + { StreamRole::StillCapture, StreamRole::VideoRecording }, + { StreamRole::VideoRecording, StreamRole::VideoRecording }, +}; + +INSTANTIATE_TEST_SUITE_P(SingleStream, + SimpleCapture, + testing::Combine(testing::ValuesIn(SINGLEROLES), + testing::ValuesIn(NUMREQUESTS)), + SimpleCapture::nameParameters); + +INSTANTIATE_TEST_SUITE_P(MultiStream, + SimpleCapture, + testing::Combine(testing::ValuesIn(MULTIROLES), testing::ValuesIn(NUMREQUESTS)), - SingleStream::nameParameters); + SimpleCapture::nameParameters); } /* namespace */ From patchwork Tue Jan 14 18:23:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22577 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 BFAEAC3304 for ; Tue, 14 Jan 2025 18:23:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7868368562; Tue, 14 Jan 2025 19:23:12 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="owY7BZKR"; dkim-atps=neutral Received: from mail-40131.protonmail.ch (mail-40131.protonmail.ch [185.70.40.131]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2E18468560 for ; Tue, 14 Jan 2025 19:23:11 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1736878989; x=1737138189; bh=5pID2MA8VOFbZIuXw2qYio4RxdA4dJ8xJoviCGtAhlM=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=owY7BZKRPsbc8lKZzdINCT7687upzmtZAJiWyUdcBhWHew/KIPGJTVHsXHxEDyYXj gGl3oEvp404JYv/eSZWYvrqZtm0AH67oPyPFuYByoVtZf9LQOAY7EJJIzT6/45Woyo gh2XRnkksVkhYfhDEN3448XVyljCy01QpeoKm4kL46GLkKDFnc6YRG8F2Ot0bbxeee IfSuPghsIxM5nXcp1nQvu7ODchWnLb5xr+9qvk3k3ccFOvCIWarDuoPYKI5pWSv0dc 9lnubmqU0GZ2ttzxnXFWXxJ+eQF18osHKNHQpYXLu2IRJw9RuEI9nk1kchie5VeMZX Txl4B0bxalltg== Date: Tue, 14 Jan 2025 18:23:05 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [RFC PATCH v2 16/16] apps: lc-compliance: Run request completion handler in "main" thread Message-ID: <20250114182143.1773762-17-pobrn@protonmail.com> In-Reply-To: <20250114182143.1773762-1-pobrn@protonmail.com> References: <20250114182143.1773762-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 6272a51921d450ec30a7bf583bae3c870de9ce89 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" Currently, `Capture::requestCompleted()` runs in the `CameraManager`'s thread. This makes it a bit more complicated to use googletest and report errors in those callbacks since lc-compliance sets up googletest to throw exceptions on fatal errors / test skip, but those exceptions are only caught on the "main" thread, the one running the test suite. To minimize the burden of dealing with synchronization in tests, execute `Capture::requestCompleted()` in the event loop's thread by utilizing `EventLoop::callLater()`. Signed-off-by: Barnabás Pőcze --- src/apps/lc-compliance/helpers/capture.cpp | 21 ++++++++++++--------- src/apps/lc-compliance/helpers/capture.h | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/apps/lc-compliance/helpers/capture.cpp b/src/apps/lc-compliance/helpers/capture.cpp index dbaff4138..528a3a13a 100644 --- a/src/apps/lc-compliance/helpers/capture.cpp +++ b/src/apps/lc-compliance/helpers/capture.cpp @@ -129,16 +129,13 @@ void Capture::prepareRequests(std::optional queueLimit) } } -int Capture::queueRequest(libcamera::Request *request) +void Capture::queueRequest(libcamera::Request *request) { if (queueLimit_ && queueCount_ >= *queueLimit_) - return 0; - - if (int ret = camera_->queueRequest(request); ret < 0) - return ret; + return; + ASSERT_EQ(camera_->queueRequest(request), 0); queueCount_ += 1; - return 0; } void Capture::requestComplete(Request *request) @@ -153,8 +150,7 @@ void Capture::requestComplete(Request *request) << "Request didn't complete successfully"; request->reuse(Request::ReuseBuffers); - if (queueRequest(request)) - loop_->exit(-EINVAL); + queueRequest(request); } void Capture::start() @@ -173,7 +169,14 @@ void Capture::start() ASSERT_TRUE(allocator_.allocated()); - camera_->requestCompleted.connect(this, &Capture::requestComplete); + camera_->requestCompleted.connect(this, [this](libcamera::Request *request) { + /* Runs in the CameraManager thread. */ + + loop_->callLater([this, request] { + /* Run handler in the context of the event loop. */ + requestComplete(request); + }); + }); ASSERT_EQ(camera_->start(), 0) << "Failed to start camera"; } diff --git a/src/apps/lc-compliance/helpers/capture.h b/src/apps/lc-compliance/helpers/capture.h index 391184ad6..9003a0934 100644 --- a/src/apps/lc-compliance/helpers/capture.h +++ b/src/apps/lc-compliance/helpers/capture.h @@ -30,7 +30,7 @@ private: void stop(); void prepareRequests(std::optional queueLimit = {}); - int queueRequest(libcamera::Request *request); + void queueRequest(libcamera::Request *request); void requestComplete(libcamera::Request *request); std::shared_ptr camera_;