summaryrefslogtreecommitdiff
path: root/src/apps/lc-compliance/simple_capture.cpp
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-10-20 00:44:55 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-10-20 13:36:25 +0300
commit84ad104499d9efc0253dae1a60ee070ed375ad95 (patch)
treed10fd53eb79cebb28fa3f72b18b46dddb6382b83 /src/apps/lc-compliance/simple_capture.cpp
parentdaf3f4b59f4ea0ecb42c6a39fe909f071d3a2842 (diff)
Move test applications to src/apps/
The cam and qcam test application share code, currently through a crude hack that references the cam source files directly from the qcam meson.build file. To prepare for the introduction of hosting that code in a static library, move all applications to src/apps/. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Diffstat (limited to 'src/apps/lc-compliance/simple_capture.cpp')
-rw-r--r--src/apps/lc-compliance/simple_capture.cpp191
1 files changed, 191 insertions, 0 deletions
diff --git a/src/apps/lc-compliance/simple_capture.cpp b/src/apps/lc-compliance/simple_capture.cpp
new file mode 100644
index 00000000..ab5cb35c
--- /dev/null
+++ b/src/apps/lc-compliance/simple_capture.cpp
@@ -0,0 +1,191 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020-2021, Google Inc.
+ *
+ * simple_capture.cpp - Simple capture helper
+ */
+
+#include <gtest/gtest.h>
+
+#include "simple_capture.h"
+
+using namespace libcamera;
+
+SimpleCapture::SimpleCapture(std::shared_ptr<Camera> camera)
+ : loop_(nullptr), camera_(camera),
+ allocator_(std::make_unique<FrameBufferAllocator>(camera))
+{
+}
+
+SimpleCapture::~SimpleCapture()
+{
+ stop();
+}
+
+void SimpleCapture::configure(StreamRole role)
+{
+ config_ = camera_->generateConfiguration({ role });
+
+ if (!config_) {
+ std::cout << "Role not supported by camera" << std::endl;
+ GTEST_SKIP();
+ }
+
+ if (config_->validate() != CameraConfiguration::Valid) {
+ config_.reset();
+ FAIL() << "Configuration not valid";
+ }
+
+ if (camera_->configure(config_.get())) {
+ config_.reset();
+ FAIL() << "Failed to configure camera";
+ }
+}
+
+void SimpleCapture::start()
+{
+ Stream *stream = config_->at(0).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";
+
+ camera_->requestCompleted.connect(this, &SimpleCapture::requestComplete);
+
+ ASSERT_EQ(camera_->start(), 0) << "Failed to start camera";
+}
+
+void SimpleCapture::stop()
+{
+ if (!config_ || !allocator_->allocated())
+ return;
+
+ camera_->stop();
+
+ camera_->requestCompleted.disconnect(this);
+
+ Stream *stream = config_->at(0).stream();
+ allocator_->free(stream);
+}
+
+/* SimpleCaptureBalanced */
+
+SimpleCaptureBalanced::SimpleCaptureBalanced(std::shared_ptr<Camera> camera)
+ : SimpleCapture(camera)
+{
+}
+
+void SimpleCaptureBalanced::capture(unsigned int numRequests)
+{
+ start();
+
+ Stream *stream = config_->at(0).stream();
+ const std::vector<std::unique_ptr<FrameBuffer>> &buffers = allocator_->buffers(stream);
+
+ /* 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();
+ }
+
+ queueCount_ = 0;
+ captureCount_ = 0;
+ captureLimit_ = numRequests;
+
+ /* Queue the recommended number of reqeuests. */
+ std::vector<std::unique_ptr<libcamera::Request>> requests;
+ for (const std::unique_ptr<FrameBuffer> &buffer : buffers) {
+ std::unique_ptr<Request> 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 SimpleCaptureBalanced::queueRequest(Request *request)
+{
+ queueCount_++;
+ if (queueCount_ > captureLimit_)
+ return 0;
+
+ return camera_->queueRequest(request);
+}
+
+void SimpleCaptureBalanced::requestComplete(Request *request)
+{
+ captureCount_++;
+ if (captureCount_ >= captureLimit_) {
+ loop_->exit(0);
+ return;
+ }
+
+ request->reuse(Request::ReuseBuffers);
+ if (queueRequest(request))
+ loop_->exit(-EINVAL);
+}
+
+/* SimpleCaptureUnbalanced */
+
+SimpleCaptureUnbalanced::SimpleCaptureUnbalanced(std::shared_ptr<Camera> camera)
+ : SimpleCapture(camera)
+{
+}
+
+void SimpleCaptureUnbalanced::capture(unsigned int numRequests)
+{
+ start();
+
+ Stream *stream = config_->at(0).stream();
+ const std::vector<std::unique_ptr<FrameBuffer>> &buffers = allocator_->buffers(stream);
+
+ captureCount_ = 0;
+ captureLimit_ = numRequests;
+
+ /* Queue the recommended number of reqeuests. */
+ std::vector<std::unique_ptr<libcamera::Request>> requests;
+ for (const std::unique_ptr<FrameBuffer> &buffer : buffers) {
+ std::unique_ptr<Request> 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";
+
+ requests.push_back(std::move(request));
+ }
+
+ /* Run capture session. */
+ loop_ = new EventLoop();
+ int status = loop_->exec();
+ stop();
+ delete loop_;
+
+ ASSERT_EQ(status, 0);
+}
+
+void SimpleCaptureUnbalanced::requestComplete(Request *request)
+{
+ captureCount_++;
+ if (captureCount_ >= captureLimit_) {
+ loop_->exit(0);
+ return;
+ }
+
+ request->reuse(Request::ReuseBuffers);
+ if (camera_->queueRequest(request))
+ loop_->exit(-EINVAL);
+}