From ed632bf37ebe94310d15f2ef8d25552fea88bafc Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Fri, 22 Dec 2023 17:22:40 +0100 Subject: apps: lc-compliance: Re-organize source directory Before adding more tests and more helper classes to lc-compliance, reorganize the source tree to split test and helpers in two separate directories. While at it, rename the 'SimpleCapture' class and its derived classes to just 'Capture'. Rename the source files accordingly. Re-sort headers inclusions to please checkstyle.py too. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Stefan Klug Tested-by: Stefan Klug --- src/apps/lc-compliance/helpers/capture.cpp | 196 +++++++++++++++++++++++++++++ src/apps/lc-compliance/helpers/capture.h | 66 ++++++++++ 2 files changed, 262 insertions(+) create mode 100644 src/apps/lc-compliance/helpers/capture.cpp create mode 100644 src/apps/lc-compliance/helpers/capture.h (limited to 'src/apps/lc-compliance/helpers') 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 + +using namespace libcamera; + +Capture::Capture(std::shared_ptr camera) + : loop_(nullptr), camera_(camera), + allocator_(std::make_unique(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) + : Capture(camera) +{ +} + +void CaptureBalanced::capture(unsigned int numRequests) +{ + start(); + + Stream *stream = config_->at(0).stream(); + const std::vector> &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 &buffer : buffers) { + std::unique_ptr 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) + : Capture(camera) +{ +} + +void CaptureUnbalanced::capture(unsigned int numRequests) +{ + start(); + + Stream *stream = config_->at(0).stream(); + const std::vector> &buffers = allocator_->buffers(stream); + + captureCount_ = 0; + captureLimit_ = numRequests; + + /* Queue the recommended number of requests. */ + for (const std::unique_ptr &buffer : buffers) { + std::unique_ptr 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 + +#include + +#include "../common/event_loop.h" + +class Capture +{ +public: + void configure(libcamera::StreamRole role); + +protected: + Capture(std::shared_ptr camera); + virtual ~Capture(); + + void start(); + void stop(); + + virtual void requestComplete(libcamera::Request *request) = 0; + + EventLoop *loop_; + + std::shared_ptr camera_; + std::unique_ptr allocator_; + std::unique_ptr config_; + std::vector> requests_; +}; + +class CaptureBalanced : public Capture +{ +public: + CaptureBalanced(std::shared_ptr 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 camera); + + void capture(unsigned int numRequests); + +private: + void requestComplete(libcamera::Request *request) override; + + unsigned int captureCount_; + unsigned int captureLimit_; +}; -- cgit v1.2.1