From patchwork Thu May 6 18:02:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= X-Patchwork-Id: 12213 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 DE043BDE7F for ; Thu, 6 May 2021 18:04:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A578568926; Thu, 6 May 2021 20:04:02 +0200 (CEST) Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 30D8D68926 for ; Thu, 6 May 2021 20:04:01 +0200 (CEST) Received: from localhost.localdomain (unknown [IPv6:2804:14c:1a9:2978:995d:672b:100f:2fd9]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: nfraprado) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 6A3B11F43B94; Thu, 6 May 2021 19:03:59 +0100 (BST) From: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= To: libcamera-devel@lists.libcamera.org Date: Thu, 6 May 2021 15:02:47 -0300 Message-Id: <20210506180249.318346-5-nfraprado@collabora.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210506180249.318346-1-nfraprado@collabora.com> References: <20210506180249.318346-1-nfraprado@collabora.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 4/6] lc-compliance: Add test to queue more requests than hardware depth 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: , Cc: kernel@collabora.com, =?utf-8?q?Andr=C3=A9_Almeida?= Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" A pipeline handler should be able to handle an arbitrary number of simultaneous requests by submitting what it can to the video device and queuing the rest internally until resources are available. This isn't currently done by some pipeline handlers however [1]. Add a new test to lc-compliance that submits a lot of requests at once to check if the pipeline handler is behaving well in this situation. [1] https://bugs.libcamera.org/show_bug.cgi?id=24 Signed-off-by: NĂ­colas F. R. A. Prado --- src/lc-compliance/simple_capture.cpp | 48 ++++++++++++++++++++++++++++ src/lc-compliance/simple_capture.h | 12 +++++++ src/lc-compliance/single_stream.cpp | 31 +++++++++++++++++- 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/src/lc-compliance/simple_capture.cpp b/src/lc-compliance/simple_capture.cpp index bb173ef1f71a..598c5aebe033 100644 --- a/src/lc-compliance/simple_capture.cpp +++ b/src/lc-compliance/simple_capture.cpp @@ -249,3 +249,51 @@ void SimpleCaptureUnbalanced::requestComplete(Request *request) if (camera_->queueRequest(request)) loop_->exit(-EINVAL); } + +/* SimpleCaptureOverflow */ + +SimpleCaptureOverflow::SimpleCaptureOverflow(std::shared_ptr camera) + : SimpleCapture(camera) +{ +} + +Results::Result SimpleCaptureOverflow::capture() +{ + Results::Result ret = start(); + if (ret.first != Results::Pass) + return ret; + + Stream *stream = config_->at(0).stream(); + const std::vector> &buffers = allocator_->buffers(stream); + + captureCount_ = 0; + captureLimit_ = buffers.size(); + + std::vector> requests; + ret = queueRequests(stream, requests, buffers); + if (ret.first != Results::Pass) + return ret; + + runCaptureSession(); + + if (captureCount_ != captureLimit_) + return { Results::Fail, "Got " + std::to_string(captureCount_) + + " request, wanted " + std::to_string(captureLimit_) }; + + return { Results::Pass, "Overflow capture of " + + std::to_string(captureLimit_) + " requests" }; +} + +void SimpleCaptureOverflow::requestComplete([[maybe_unused]] Request *request) +{ + captureCompleted(); +} + +Results::Result SimpleCaptureOverflow::allocateBuffers(unsigned int count) +{ + Stream *stream = config_->at(0).stream(); + if (allocator_->allocate(stream, count) < 0) + return { Results::Fail, "Failed to allocate buffers" }; + + return { Results::Pass, "Allocated buffers" }; +} diff --git a/src/lc-compliance/simple_capture.h b/src/lc-compliance/simple_capture.h index 8d0f94f0c3e5..3b818c640477 100644 --- a/src/lc-compliance/simple_capture.h +++ b/src/lc-compliance/simple_capture.h @@ -72,4 +72,16 @@ private: void requestComplete(libcamera::Request *request) override; }; +class SimpleCaptureOverflow : public SimpleCapture +{ +public: + SimpleCaptureOverflow(std::shared_ptr camera); + + Results::Result allocateBuffers(unsigned int count); + Results::Result capture(); + +private: + void requestComplete(libcamera::Request *request) override; +}; + #endif /* __LC_COMPLIANCE_SIMPLE_CAPTURE_H__ */ diff --git a/src/lc-compliance/single_stream.cpp b/src/lc-compliance/single_stream.cpp index 649291c7bb73..7035d9cf5df5 100644 --- a/src/lc-compliance/single_stream.cpp +++ b/src/lc-compliance/single_stream.cpp @@ -12,6 +12,23 @@ using namespace libcamera; +static const unsigned int MAX_SIMULTANEOUS_REQUESTS = 8; + +Results::Result testRequestOverflow(std::shared_ptr camera, + StreamRole role, unsigned int numRequests) +{ + SimpleCaptureOverflow capture(camera); + + Results::Result ret = capture.configure(role); + if (ret.first != Results::Pass) + return ret; + capture.allocateBuffers(numRequests); + if (ret.first != Results::Pass) + return ret; + + return capture.capture(); +} + Results::Result testRequestBalance(std::shared_ptr camera, StreamRole role, unsigned int startCycles, unsigned int numRequests) @@ -61,7 +78,7 @@ Results testSingleStream(std::shared_ptr camera) }; static const std::vector numRequests = { 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 }; - Results results(numRequests.size() * roles.size() * 3); + Results results(numRequests.size() * roles.size() * 3 + roles.size()); for (const auto &role : roles) { std::cout << "= Test role " << role.first << std::endl; @@ -97,6 +114,18 @@ Results testSingleStream(std::shared_ptr camera) std::cout << "* Test unbalanced stop" << std::endl; for (unsigned int num : numRequests) results.add(testRequestUnbalance(camera, role.second, num)); + + /* + * Test overflowing pipeline with requests + * + * Makes sure that the camera supports receiving a large number + * of requests at once. Example failure is a camera that doesn't + * check if there are available resources (free internal + * buffers, free buffers in the video devices) before handling a + * request. + */ + std::cout << "* Test overflowing requests" << std::endl; + results.add(testRequestOverflow(camera, role.second, MAX_SIMULTANEOUS_REQUESTS)); } return results;