summaryrefslogtreecommitdiff
path: root/src/apps
diff options
context:
space:
mode:
Diffstat (limited to 'src/apps')
-rw-r--r--src/apps/cam/camera_session.cpp10
-rw-r--r--src/apps/common/event_loop.cpp64
-rw-r--r--src/apps/common/event_loop.h23
-rw-r--r--src/apps/common/options.cpp2
-rw-r--r--src/apps/common/ppm_writer.cpp7
-rw-r--r--src/apps/lc-compliance/environment.h2
-rw-r--r--src/apps/lc-compliance/helpers/capture.cpp162
-rw-r--r--src/apps/lc-compliance/helpers/capture.h51
-rw-r--r--src/apps/lc-compliance/main.cpp42
-rw-r--r--src/apps/lc-compliance/tests/capture_test.cpp21
-rw-r--r--src/apps/qcam/format_converter.cpp2
-rw-r--r--src/apps/qcam/main_window.cpp43
-rw-r--r--src/apps/qcam/main_window.h2
13 files changed, 174 insertions, 257 deletions
diff --git a/src/apps/cam/camera_session.cpp b/src/apps/cam/camera_session.cpp
index 6e9890cc..9e934827 100644
--- a/src/apps/cam/camera_session.cpp
+++ b/src/apps/cam/camera_session.cpp
@@ -159,12 +159,18 @@ CameraSession::~CameraSession()
void CameraSession::listControls() const
{
for (const auto &[id, info] : camera_->controls()) {
+ std::stringstream io;
+ io << "["
+ << (id->isInput() ? "in" : " ")
+ << (id->isOutput() ? "out" : " ")
+ << "] ";
+
if (info.values().empty()) {
- std::cout << "Control: "
+ std::cout << "Control: " << io.str()
<< id->vendor() << "::" << id->name() << ": "
<< info.toString() << std::endl;
} else {
- std::cout << "Control: "
+ std::cout << "Control: " << io.str()
<< id->vendor() << "::" << id->name() << ":"
<< std::endl;
for (const auto &value : info.values()) {
diff --git a/src/apps/common/event_loop.cpp b/src/apps/common/event_loop.cpp
index f7f9afa0..b6230f4b 100644
--- a/src/apps/common/event_loop.cpp
+++ b/src/apps/common/event_loop.cpp
@@ -21,12 +21,35 @@ EventLoop::EventLoop()
evthread_use_pthreads();
base_ = event_base_new();
instance_ = this;
+
+ callsTrigger_ = event_new(base_, -1, EV_PERSIST, [](evutil_socket_t, short, void *closure) {
+ auto *self = static_cast<EventLoop *>(closure);
+
+ for (;;) {
+ std::function<void()> call;
+
+ {
+ std::lock_guard locker(self->lock_);
+ if (self->calls_.empty())
+ break;
+
+ call = std::move(self->calls_.front());
+ self->calls_.pop_front();
+ }
+
+ call();
+ }
+ }, this);
+ assert(callsTrigger_);
+ event_add(callsTrigger_, nullptr);
}
EventLoop::~EventLoop()
{
instance_ = nullptr;
+ event_free(callsTrigger_);
+
events_.clear();
event_base_free(base_);
libevent_global_shutdown();
@@ -50,20 +73,20 @@ void EventLoop::exit(int code)
event_base_loopbreak(base_);
}
-void EventLoop::callLater(const std::function<void()> &func)
+void EventLoop::callLater(std::function<void()> &&func)
{
{
std::unique_lock<std::mutex> locker(lock_);
- calls_.push_back(func);
+ calls_.push_back(std::move(func));
}
- event_base_once(base_, -1, EV_TIMEOUT, dispatchCallback, this, nullptr);
+ event_active(callsTrigger_, 0, 0);
}
void EventLoop::addFdEvent(int fd, EventType type,
- const std::function<void()> &callback)
+ std::function<void()> &&callback)
{
- std::unique_ptr<Event> event = std::make_unique<Event>(callback);
+ std::unique_ptr<Event> event = std::make_unique<Event>(std::move(callback));
short events = (type & Read ? EV_READ : 0)
| (type & Write ? EV_WRITE : 0)
| EV_PERSIST;
@@ -85,9 +108,9 @@ void EventLoop::addFdEvent(int fd, EventType type,
}
void EventLoop::addTimerEvent(const std::chrono::microseconds period,
- const std::function<void()> &callback)
+ std::function<void()> &&callback)
{
- std::unique_ptr<Event> event = std::make_unique<Event>(callback);
+ std::unique_ptr<Event> event = std::make_unique<Event>(std::move(callback));
event->event_ = event_new(base_, -1, EV_PERSIST, &EventLoop::Event::dispatch,
event.get());
if (!event->event_) {
@@ -108,31 +131,8 @@ void EventLoop::addTimerEvent(const std::chrono::microseconds period,
events_.push_back(std::move(event));
}
-void EventLoop::dispatchCallback([[maybe_unused]] evutil_socket_t fd,
- [[maybe_unused]] short flags, void *param)
-{
- EventLoop *loop = static_cast<EventLoop *>(param);
- loop->dispatchCall();
-}
-
-void EventLoop::dispatchCall()
-{
- std::function<void()> call;
-
- {
- std::unique_lock<std::mutex> locker(lock_);
- if (calls_.empty())
- return;
-
- call = calls_.front();
- calls_.pop_front();
- }
-
- call();
-}
-
-EventLoop::Event::Event(const std::function<void()> &callback)
- : callback_(callback), event_(nullptr)
+EventLoop::Event::Event(std::function<void()> &&callback)
+ : callback_(std::move(callback)), event_(nullptr)
{
}
diff --git a/src/apps/common/event_loop.h b/src/apps/common/event_loop.h
index ef129b9a..d8b6df2f 100644
--- a/src/apps/common/event_loop.h
+++ b/src/apps/common/event_loop.h
@@ -8,11 +8,14 @@
#pragma once
#include <chrono>
+#include <deque>
#include <functional>
#include <list>
#include <memory>
#include <mutex>
+#include <libcamera/base/class.h>
+
#include <event2/util.h>
struct event_base;
@@ -33,18 +36,20 @@ public:
int exec();
void exit(int code = 0);
- void callLater(const std::function<void()> &func);
+ void callLater(std::function<void()> &&func);
void addFdEvent(int fd, EventType type,
- const std::function<void()> &handler);
+ std::function<void()> &&handler);
- using duration = std::chrono::steady_clock::duration;
void addTimerEvent(const std::chrono::microseconds period,
- const std::function<void()> &handler);
+ std::function<void()> &&handler);
private:
+ LIBCAMERA_DISABLE_COPY_AND_MOVE(EventLoop)
+
struct Event {
- Event(const std::function<void()> &callback);
+ Event(std::function<void()> &&callback);
+ LIBCAMERA_DISABLE_COPY_AND_MOVE(Event)
~Event();
static void dispatch(int fd, short events, void *arg);
@@ -58,11 +63,9 @@ private:
struct event_base *base_;
int exitCode_;
- std::list<std::function<void()>> calls_;
+ std::deque<std::function<void()>> calls_;
+ struct event *callsTrigger_ = nullptr;
+
std::list<std::unique_ptr<Event>> events_;
std::mutex lock_;
-
- static void dispatchCallback(evutil_socket_t fd, short flags,
- void *param);
- void dispatchCall();
};
diff --git a/src/apps/common/options.cpp b/src/apps/common/options.cpp
index ece268d0..cae193cc 100644
--- a/src/apps/common/options.cpp
+++ b/src/apps/common/options.cpp
@@ -1040,7 +1040,7 @@ void OptionsParser::usageOptions(const std::list<Option> &options,
std::cerr << std::setw(indent) << argument;
- for (const char *help = option.help, *end = help; end; ) {
+ for (const char *help = option.help, *end = help; end;) {
end = strchr(help, '\n');
if (end) {
std::cerr << std::string(help, end - help + 1);
diff --git a/src/apps/common/ppm_writer.cpp b/src/apps/common/ppm_writer.cpp
index d6c8641d..368de8bf 100644
--- a/src/apps/common/ppm_writer.cpp
+++ b/src/apps/common/ppm_writer.cpp
@@ -7,6 +7,7 @@
#include "ppm_writer.h"
+#include <errno.h>
#include <fstream>
#include <iostream>
@@ -28,7 +29,7 @@ int PPMWriter::write(const char *filename,
std::ofstream output(filename, std::ios::binary);
if (!output) {
std::cerr << "Failed to open ppm file: " << filename << std::endl;
- return -EINVAL;
+ return -EIO;
}
output << "P6" << std::endl
@@ -36,7 +37,7 @@ int PPMWriter::write(const char *filename,
<< "255" << std::endl;
if (!output) {
std::cerr << "Failed to write the file header" << std::endl;
- return -EINVAL;
+ return -EIO;
}
const unsigned int rowLength = config.size.width * 3;
@@ -45,7 +46,7 @@ int PPMWriter::write(const char *filename,
output.write(row, rowLength);
if (!output) {
std::cerr << "Failed to write image data at row " << y << std::endl;
- return -EINVAL;
+ return -EIO;
}
}
diff --git a/src/apps/lc-compliance/environment.h b/src/apps/lc-compliance/environment.h
index 543e5372..834c722e 100644
--- a/src/apps/lc-compliance/environment.h
+++ b/src/apps/lc-compliance/environment.h
@@ -23,5 +23,5 @@ private:
Environment() = default;
std::string cameraId_;
- libcamera::CameraManager *cm_;
+ libcamera::CameraManager *cm_ = nullptr;
};
diff --git a/src/apps/lc-compliance/helpers/capture.cpp b/src/apps/lc-compliance/helpers/capture.cpp
index 90c1530b..f2c6d58c 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_)
{
}
@@ -26,10 +27,8 @@ void Capture::configure(StreamRole role)
{
config_ = camera_->generateConfiguration({ role });
- if (!config_) {
- std::cout << "Role not supported by camera" << std::endl;
- GTEST_SKIP();
- }
+ if (!config_)
+ GTEST_SKIP() << "Role not supported by camera";
if (config_->validate() != CameraConfiguration::Valid) {
config_.reset();
@@ -42,155 +41,106 @@ 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";
-}
+ assert(!queueLimit || captureLimit <= *queueLimit);
-void Capture::stop()
-{
- if (!config_ || !allocator_->allocated())
- return;
+ captureLimit_ = captureLimit;
+ queueLimit_ = queueLimit;
- camera_->stop();
+ captureCount_ = queueCount_ = 0;
- camera_->requestCompleted.disconnect(this);
+ EventLoop loop;
+ loop_ = &loop;
- 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();
- }
+ 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);
+ int count = allocator_.allocate(stream);
- captureCount_ = 0;
- captureLimit_ = numRequests;
+ ASSERT_GE(count, 0) << "Failed to allocate buffers";
+ EXPECT_EQ(count, config_->at(0).bufferCount) << "Allocated less buffers than expected";
+
+ const std::vector<std::unique_ptr<FrameBuffer>> &buffers = allocator_.buffers(stream);
+
+ /* No point in testing less requests then the camera depth. */
+ if (queueLimit_ && *queueLimit_ < buffers.size()) {
+ GTEST_SKIP() << "Camera needs " << buffers.size()
+ << " requests, can't test only " << *queueLimit_;
+ }
- /* 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_;
+ camera_->requestCompleted.connect(this, &Capture::requestComplete);
- ASSERT_EQ(status, 0);
+ 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);
+
+ Stream *stream = config_->at(0).stream();
+ requests_.clear();
+ allocator_.free(stream);
}
diff --git a/src/apps/lc-compliance/helpers/capture.h b/src/apps/lc-compliance/helpers/capture.h
index 19b6927c..0e7b848f 100644
--- a/src/apps/lc-compliance/helpers/capture.h
+++ b/src/apps/lc-compliance/helpers/capture.h
@@ -8,6 +8,7 @@
#pragma once
#include <memory>
+#include <optional>
#include <libcamera/libcamera.h>
@@ -16,51 +17,29 @@
class Capture
{
public:
+ Capture(std::shared_ptr<libcamera::Camera> camera);
+ ~Capture();
+
void configure(libcamera::StreamRole role);
+ void run(unsigned int captureLimit, std::optional<unsigned int> queueLimit = {});
-protected:
- Capture(std::shared_ptr<libcamera::Camera> camera);
- virtual ~Capture();
+private:
+ LIBCAMERA_DISABLE_COPY_AND_MOVE(Capture)
void start();
void stop();
- virtual void requestComplete(libcamera::Request *request) = 0;
-
- EventLoop *loop_;
+ int queueRequest(libcamera::Request *request);
+ void requestComplete(libcamera::Request *request);
std::shared_ptr<libcamera::Camera> camera_;
- std::unique_ptr<libcamera::FrameBufferAllocator> allocator_;
+ 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_;
+ EventLoop *loop_ = nullptr;
+ unsigned int captureLimit_ = 0;
+ std::optional<unsigned int> queueLimit_;
+ unsigned int captureCount_ = 0;
+ unsigned int queueCount_ = 0;
};
diff --git a/src/apps/lc-compliance/main.cpp b/src/apps/lc-compliance/main.cpp
index 3f1d2a61..e9f0ffbb 100644
--- a/src/apps/lc-compliance/main.cpp
+++ b/src/apps/lc-compliance/main.cpp
@@ -45,13 +45,11 @@ class ThrowListener : public testing::EmptyTestEventListener
static void listCameras(CameraManager *cm)
{
for (const std::shared_ptr<Camera> &cam : cm->cameras())
- std::cout << "- " << cam.get()->id() << std::endl;
+ std::cout << "- " << cam->id() << std::endl;
}
static int initCamera(CameraManager *cm, OptionsParser::Options options)
{
- std::shared_ptr<Camera> camera;
-
int ret = cm->start();
if (ret) {
std::cout << "Failed to start camera manager: "
@@ -66,7 +64,7 @@ static int initCamera(CameraManager *cm, OptionsParser::Options options)
}
const std::string &cameraId = options[OptCamera];
- camera = cm->get(cameraId);
+ std::shared_ptr<Camera> camera = cm->get(cameraId);
if (!camera) {
std::cout << "Camera " << cameraId << " not found, available cameras:" << std::endl;
listCameras(cm);
@@ -82,45 +80,27 @@ static int initCamera(CameraManager *cm, OptionsParser::Options options)
static int initGtestParameters(char *arg0, OptionsParser::Options options)
{
- const std::map<std::string, std::string> gtestFlags = { { "list", "--gtest_list_tests" },
- { "filter", "--gtest_filter" } };
-
- int argc = 0;
+ std::vector<const char *> argv;
std::string filterParam;
- /*
- * +2 to have space for both the 0th argument that is needed but not
- * used and the null at the end.
- */
- char **argv = new char *[(gtestFlags.size() + 2)];
- if (!argv)
- return -ENOMEM;
-
- argv[0] = arg0;
- argc++;
+ argv.push_back(arg0);
- if (options.isSet(OptList)) {
- argv[argc] = const_cast<char *>(gtestFlags.at("list").c_str());
- argc++;
- }
+ if (options.isSet(OptList))
+ argv.push_back("--gtest_list_tests");
if (options.isSet(OptFilter)) {
/*
* The filter flag needs to be passed as a single parameter, in
* the format --gtest_filter=filterStr
*/
- filterParam = gtestFlags.at("filter") + "=" +
- static_cast<const std::string &>(options[OptFilter]);
-
- argv[argc] = const_cast<char *>(filterParam.c_str());
- argc++;
+ filterParam = "--gtest_filter=" + options[OptFilter].toString();
+ argv.push_back(filterParam.c_str());
}
- argv[argc] = nullptr;
-
- ::testing::InitGoogleTest(&argc, argv);
+ argv.push_back(nullptr);
- delete[] argv;
+ int argc = argv.size();
+ ::testing::InitGoogleTest(&argc, const_cast<char **>(argv.data()));
return 0;
}
diff --git a/src/apps/lc-compliance/tests/capture_test.cpp b/src/apps/lc-compliance/tests/capture_test.cpp
index ad3a1da2..93bed48f 100644
--- a/src/apps/lc-compliance/tests/capture_test.cpp
+++ b/src/apps/lc-compliance/tests/capture_test.cpp
@@ -14,10 +14,13 @@
#include "environment.h"
+namespace {
+
using namespace libcamera;
-const std::vector<int> NUMREQUESTS = { 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 };
-const std::vector<StreamRole> ROLES = {
+const int NUMREQUESTS[] = { 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 };
+
+const StreamRole ROLES[] = {
StreamRole::Raw,
StreamRole::StillCapture,
StreamRole::VideoRecording,
@@ -84,11 +87,11 @@ TEST_P(SingleStream, Capture)
{
auto [role, numRequests] = GetParam();
- CaptureBalanced capture(camera_);
+ Capture capture(camera_);
capture.configure(role);
- capture.capture(numRequests);
+ capture.run(numRequests, numRequests);
}
/*
@@ -103,12 +106,12 @@ TEST_P(SingleStream, CaptureStartStop)
auto [role, numRequests] = GetParam();
unsigned int numRepeats = 3;
- CaptureBalanced capture(camera_);
+ Capture capture(camera_);
capture.configure(role);
for (unsigned int starts = 0; starts < numRepeats; starts++)
- capture.capture(numRequests);
+ capture.run(numRequests, numRequests);
}
/*
@@ -122,11 +125,11 @@ TEST_P(SingleStream, UnbalancedStop)
{
auto [role, numRequests] = GetParam();
- CaptureUnbalanced capture(camera_);
+ Capture capture(camera_);
capture.configure(role);
- capture.capture(numRequests);
+ capture.run(numRequests);
}
INSTANTIATE_TEST_SUITE_P(CaptureTests,
@@ -134,3 +137,5 @@ INSTANTIATE_TEST_SUITE_P(CaptureTests,
testing::Combine(testing::ValuesIn(ROLES),
testing::ValuesIn(NUMREQUESTS)),
SingleStream::nameParameters);
+
+} /* namespace */
diff --git a/src/apps/qcam/format_converter.cpp b/src/apps/qcam/format_converter.cpp
index 32123493..b025a3c7 100644
--- a/src/apps/qcam/format_converter.cpp
+++ b/src/apps/qcam/format_converter.cpp
@@ -249,7 +249,7 @@ void FormatConverter::convertYUVPacked(const Image *srcImage, unsigned char *dst
dst_stride = width_ * 4;
for (src_y = 0, dst_y = 0; dst_y < height_; src_y++, dst_y++) {
- for (src_x = 0, dst_x = 0; dst_x < width_; ) {
+ for (src_x = 0, dst_x = 0; dst_x < width_;) {
cb = src[src_y * src_stride + src_x * 4 + cb_pos_];
cr = src[src_y * src_stride + src_x * 4 + cr_pos];
diff --git a/src/apps/qcam/main_window.cpp b/src/apps/qcam/main_window.cpp
index de487672..3880a846 100644
--- a/src/apps/qcam/main_window.cpp
+++ b/src/apps/qcam/main_window.cpp
@@ -251,16 +251,14 @@ void MainWindow::updateTitle()
void MainWindow::switchCamera()
{
/* Get and acquire the new camera. */
- std::string newCameraId = chooseCamera();
+ std::shared_ptr<Camera> cam = chooseCamera();
- if (newCameraId.empty())
+ if (!cam)
return;
- if (camera_ && newCameraId == camera_->id())
+ if (camera_ && cam == camera_)
return;
- const std::shared_ptr<Camera> &cam = cm_->get(newCameraId);
-
if (cam->acquire()) {
qInfo() << "Failed to acquire camera" << cam->id().c_str();
return;
@@ -282,46 +280,41 @@ void MainWindow::switchCamera()
startStopAction_->setChecked(true);
/* Display the current cameraId in the toolbar .*/
- cameraSelectButton_->setText(QString::fromStdString(newCameraId));
+ cameraSelectButton_->setText(QString::fromStdString(cam->id()));
}
-std::string MainWindow::chooseCamera()
+std::shared_ptr<Camera> MainWindow::chooseCamera()
{
if (cameraSelectorDialog_->exec() != QDialog::Accepted)
- return std::string();
+ return {};
- return cameraSelectorDialog_->getCameraId();
+ std::string id = cameraSelectorDialog_->getCameraId();
+ return cm_->get(id);
}
int MainWindow::openCamera()
{
- std::string cameraName;
-
/*
* If a camera is specified on the command line, get it. Otherwise, if
* only one camera is available, pick it automatically, else, display
* the selector dialog box.
*/
if (options_.isSet(OptCamera)) {
- cameraName = static_cast<std::string>(options_[OptCamera]);
+ std::string cameraName = static_cast<std::string>(options_[OptCamera]);
+ camera_ = cm_->get(cameraName);
+ if (!camera_)
+ qInfo() << "Camera" << cameraName.c_str() << "not found";
} else {
std::vector<std::shared_ptr<Camera>> cameras = cm_->cameras();
- if (cameras.size() == 1)
- cameraName = cameras[0]->id();
- else
- cameraName = chooseCamera();
+ camera_ = (cameras.size() == 1) ? cameras[0] : chooseCamera();
+ if (!camera_)
+ qInfo() << "No camera detected";
}
- if (cameraName == "")
- return -EINVAL;
-
- /* Get and acquire the camera. */
- camera_ = cm_->get(cameraName);
- if (!camera_) {
- qInfo() << "Camera" << cameraName.c_str() << "not found";
+ if (!camera_)
return -ENODEV;
- }
+ /* Acquire the camera. */
if (camera_->acquire()) {
qInfo() << "Failed to acquire camera";
camera_.reset();
@@ -329,7 +322,7 @@ int MainWindow::openCamera()
}
/* Set the camera switch button with the currently selected Camera id. */
- cameraSelectButton_->setText(QString::fromStdString(cameraName));
+ cameraSelectButton_->setText(QString::fromStdString(camera_->id()));
return 0;
}
diff --git a/src/apps/qcam/main_window.h b/src/apps/qcam/main_window.h
index 4cead734..81fcf915 100644
--- a/src/apps/qcam/main_window.h
+++ b/src/apps/qcam/main_window.h
@@ -73,7 +73,7 @@ private Q_SLOTS:
private:
int createToolbars();
- std::string chooseCamera();
+ std::shared_ptr<libcamera::Camera> chooseCamera();
int openCamera();
int startCapture();