From patchwork Fri Apr 16 22:28:29 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: 11971 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 212E7BD237 for ; Fri, 16 Apr 2021 22:29:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DF15468816; Sat, 17 Apr 2021 00:29:20 +0200 (CEST) Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [46.235.227.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3EEB86880A for ; Sat, 17 Apr 2021 00:29:19 +0200 (CEST) Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: nfraprado) with ESMTPSA id A00141F43A4D From: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= To: libcamera-devel@lists.libcamera.org Date: Fri, 16 Apr 2021 19:28:29 -0300 Message-Id: <20210416222830.335755-2-nfraprado@collabora.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210416222830.335755-1-nfraprado@collabora.com> References: <20210416222830.335755-1-nfraprado@collabora.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 1/2] libcamera: framebuffer_allocator: Make allocate() accept count 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" Add a 'count' argument to FrameBufferAllocator::allocate() so that a custom amount of buffers can be allocated. If 0 is passed, the pipeline handler allocates the default amount, which is the configured bufferCount. Signed-off-by: NĂ­colas F. R. A. Prado --- include/libcamera/camera.h | 3 ++- include/libcamera/framebuffer_allocator.h | 2 +- include/libcamera/internal/pipeline_handler.h | 3 ++- src/cam/capture.cpp | 2 +- src/lc-compliance/simple_capture.cpp | 8 ++++---- src/lc-compliance/simple_capture.h | 2 +- src/libcamera/camera.cpp | 5 +++-- src/libcamera/framebuffer_allocator.cpp | 5 +++-- src/libcamera/pipeline/ipu3/ipu3.cpp | 9 ++++++--- src/libcamera/pipeline/raspberrypi/raspberrypi.cpp | 9 ++++++--- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 9 ++++++--- src/libcamera/pipeline/simple/simple.cpp | 9 ++++++--- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 9 ++++++--- src/libcamera/pipeline/vimc/vimc.cpp | 9 ++++++--- src/libcamera/pipeline_handler.cpp | 1 + src/qcam/main_window.cpp | 2 +- test/camera/capture.cpp | 2 +- test/camera/statemachine.cpp | 2 +- test/mapped-buffer.cpp | 2 +- 19 files changed, 58 insertions(+), 35 deletions(-) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 326b14d0ca01..ef6113113b6c 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -116,7 +116,8 @@ private: friend class FrameBufferAllocator; int exportFrameBuffers(Stream *stream, - std::vector> *buffers); + std::vector> *buffers, + unsigned int count); }; } /* namespace libcamera */ diff --git a/include/libcamera/framebuffer_allocator.h b/include/libcamera/framebuffer_allocator.h index 0c85631a1da2..f1ae37288d50 100644 --- a/include/libcamera/framebuffer_allocator.h +++ b/include/libcamera/framebuffer_allocator.h @@ -25,7 +25,7 @@ public: FrameBufferAllocator(std::shared_ptr camera); ~FrameBufferAllocator(); - int allocate(Stream *stream); + int allocate(Stream *stream, unsigned int count); int free(Stream *stream); bool allocated() const { return !buffers_.empty(); } diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index c6454db6b2c4..37c51f3f0604 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -76,7 +76,8 @@ public: virtual int configure(Camera *camera, CameraConfiguration *config) = 0; virtual int exportFrameBuffers(Camera *camera, Stream *stream, - std::vector> *buffers) = 0; + std::vector> *buffers, + unsigned int count) = 0; virtual int start(Camera *camera, const ControlList *controls) = 0; virtual void stop(Camera *camera) = 0; diff --git a/src/cam/capture.cpp b/src/cam/capture.cpp index 7b55fc677022..dc24b12f4d10 100644 --- a/src/cam/capture.cpp +++ b/src/cam/capture.cpp @@ -80,7 +80,7 @@ int Capture::capture(FrameBufferAllocator *allocator) /* Identify the stream with the least number of buffers. */ unsigned int nbuffers = UINT_MAX; for (StreamConfiguration &cfg : *config_) { - ret = allocator->allocate(cfg.stream()); + ret = allocator->allocate(cfg.stream(), 0); if (ret < 0) { std::cerr << "Can't allocate buffers" << std::endl; return -ENOMEM; diff --git a/src/lc-compliance/simple_capture.cpp b/src/lc-compliance/simple_capture.cpp index 64e862a08e3a..42e4c9b1302d 100644 --- a/src/lc-compliance/simple_capture.cpp +++ b/src/lc-compliance/simple_capture.cpp @@ -39,10 +39,10 @@ Results::Result SimpleCapture::configure(StreamRole role) return { Results::Pass, "Configure camera" }; } -Results::Result SimpleCapture::start() +Results::Result SimpleCapture::start(unsigned int numBuffers) { Stream *stream = config_->at(0).stream(); - if (allocator_->allocate(stream) < 0) + if (allocator_->allocate(stream, numBuffers) < 0) return { Results::Fail, "Failed to allocate buffers" }; if (camera_->start()) @@ -73,7 +73,7 @@ SimpleCaptureBalanced::SimpleCaptureBalanced(std::shared_ptr camera) Results::Result SimpleCaptureBalanced::capture(unsigned int numRequests) { - Results::Result ret = start(); + Results::Result ret = start(0); if (ret.first != Results::Pass) return ret; @@ -161,7 +161,7 @@ SimpleCaptureUnbalanced::SimpleCaptureUnbalanced(std::shared_ptr camera) Results::Result SimpleCaptureUnbalanced::capture(unsigned int numRequests) { - Results::Result ret = start(); + Results::Result ret = start(0); if (ret.first != Results::Pass) return ret; diff --git a/src/lc-compliance/simple_capture.h b/src/lc-compliance/simple_capture.h index d9de53fb63a3..2b1493ecaf96 100644 --- a/src/lc-compliance/simple_capture.h +++ b/src/lc-compliance/simple_capture.h @@ -23,7 +23,7 @@ protected: SimpleCapture(std::shared_ptr camera); virtual ~SimpleCapture(); - Results::Result start(); + Results::Result start(unsigned int numBuffers); void stop(); virtual void requestComplete(libcamera::Request *request) = 0; diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 763f3b9926fd..7df110ee2f52 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -657,7 +657,8 @@ void Camera::disconnect() } int Camera::exportFrameBuffers(Stream *stream, - std::vector> *buffers) + std::vector> *buffers, + unsigned int count) { Private *const d = LIBCAMERA_D_PTR(); @@ -673,7 +674,7 @@ int Camera::exportFrameBuffers(Stream *stream, return d->pipe_->invokeMethod(&PipelineHandler::exportFrameBuffers, ConnectionTypeBlocking, this, stream, - buffers); + buffers, count); } /** diff --git a/src/libcamera/framebuffer_allocator.cpp b/src/libcamera/framebuffer_allocator.cpp index 2fbba37a1b0b..6b07203017cd 100644 --- a/src/libcamera/framebuffer_allocator.cpp +++ b/src/libcamera/framebuffer_allocator.cpp @@ -70,6 +70,7 @@ FrameBufferAllocator::~FrameBufferAllocator() /** * \brief Allocate buffers for a configured stream * \param[in] stream The stream to allocate buffers for + * \param[in] count The amount of buffers to allocate * * Allocate buffers suitable for capturing frames from the \a stream. The Camera * shall have been previously configured with Camera::configure() and shall be @@ -85,14 +86,14 @@ FrameBufferAllocator::~FrameBufferAllocator() * not part of the active camera configuration * \retval -EBUSY Buffers are already allocated for the \a stream */ -int FrameBufferAllocator::allocate(Stream *stream) +int FrameBufferAllocator::allocate(Stream *stream, unsigned int count) { if (buffers_.count(stream)) { LOG(Allocator, Error) << "Buffers already allocated for stream"; return -EBUSY; } - int ret = camera_->exportFrameBuffers(stream, &buffers_[stream]); + int ret = camera_->exportFrameBuffers(stream, &buffers_[stream], count); if (ret == -EINVAL) LOG(Allocator, Error) << "Stream is not part of " << camera_->id() diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 519cad4f8148..7a44900b9fbc 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -131,7 +131,8 @@ public: int configure(Camera *camera, CameraConfiguration *config) override; int exportFrameBuffers(Camera *camera, Stream *stream, - std::vector> *buffers) override; + std::vector> *buffers, + unsigned int count) override; int start(Camera *camera, const ControlList *controls) override; void stop(Camera *camera) override; @@ -641,10 +642,12 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) } int PipelineHandlerIPU3::exportFrameBuffers(Camera *camera, Stream *stream, - std::vector> *buffers) + std::vector> *buffers, + unsigned int count) { IPU3CameraData *data = cameraData(camera); - unsigned int count = stream->configuration().bufferCount; + if (!count) + count = stream->configuration().bufferCount; if (stream == &data->outStream_) return data->imgu_->output_->exportBuffers(count, buffers); diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index f22e286ed87a..3ab27123b1ac 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -250,7 +250,8 @@ public: int configure(Camera *camera, CameraConfiguration *config) override; int exportFrameBuffers(Camera *camera, Stream *stream, - std::vector> *buffers) override; + std::vector> *buffers, + unsigned int count) override; int start(Camera *camera, const ControlList *controls) override; void stop(Camera *camera) override; @@ -786,10 +787,12 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) } int PipelineHandlerRPi::exportFrameBuffers([[maybe_unused]] Camera *camera, Stream *stream, - std::vector> *buffers) + std::vector> *buffers, + unsigned int count) { RPi::Stream *s = static_cast(stream); - unsigned int count = stream->configuration().bufferCount; + if (!count) + count = stream->configuration().bufferCount; int ret = s->dev()->exportBuffers(count, buffers); s->setExportedBuffers(buffers); diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 549f4a4e61a8..4cc3c7739251 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -140,7 +140,8 @@ public: int configure(Camera *camera, CameraConfiguration *config) override; int exportFrameBuffers(Camera *camera, Stream *stream, - std::vector> *buffers) override; + std::vector> *buffers, + unsigned int count) override; int start(Camera *camera, const ControlList *controls) override; void stop(Camera *camera) override; @@ -666,10 +667,12 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) } int PipelineHandlerRkISP1::exportFrameBuffers([[maybe_unused]] Camera *camera, Stream *stream, - std::vector> *buffers) + std::vector> *buffers, + unsigned int count) { RkISP1CameraData *data = cameraData(camera); - unsigned int count = stream->configuration().bufferCount; + if (!count) + count = stream->configuration().bufferCount; if (stream == &data->mainPathStream_) return mainPath_.exportBuffers(count, buffers); diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index f6095d38e97a..e9b0698813fc 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -223,7 +223,8 @@ public: int configure(Camera *camera, CameraConfiguration *config) override; int exportFrameBuffers(Camera *camera, Stream *stream, - std::vector> *buffers) override; + std::vector> *buffers, + unsigned int count) override; int start(Camera *camera, const ControlList *controls) override; void stop(Camera *camera) override; @@ -762,10 +763,12 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c) } int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream, - std::vector> *buffers) + std::vector> *buffers, + unsigned int count) { SimpleCameraData *data = cameraData(camera); - unsigned int count = stream->configuration().bufferCount; + if (!count) + count = stream->configuration().bufferCount; /* * Export buffers on the converter or capture video node, depending on diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index b6c6ade5ebaf..298e7031d23b 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -70,7 +70,8 @@ public: int configure(Camera *camera, CameraConfiguration *config) override; int exportFrameBuffers(Camera *camera, Stream *stream, - std::vector> *buffers) override; + std::vector> *buffers, + unsigned int count) override; int start(Camera *camera, const ControlList *controls) override; void stop(Camera *camera) override; @@ -224,10 +225,12 @@ int PipelineHandlerUVC::configure(Camera *camera, CameraConfiguration *config) } int PipelineHandlerUVC::exportFrameBuffers(Camera *camera, Stream *stream, - std::vector> *buffers) + std::vector> *buffers, + unsigned int count) { UVCCameraData *data = cameraData(camera); - unsigned int count = stream->configuration().bufferCount; + if (!count) + count = stream->configuration().bufferCount; return data->video_->exportBuffers(count, buffers); } diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 8f5f4ba30953..2f889347b624 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -84,7 +84,8 @@ public: int configure(Camera *camera, CameraConfiguration *config) override; int exportFrameBuffers(Camera *camera, Stream *stream, - std::vector> *buffers) override; + std::vector> *buffers, + unsigned int count) override; int start(Camera *camera, const ControlList *controls) override; void stop(Camera *camera) override; @@ -299,10 +300,12 @@ int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config) } int PipelineHandlerVimc::exportFrameBuffers(Camera *camera, Stream *stream, - std::vector> *buffers) + std::vector> *buffers, + unsigned int count) { VimcCameraData *data = cameraData(camera); - unsigned int count = stream->configuration().bufferCount; + if (!count) + count = stream->configuration().bufferCount; return data->video_->exportBuffers(count, buffers); } diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 3b3150bdbbf7..ab5f21a01438 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -323,6 +323,7 @@ const ControlList &PipelineHandler::properties(const Camera *camera) const * \param[in] camera The camera * \param[in] stream The stream to allocate buffers for * \param[out] buffers Array of buffers successfully allocated + * \param[in] count The amount of buffers to allocate * * This method allocates buffers for the \a stream from the devices associated * with the stream in the corresponding pipeline handler. Those buffers shall be diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 39d034de6bb2..4e1dbb0656c8 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -463,7 +463,7 @@ int MainWindow::startCapture() for (StreamConfiguration &config : *config_) { Stream *stream = config.stream(); - ret = allocator_->allocate(stream); + ret = allocator_->allocate(stream, 0); if (ret < 0) { qWarning() << "Failed to allocate capture buffers"; goto error; diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp index c4bc21100777..6cbca15b30bc 100644 --- a/test/camera/capture.cpp +++ b/test/camera/capture.cpp @@ -96,7 +96,7 @@ protected: Stream *stream = cfg.stream(); - int ret = allocator_->allocate(stream); + int ret = allocator_->allocate(stream, 0); if (ret < 0) return TestFail; diff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp index f0c3d7764027..9e076d05bc6f 100644 --- a/test/camera/statemachine.cpp +++ b/test/camera/statemachine.cpp @@ -118,7 +118,7 @@ protected: /* Use internally allocated buffers. */ allocator_ = new FrameBufferAllocator(camera_); Stream *stream = *camera_->streams().begin(); - if (allocator_->allocate(stream) < 0) + if (allocator_->allocate(stream, 0) < 0) return TestFail; if (camera_->start()) diff --git a/test/mapped-buffer.cpp b/test/mapped-buffer.cpp index 5de8201e45f6..f5c2e2c0169a 100644 --- a/test/mapped-buffer.cpp +++ b/test/mapped-buffer.cpp @@ -54,7 +54,7 @@ protected: stream_ = cfg.stream(); - int ret = allocator_->allocate(stream_); + int ret = allocator_->allocate(stream_, 0); if (ret < 0) return TestFail; From patchwork Fri Apr 16 22:28:30 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: 11972 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 E38A4BD237 for ; Fri, 16 Apr 2021 22:29:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A82B168812; Sat, 17 Apr 2021 00:29:22 +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 3D95368814 for ; Sat, 17 Apr 2021 00:29:21 +0200 (CEST) Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: nfraprado) with ESMTPSA id 89A7F1F43A4A From: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= To: libcamera-devel@lists.libcamera.org Date: Fri, 16 Apr 2021 19:28:30 -0300 Message-Id: <20210416222830.335755-3-nfraprado@collabora.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210416222830.335755-1-nfraprado@collabora.com> References: <20210416222830.335755-1-nfraprado@collabora.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/2] 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" A pipeline handler should be able to handle an arbitrary amount 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 | 61 ++++++++++++++++++++++++++++ src/lc-compliance/simple_capture.h | 14 +++++++ src/lc-compliance/single_stream.cpp | 28 ++++++++++++- 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/src/lc-compliance/simple_capture.cpp b/src/lc-compliance/simple_capture.cpp index 42e4c9b1302d..26d91e036656 100644 --- a/src/lc-compliance/simple_capture.cpp +++ b/src/lc-compliance/simple_capture.cpp @@ -214,3 +214,64 @@ void SimpleCaptureUnbalanced::requestComplete(Request *request) if (camera_->queueRequest(request)) loop_->exit(-EINVAL); } + +SimpleCaptureOverflow::SimpleCaptureOverflow(std::shared_ptr camera) + : SimpleCapture(camera) +{ +} + +Results::Result SimpleCaptureOverflow::capture(unsigned int numRequests) +{ + Results::Result ret = start(numRequests); + if (ret.first != Results::Pass) + return ret; + + Stream *stream = config_->at(0).stream(); + const std::vector> &buffers = allocator_->buffers(stream); + + captureCount_ = 0; + captureLimit_ = numRequests; + + std::vector> requests; + for (const std::unique_ptr &buffer : buffers) { + std::unique_ptr request = camera_->createRequest(); + if (!request) { + stop(); + return { Results::Fail, "Can't create request" }; + } + + if (request->addBuffer(stream, buffer.get())) { + stop(); + return { Results::Fail, "Can't set buffer for request" }; + } + + if (camera_->queueRequest(request.get()) < 0) { + stop(); + return { Results::Fail, "Failed to queue request" }; + } + + requests.push_back(std::move(request)); + } + + /* Run capture session. */ + loop_ = new EventLoop(); + loop_->exec(); + stop(); + delete loop_; + + 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(numRequests) + " requests" }; +} + +void SimpleCaptureOverflow::requestComplete([[maybe_unused]]Request *request) +{ + captureCount_++; + if (captureCount_ >= captureLimit_) { + loop_->exit(0); + return; + } +} diff --git a/src/lc-compliance/simple_capture.h b/src/lc-compliance/simple_capture.h index 2b1493ecaf96..d25c3b20d059 100644 --- a/src/lc-compliance/simple_capture.h +++ b/src/lc-compliance/simple_capture.h @@ -65,4 +65,18 @@ private: unsigned int captureLimit_; }; +class SimpleCaptureOverflow : public SimpleCapture +{ +public: + SimpleCaptureOverflow(std::shared_ptr camera); + + Results::Result capture(unsigned int numRequests); + +private: + void requestComplete(libcamera::Request *request) override; + + unsigned int captureCount_; + unsigned int captureLimit_; +}; + #endif /* __LC_COMPLIANCE_SIMPLE_CAPTURE_H__ */ diff --git a/src/lc-compliance/single_stream.cpp b/src/lc-compliance/single_stream.cpp index 8318b42f42d6..276a588f58e2 100644 --- a/src/lc-compliance/single_stream.cpp +++ b/src/lc-compliance/single_stream.cpp @@ -12,6 +12,20 @@ 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; + + return capture.capture(numRequests); +} + Results::Result testRequestBalance(std::shared_ptr camera, StreamRole role, unsigned int startCycles, unsigned int numRequests) @@ -55,7 +69,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() * 1); for (const auto &role : roles) { std::cout << "= Test role " << role.first << std::endl; @@ -91,6 +105,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 amount + * 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;