/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2020, Google Inc. * * simple_capture.cpp - Simple capture helper */ #include "simple_capture.h" using namespace libcamera; SimpleCapture::SimpleCapture(std::shared_ptr camera) : loop_(nullptr), camera_(camera), allocator_(std::make_unique(camera)) { } SimpleCapture::~SimpleCapture() { } Results::Result SimpleCapture::configure(StreamRole role) { config_ = camera_->generateConfiguration({ role }); if (!config_) return { Results::Skip, "Role not supported by camera" }; if (config_->validate() != CameraConfiguration::Valid) { config_.reset(); return { Results::Fail, "Configuration not valid" }; } if (camera_->configure(config_.get())) { config_.reset(); return { Results::Fail, "Failed to configure camera" }; } return { Results::Pass, "Configure camera" }; } Results::Result SimpleCapture::start() { Stream *stream = config_->at(0).stream(); if (allocator_->allocate(stream) < 0) return { Results::Fail, "Failed to allocate buffers" }; if (camera_->start()) return { Results::Fail, "Failed to start camera" }; camera_->requestCompleted.connect(this, &SimpleCapture::requestComplete); return { Results::Pass, "Started camera" }; } void SimpleCapture::stop() { Stream *stream = config_->at(0).stream(); camera_->stop(); camera_->requestCompleted.disconnect(this, &SimpleCapture::requestComplete); allocator_->free(stream); } /* SimpleCaptureBalanced */ SimpleCaptureBalanced::SimpleCaptureBalanced(std::shared_ptr camera) : SimpleCapture(camera) { } Results::Result SimpleCaptureBalanced::capture(unsigned int numRequests) { Results::Result ret = start(); if (ret.first != Results::Pass) return ret; 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) { /* Cache buffers.size() before we destroy it in stop() */ int buffers_size = buffers.size(); stop(); return { Results::Skip, "Camera needs " + std::to_string(buffers_size) + " requests, can't test only " + std::to_string(numRequests) }; } queueCount_ = 0; captureCount_ = 0; captureLimit_ = numRequests; /* Queue the recommended number of reqeuests. */ 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 (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, "Balanced capture of " + std::to_string(numRequests) + " requests" }; } 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) : SimpleCapture(camera) { } Results::Result SimpleCaptureUnbalanced::capture(unsigned int numRequests) { Results::Result ret = start(); if (ret.first != Results::Pass) return ret; Stream *stream = config_->at(0).stream(); const std::vector> &buffers = allocator_->buffers(stream); captureCount_ = 0; captureLimit_ = numRequests; /* Queue the recommended number of reqeuests. */ 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(); int status = loop_->exec(); stop(); delete loop_; return { status ? Results::Fail : Results::Pass, "Unbalanced capture of " + std::to_string(numRequests) + " requests" }; } void SimpleCaptureUnbalanced::requestComplete(Request *request) { captureCount_++; if (captureCount_ >= captureLimit_) { loop_->exit(0); return; } request->reuse(Request::ReuseBuffers); if (camera_->queueRequest(request)) loop_->exit(-EINVAL); } class='content'>blob: 4b21b32b6fb7da03e2d8bf41c1be12349a68dd29 (plain)
1
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-message-circle"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"></path></svg>