diff options
Diffstat (limited to 'src/apps/lc-compliance/helpers/capture.cpp')
-rw-r--r-- | src/apps/lc-compliance/helpers/capture.cpp | 202 |
1 files changed, 91 insertions, 111 deletions
diff --git a/src/apps/lc-compliance/helpers/capture.cpp b/src/apps/lc-compliance/helpers/capture.cpp index 90c1530b..2a3fa3b6 100644 --- a/src/apps/lc-compliance/helpers/capture.cpp +++ b/src/apps/lc-compliance/helpers/capture.cpp @@ -7,13 +7,14 @@ #include "capture.h" +#include <assert.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)) + : camera_(std::move(camera)), allocator_(camera_) { } @@ -22,14 +23,29 @@ Capture::~Capture() stop(); } -void Capture::configure(StreamRole role) +void Capture::configure(libcamera::Span<const libcamera::StreamRole> roles) { - config_ = camera_->generateConfiguration({ role }); + assert(!roles.empty()); - if (!config_) { - std::cout << "Role not supported by camera" << std::endl; - GTEST_SKIP(); - } + config_ = camera_->generateConfiguration(roles); + if (!config_) + GTEST_SKIP() << "Roles not supported by camera"; + + ASSERT_EQ(config_->size(), roles.size()) << "Unexpected number of streams in configuration"; + + /* + * Set the buffers count to the largest value across all streams. + * \todo: Should all streams from a Camera have the same buffer count ? + */ + auto largest = + std::max_element(config_->begin(), config_->end(), + [](const StreamConfiguration &l, const StreamConfiguration &r) + { return l.bufferCount < r.bufferCount; }); + + assert(largest != config_->end()); + + for (auto &cfg : *config_) + cfg.bufferCount = largest->bufferCount; if (config_->validate() != CameraConfiguration::Valid) { config_.reset(); @@ -42,155 +58,119 @@ void Capture::configure(StreamRole role) } } -void Capture::start() +void Capture::run(unsigned int captureLimit, std::optional<unsigned int> queueLimit) { - 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(); + assert(!queueLimit || captureLimit <= *queueLimit); - camera_->requestCompleted.disconnect(this); + captureLimit_ = captureLimit; + queueLimit_ = queueLimit; - Stream *stream = config_->at(0).stream(); - requests_.clear(); - allocator_->free(stream); -} + captureCount_ = queueCount_ = 0; -/* CaptureBalanced */ - -CaptureBalanced::CaptureBalanced(std::shared_ptr<Camera> camera) - : Capture(camera) -{ -} + EventLoop loop; + loop_ = &loop; -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(); - } + for (const auto &request : requests_) + queueRequest(request.get()); - queueCount_ = 0; - captureCount_ = 0; - captureLimit_ = numRequests; + EXPECT_EQ(loop_->exec(), 0); - /* 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_); + EXPECT_LE(captureLimit_, captureCount_); + EXPECT_LE(captureCount_, queueCount_); + EXPECT_TRUE(!queueLimit_ || queueCount_ <= *queueLimit_); } -int CaptureBalanced::queueRequest(Request *request) +int Capture::queueRequest(libcamera::Request *request) { - queueCount_++; - if (queueCount_ > captureLimit_) + if (queueLimit_ && queueCount_ >= *queueLimit_) return 0; - return camera_->queueRequest(request); + int ret = camera_->queueRequest(request); + if (ret < 0) + return ret; + + queueCount_ += 1; + return 0; } -void CaptureBalanced::requestComplete(Request *request) +void Capture::requestComplete(Request *request) { - EXPECT_EQ(request->status(), Request::Status::RequestComplete) - << "Request didn't complete successfully"; - 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 (queueRequest(request)) loop_->exit(-EINVAL); } -/* CaptureUnbalanced */ - -CaptureUnbalanced::CaptureUnbalanced(std::shared_ptr<Camera> camera) - : Capture(camera) -{ -} - -void CaptureUnbalanced::capture(unsigned int numRequests) +void Capture::start() { - start(); + assert(config_); + assert(!config_->empty()); + assert(!allocator_.allocated()); + assert(requests_.empty()); - Stream *stream = config_->at(0).stream(); - const std::vector<std::unique_ptr<FrameBuffer>> &buffers = allocator_->buffers(stream); + const auto bufferCount = config_->at(0).bufferCount; - captureCount_ = 0; - captureLimit_ = numRequests; + /* No point in testing less requests then the camera depth. */ + if (queueLimit_ && *queueLimit_ < bufferCount) { + GTEST_SKIP() << "Camera needs " << bufferCount + << " requests, can't test only " << *queueLimit_; + } - /* Queue the recommended number of requests. */ - for (const std::unique_ptr<FrameBuffer> &buffer : buffers) { + for (std::size_t i = 0; i < bufferCount; i++) { std::unique_ptr<Request> request = camera_->createRequest(); ASSERT_TRUE(request) << "Can't create request"; + requests_.push_back(std::move(request)); + } - ASSERT_EQ(request->addBuffer(stream, buffer.get()), 0) << "Can't set buffer for request"; + for (const auto &cfg : *config_) { + Stream *stream = cfg.stream(); - ASSERT_EQ(camera_->queueRequest(request.get()), 0) << "Failed to queue request"; + int count = allocator_.allocate(stream); + ASSERT_GE(count, 0) << "Failed to allocate buffers"; - requests_.push_back(std::move(request)); + const auto &buffers = allocator_.buffers(stream); + ASSERT_EQ(buffers.size(), bufferCount) << "Mismatching buffer count"; + + for (std::size_t i = 0; i < bufferCount; i++) { + ASSERT_EQ(requests_[i]->addBuffer(stream, buffers[i].get()), 0) + << "Failed to add buffer to request"; + } } - /* Run capture session. */ - loop_ = new EventLoop(); - int status = loop_->exec(); - stop(); - delete loop_; + ASSERT_TRUE(allocator_.allocated()); - ASSERT_EQ(status, 0); + camera_->requestCompleted.connect(this, &Capture::requestComplete); + + ASSERT_EQ(camera_->start(), 0) << "Failed to start camera"; } -void CaptureUnbalanced::requestComplete(Request *request) +void Capture::stop() { - captureCount_++; - if (captureCount_ >= captureLimit_) { - loop_->exit(0); + if (!config_ || !allocator_.allocated()) return; - } - EXPECT_EQ(request->status(), Request::Status::RequestComplete) - << "Request didn't complete successfully"; + camera_->stop(); - request->reuse(Request::ReuseBuffers); - if (camera_->queueRequest(request)) - loop_->exit(-EINVAL); + camera_->requestCompleted.disconnect(this); + + requests_.clear(); + + for (const auto &cfg : *config_) { + EXPECT_EQ(allocator_.free(cfg.stream()), 0) + << "Failed to free buffers associated with stream"; + } + + EXPECT_FALSE(allocator_.allocated()); } |