From patchwork Fri Dec 20 15:08:51 2024 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: 22437 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 21A3BC3272 for ; Fri, 20 Dec 2024 15:09:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7B856684B6; Fri, 20 Dec 2024 16:09:00 +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="pZ2QhNyS"; 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 140FD684AE for ; Fri, 20 Dec 2024 16:08:58 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1734707336; x=1734966536; bh=C7RsNeSb066QbfUOWol90VEasHYTTm4kBKkdKoQGcKY=; 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=pZ2QhNySdCDVEPJ6vafbz1Gqr8Vp+gk8yrByfwV7ADxCjn0o2JVuYCMJasobOa1vJ T3IwY3wp63VYAwmomQPCcsdkeFbtBM0awhwrB7mGuZBxAud8ZCbD0d5TaeNRmjhOLu SRRwkua3gqB9UzbisnoR3sGOU+OCJSbjLsBjg4SWd+YE6pRdHYajxj+DxiQ6Mp5+o6 o5k+bSORiWrPWmssrQ2iVe/45VSOehlCuBDBsn2yRkqph46ocsnnq6fCIPzHV4N4oG iNyccoljpZeFUi6LvATwiBLy9Pltvfe2FK9A0ih8lSr9AFnNfBfilVeFyCMMhoPYiP gRr/aDmTEWvYA== Date: Fri, 20 Dec 2024 15:08:51 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Cc: Jacopo Mondi Subject: [RFC PATCH v1 11/12] apps: lc-compliance: Support multiple streams in helpers Message-ID: <20241220150759.709756-12-pobrn@protonmail.com> In-Reply-To: <20241220150759.709756-1-pobrn@protonmail.com> References: <20241220150759.709756-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 24cc50e67843f5a4cf4c8658dab53a16b8dc8fca 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 Reviewed-by: Laurent Pinchart --- src/apps/lc-compliance/helpers/capture.cpp | 83 ++++++++++++++----- src/apps/lc-compliance/helpers/capture.h | 2 +- src/apps/lc-compliance/tests/capture_test.cpp | 6 +- 3 files changed, 66 insertions(+), 25 deletions(-) diff --git a/src/apps/lc-compliance/helpers/capture.cpp b/src/apps/lc-compliance/helpers/capture.cpp index 7a05be9a3..38edb6f28 100644 --- a/src/apps/lc-compliance/helpers/capture.cpp +++ b/src/apps/lc-compliance/helpers/capture.cpp @@ -24,15 +24,29 @@ 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_) { std::cout << "Role not supported by camera" << std::endl; GTEST_SKIP(); } + /* + * 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; }); + + for (auto &cfg : *config_) + cfg.bufferCount = largest->bufferCount; + if (config_->validate() != CameraConfiguration::Valid) { config_.reset(); FAIL() << "Configuration not valid"; @@ -46,12 +60,20 @@ void Capture::configure(StreamRole role) 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_EQ(count, allocator_.buffers(stream).size()) << "Unexpected number of buffers in allocator"; + } - ASSERT_GE(count, 0) << "Failed to allocate buffers"; - EXPECT_EQ(count, config_->at(0).bufferCount) << "Allocated less buffers than expected"; - ASSERT_EQ(count, allocator_.buffers(stream).size()) << "Unexpected number of buffers in allocator"; + ASSERT_TRUE(allocator_.allocated()); camera_->requestCompleted.connect(this, &Capture::requestComplete); @@ -71,9 +93,14 @@ void Capture::stop() camera_->requestCompleted.disconnect(this); - Stream *stream = config_->at(0).stream(); requests_.clear(); - allocator_.free(stream); + + for (const auto &cfg : *config_) { + int res = allocator_.free(cfg.stream()); + ASSERT_EQ(res, 0) << "Failed to free buffers associated with stream"; + } + + ASSERT_FALSE(allocator_.allocated()); } void Capture::prepareRequests(unsigned int plannedRequests) @@ -81,22 +108,36 @@ void Capture::prepareRequests(unsigned int plannedRequests) assert(config_); assert(requests_.empty()); - Stream *stream = config_->at(0).stream(); - const std::vector> &buffers = allocator_.buffers(stream); + std::size_t maxBuffers = 0; - /* No point in testing less requests then the camera depth. */ - if (plannedRequests < buffers.size()) { - std::cout << "Camera needs " << buffers.size() - << " requests, can't test only " - << plannedRequests << std::endl; - GTEST_SKIP(); + for (const auto &cfg : *config_) { + const auto &buffers = allocator_.buffers(cfg.stream()); + ASSERT_FALSE(buffers.empty()) << "Zero buffers allocated for stream"; + + /* No point in testing less requests then the camera depth. */ + if (plannedRequests < buffers.size()) { + std::cout << "Camera needs " << buffers.size() + << " requests, can't test only " + << plannedRequests << std::endl; + GTEST_SKIP(); + } + + maxBuffers = std::max(maxBuffers, buffers.size()); } - for (const std::unique_ptr &buffer : buffers) { - std::unique_ptr request = camera_->createRequest(); - ASSERT_TRUE(request) << "Can't create request"; + for (std::size_t i = 0; i < maxBuffers; i++) { + std::unique_ptr request = camera_->createRequest(i); + + for (const auto &cfg : *config_) { + Stream *stream = cfg.stream(); + const auto &buffers = allocator_.buffers(stream); + assert(!buffers.empty()); - ASSERT_EQ(request->addBuffer(stream, buffer.get()), 0) << "Can't set buffer for request"; + if (i < buffers.size()) { + ASSERT_EQ(request->addBuffer(stream, buffers[i].get()), 0) + << "Can't add buffer to request"; + } + } requests_.push_back(std::move(request)); } diff --git a/src/apps/lc-compliance/helpers/capture.h b/src/apps/lc-compliance/helpers/capture.h index 67c29021b..b3a390941 100644 --- a/src/apps/lc-compliance/helpers/capture.h +++ b/src/apps/lc-compliance/helpers/capture.h @@ -17,7 +17,7 @@ class Capture { public: - void configure(libcamera::StreamRole role); + void configure(libcamera::Span roles); protected: Capture(std::shared_ptr camera); diff --git a/src/apps/lc-compliance/tests/capture_test.cpp b/src/apps/lc-compliance/tests/capture_test.cpp index 97465a612..c382fcf47 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) CaptureBalanced capture(camera_); - capture.configure(role); + capture.configure(std::array{ role }); capture.capture(numRequests); } @@ -108,7 +108,7 @@ TEST_P(SingleStream, CaptureStartStop) CaptureBalanced capture(camera_); - capture.configure(role); + capture.configure(std::array{ role }); for (unsigned int starts = 0; starts < numRepeats; starts++) capture.capture(numRequests); @@ -127,7 +127,7 @@ TEST_P(SingleStream, UnbalancedStop) CaptureUnbalanced capture(camera_); - capture.configure(role); + capture.configure(std::array{ role }); capture.capture(numRequests); }