summaryrefslogtreecommitdiff
path: root/src/apps/lc-compliance/helpers
diff options
context:
space:
mode:
Diffstat (limited to 'src/apps/lc-compliance/helpers')
-rw-r--r--src/apps/lc-compliance/helpers/capture.cpp196
-rw-r--r--src/apps/lc-compliance/helpers/capture.h66
2 files changed, 262 insertions, 0 deletions
diff --git a/src/apps/lc-compliance/helpers/capture.cpp b/src/apps/lc-compliance/helpers/capture.cpp
new file mode 100644
index 00000000..5aab973f
--- /dev/null
+++ b/src/apps/lc-compliance/helpers/capture.cpp
@@ -0,0 +1,196 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020-2021, Google Inc.
+ *
+ * simple_capture.cpp - Simple capture helper
+ */
+
+#include "capture.h"
+
+#include <gtest/gtest.h>
+
+using namespace libcamera;
+
+Capture::Capture(std::shared_ptr<Camera> camera)
+ : loop_(nullptr), camera_(camera),
+ allocator_(std::make_unique<FrameBufferAllocator>(camera))
+{
+}
+
+Capture::~Capture()
+{
+ stop();
+}
+
+void Capture::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 Capture::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, &Capture::requestComplete);
+
+ ASSERT_EQ(camera_->start(), 0) << "Failed to start camera";
+}
+
+void Capture::stop()
+{
+ if (!config_ || !allocator_->allocated())
+ return;
+
+ camera_->stop();
+
+ camera_->requestCompleted.disconnect(this);
+
+ Stream *stream = config_->at(0).stream();
+ requests_.clear();
+ allocator_->free(stream);
+}
+
+/* CaptureBalanced */
+
+CaptureBalanced::CaptureBalanced(std::shared_ptr<Camera> camera)
+ : Capture(camera)
+{
+}
+
+void CaptureBalanced::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 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 CaptureBalanced::queueRequest(Request *request)
+{
+ queueCount_++;
+ if (queueCount_ > captureLimit_)
+ return 0;
+
+ return camera_->queueRequest(request);
+}
+
+void CaptureBalanced::requestComplete(Request *request)
+{
+ EXPECT_EQ(request->status(), Request::Status::RequestComplete)
+ << "Request didn't complete successfully";
+
+ captureCount_++;
+ if (captureCount_ >= captureLimit_) {
+ loop_->exit(0);
+ return;
+ }
+
+ request->reuse(Request::ReuseBuffers);
+ if (queueRequest(request))
+ loop_->exit(-EINVAL);
+}
+
+/* CaptureUnbalanced */
+
+CaptureUnbalanced::CaptureUnbalanced(std::shared_ptr<Camera> camera)
+ : Capture(camera)
+{
+}
+
+void CaptureUnbalanced::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 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 CaptureUnbalanced::requestComplete(Request *request)
+{
+ 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 (camera_->queueRequest(request))
+ loop_->exit(-EINVAL);
+}
diff --git a/src/apps/lc-compliance/helpers/capture.h b/src/apps/lc-compliance/helpers/capture.h
new file mode 100644
index 00000000..0574ab1c
--- /dev/null
+++ b/src/apps/lc-compliance/helpers/capture.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020-2021, Google Inc.
+ *
+ * simple_capture.h - Simple capture helper
+ */
+
+#pragma once
+
+#include <memory>
+
+#include <libcamera/libcamera.h>
+
+#include "../common/event_loop.h"
+
+class Capture
+{
+public:
+ void configure(libcamera::StreamRole role);
+
+protected:
+ Capture(std::shared_ptr<libcamera::Camera> camera);
+ virtual ~Capture();
+
+ void start();
+ void stop();
+
+ virtual void requestComplete(libcamera::Request *request) = 0;
+
+ EventLoop *loop_;
+
+ std::shared_ptr<libcamera::Camera> camera_;
+ std::unique_ptr<libcamera::FrameBufferAllocator> allocator_;
+ std::unique_ptr<libcamera::CameraConfiguration> config_;
+ std::vector<std::unique_ptr<libcamera::Request>> requests_;
+};
+
+class CaptureBalanced : public Capture
+{
+public:
+ CaptureBalanced(std::shared_ptr<libcamera::Camera> 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<libcamera::Camera> camera);
+
+ void capture(unsigned int numRequests);
+
+private:
+ void requestComplete(libcamera::Request *request) override;
+
+ unsigned int captureCount_;
+ unsigned int captureLimit_;
+};