summaryrefslogtreecommitdiff
path: root/src/cam
diff options
context:
space:
mode:
Diffstat (limited to 'src/cam')
-rw-r--r--src/cam/buffer_writer.cpp88
-rw-r--r--src/cam/buffer_writer.h31
-rw-r--r--src/cam/capture.cpp204
-rw-r--r--src/cam/capture.h44
-rw-r--r--src/cam/event_loop.cpp39
-rw-r--r--src/cam/event_loop.h34
-rw-r--r--src/cam/main.cpp385
-rw-r--r--src/cam/main.h21
-rw-r--r--src/cam/meson.build11
-rw-r--r--src/cam/options.cpp537
-rw-r--r--src/cam/options.h147
11 files changed, 0 insertions, 1541 deletions
diff --git a/src/cam/buffer_writer.cpp b/src/cam/buffer_writer.cpp
deleted file mode 100644
index c5a5eb46..00000000
--- a/src/cam/buffer_writer.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2019, Google Inc.
- *
- * buffer_writer.cpp - Buffer writer
- */
-
-#include <fcntl.h>
-#include <iomanip>
-#include <iostream>
-#include <sstream>
-#include <string.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-#include "buffer_writer.h"
-
-using namespace libcamera;
-
-BufferWriter::BufferWriter(const std::string &pattern)
- : pattern_(pattern)
-{
-}
-
-BufferWriter::~BufferWriter()
-{
- for (auto &iter : mappedBuffers_) {
- void *memory = iter.second.first;
- unsigned int length = iter.second.second;
- munmap(memory, length);
- }
- mappedBuffers_.clear();
-}
-
-void BufferWriter::mapBuffer(FrameBuffer *buffer)
-{
- for (const FrameBuffer::Plane &plane : buffer->planes()) {
- void *memory = mmap(NULL, plane.length, PROT_READ, MAP_SHARED,
- plane.fd.fd(), 0);
-
- mappedBuffers_[plane.fd.fd()] =
- std::make_pair(memory, plane.length);
- }
-}
-
-int BufferWriter::write(FrameBuffer *buffer, const std::string &streamName)
-{
- std::string filename;
- size_t pos;
- int fd, ret = 0;
-
- filename = pattern_;
- pos = filename.find_first_of('#');
- if (pos != std::string::npos) {
- std::stringstream ss;
- ss << streamName << "-" << std::setw(6)
- << std::setfill('0') << buffer->metadata().sequence;
- filename.replace(pos, 1, ss.str());
- }
-
- fd = open(filename.c_str(), O_CREAT | O_WRONLY |
- (pos == std::string::npos ? O_APPEND : O_TRUNC),
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
- if (fd == -1)
- return -errno;
-
- for (const FrameBuffer::Plane &plane : buffer->planes()) {
- void *data = mappedBuffers_[plane.fd.fd()].first;
- unsigned int length = plane.length;
-
- ret = ::write(fd, data, length);
- if (ret < 0) {
- ret = -errno;
- std::cerr << "write error: " << strerror(-ret)
- << std::endl;
- break;
- } else if (ret != (int)length) {
- std::cerr << "write error: only " << ret
- << " bytes written instead of "
- << length << std::endl;
- break;
- }
- }
-
- close(fd);
-
- return ret;
-}
diff --git a/src/cam/buffer_writer.h b/src/cam/buffer_writer.h
deleted file mode 100644
index 8c9b2436..00000000
--- a/src/cam/buffer_writer.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2019, Google Inc.
- *
- * buffer_writer.h - Buffer writer
- */
-#ifndef __LIBCAMERA_BUFFER_WRITER_H__
-#define __LIBCAMERA_BUFFER_WRITER_H__
-
-#include <map>
-#include <string>
-
-#include <libcamera/buffer.h>
-
-class BufferWriter
-{
-public:
- BufferWriter(const std::string &pattern = "frame-#.bin");
- ~BufferWriter();
-
- void mapBuffer(libcamera::FrameBuffer *buffer);
-
- int write(libcamera::FrameBuffer *buffer,
- const std::string &streamName);
-
-private:
- std::string pattern_;
- std::map<int, std::pair<void *, unsigned int>> mappedBuffers_;
-};
-
-#endif /* __LIBCAMERA_BUFFER_WRITER_H__ */
diff --git a/src/cam/capture.cpp b/src/cam/capture.cpp
deleted file mode 100644
index 55fa2dab..00000000
--- a/src/cam/capture.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2019, Google Inc.
- *
- * capture.cpp - Cam capture
- */
-
-#include <chrono>
-#include <iomanip>
-#include <iostream>
-#include <limits.h>
-#include <sstream>
-
-#include "capture.h"
-#include "main.h"
-
-using namespace libcamera;
-
-Capture::Capture(std::shared_ptr<Camera> camera, CameraConfiguration *config)
- : camera_(camera), config_(config), writer_(nullptr)
-{
-}
-
-int Capture::run(EventLoop *loop, const OptionsParser::Options &options)
-{
- int ret;
-
- if (!camera_) {
- std::cout << "Can't capture without a camera" << std::endl;
- return -ENODEV;
- }
-
- ret = camera_->configure(config_);
- if (ret < 0) {
- std::cout << "Failed to configure camera" << std::endl;
- return ret;
- }
-
- streamName_.clear();
- for (unsigned int index = 0; index < config_->size(); ++index) {
- StreamConfiguration &cfg = config_->at(index);
- streamName_[cfg.stream()] = "stream" + std::to_string(index);
- }
-
- camera_->requestCompleted.connect(this, &Capture::requestComplete);
-
- if (options.isSet(OptFile)) {
- if (!options[OptFile].toString().empty())
- writer_ = new BufferWriter(options[OptFile]);
- else
- writer_ = new BufferWriter();
- }
-
-
- FrameBufferAllocator *allocator = new FrameBufferAllocator(camera_);
-
- ret = capture(loop, allocator);
-
- if (options.isSet(OptFile)) {
- delete writer_;
- writer_ = nullptr;
- }
-
- delete allocator;
-
- return ret;
-}
-
-int Capture::capture(EventLoop *loop, FrameBufferAllocator *allocator)
-{
- int ret;
-
- /* Identify the stream with the least number of buffers. */
- unsigned int nbuffers = UINT_MAX;
- for (StreamConfiguration &cfg : *config_) {
- ret = allocator->allocate(cfg.stream());
- if (ret < 0) {
- std::cerr << "Can't allocate buffers" << std::endl;
- return -ENOMEM;
- }
-
- unsigned int allocated = allocator->buffers(cfg.stream()).size();
- nbuffers = std::min(nbuffers, allocated);
- }
-
- /*
- * TODO: make cam tool smarter to support still capture by for
- * example pushing a button. For now run all streams all the time.
- */
-
- std::vector<Request *> requests;
- for (unsigned int i = 0; i < nbuffers; i++) {
- Request *request = camera_->createRequest();
- if (!request) {
- std::cerr << "Can't create request" << std::endl;
- return -ENOMEM;
- }
-
- for (StreamConfiguration &cfg : *config_) {
- Stream *stream = cfg.stream();
- const std::vector<std::unique_ptr<FrameBuffer>> &buffers =
- allocator->buffers(stream);
- const std::unique_ptr<FrameBuffer> &buffer = buffers[i];
-
- ret = request->addBuffer(stream, buffer.get());
- if (ret < 0) {
- std::cerr << "Can't set buffer for request"
- << std::endl;
- return ret;
- }
-
- if (writer_)
- writer_->mapBuffer(buffer.get());
- }
-
- requests.push_back(request);
- }
-
- ret = camera_->start();
- if (ret) {
- std::cout << "Failed to start capture" << std::endl;
- return ret;
- }
-
- for (Request *request : requests) {
- ret = camera_->queueRequest(request);
- if (ret < 0) {
- std::cerr << "Can't queue request" << std::endl;
- camera_->stop();
- return ret;
- }
- }
-
- std::cout << "Capture until user interrupts by SIGINT" << std::endl;
- ret = loop->exec();
- if (ret)
- std::cout << "Failed to run capture loop" << std::endl;
-
- ret = camera_->stop();
- if (ret)
- std::cout << "Failed to stop capture" << std::endl;
-
- return ret;
-}
-
-void Capture::requestComplete(Request *request)
-{
- if (request->status() == Request::RequestCancelled)
- return;
-
- const std::map<Stream *, FrameBuffer *> &buffers = request->buffers();
-
- std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
- double fps = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_).count();
- fps = last_ != std::chrono::steady_clock::time_point() && fps
- ? 1000.0 / fps : 0.0;
- last_ = now;
-
- std::stringstream info;
- info << "fps: " << std::fixed << std::setprecision(2) << fps;
-
- for (auto it = buffers.begin(); it != buffers.end(); ++it) {
- Stream *stream = it->first;
- FrameBuffer *buffer = it->second;
- const std::string &name = streamName_[stream];
-
- const FrameMetadata &metadata = buffer->metadata();
-
- info << " " << name
- << " seq: " << std::setw(6) << std::setfill('0') << metadata.sequence
- << " bytesused: ";
-
- unsigned int nplane = 0;
- for (const FrameMetadata::Plane &plane : metadata.planes) {
- info << plane.bytesused;
- if (++nplane < metadata.planes.size())
- info << "/";
- }
-
- if (writer_)
- writer_->write(buffer, name);
- }
-
- std::cout << info.str() << std::endl;
-
- /*
- * Create a new request and populate it with one buffer for each
- * stream.
- */
- request = camera_->createRequest();
- if (!request) {
- std::cerr << "Can't create request" << std::endl;
- return;
- }
-
- for (auto it = buffers.begin(); it != buffers.end(); ++it) {
- Stream *stream = it->first;
- FrameBuffer *buffer = it->second;
-
- request->addBuffer(stream, buffer);
- }
-
- camera_->queueRequest(request);
-}
diff --git a/src/cam/capture.h b/src/cam/capture.h
deleted file mode 100644
index 9bca5661..00000000
--- a/src/cam/capture.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2019, Google Inc.
- *
- * capture.h - Cam capture
- */
-#ifndef __CAM_CAPTURE_H__
-#define __CAM_CAPTURE_H__
-
-#include <chrono>
-#include <memory>
-
-#include <libcamera/buffer.h>
-#include <libcamera/camera.h>
-#include <libcamera/framebuffer_allocator.h>
-#include <libcamera/request.h>
-#include <libcamera/stream.h>
-
-#include "buffer_writer.h"
-#include "event_loop.h"
-#include "options.h"
-
-class Capture
-{
-public:
- Capture(std::shared_ptr<libcamera::Camera> camera,
- libcamera::CameraConfiguration *config);
-
- int run(EventLoop *loop, const OptionsParser::Options &options);
-private:
- int capture(EventLoop *loop,
- libcamera::FrameBufferAllocator *allocator);
-
- void requestComplete(libcamera::Request *request);
-
- std::shared_ptr<libcamera::Camera> camera_;
- libcamera::CameraConfiguration *config_;
-
- std::map<libcamera::Stream *, std::string> streamName_;
- BufferWriter *writer_;
- std::chrono::steady_clock::time_point last_;
-};
-
-#endif /* __CAM_CAPTURE_H__ */
diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp
deleted file mode 100644
index e8ab8617..00000000
--- a/src/cam/event_loop.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2019, Google Inc.
- *
- * event_loop.cpp - cam - Event loop
- */
-
-#include <libcamera/event_dispatcher.h>
-
-#include "event_loop.h"
-
-using namespace libcamera;
-
-EventLoop::EventLoop(EventDispatcher *dispatcher)
- : dispatcher_(dispatcher)
-{
-}
-
-EventLoop::~EventLoop()
-{
-}
-
-int EventLoop::exec()
-{
- exitCode_ = -1;
- exit_.store(false, std::memory_order_release);
-
- while (!exit_.load(std::memory_order_acquire))
- dispatcher_->processEvents();
-
- return exitCode_;
-}
-
-void EventLoop::exit(int code)
-{
- exitCode_ = code;
- exit_.store(true, std::memory_order_release);
- dispatcher_->interrupt();
-}
diff --git a/src/cam/event_loop.h b/src/cam/event_loop.h
deleted file mode 100644
index 581c7cba..00000000
--- a/src/cam/event_loop.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2019, Google Inc.
- *
- * event_loop.h - cam - Event loop
- */
-#ifndef __CAM_EVENT_LOOP_H__
-#define __CAM_EVENT_LOOP_H__
-
-#include <atomic>
-
-#include <libcamera/event_notifier.h>
-
-namespace libcamera {
-class EventDispatcher;
-}
-
-class EventLoop
-{
-public:
- EventLoop(libcamera::EventDispatcher *dispatcher);
- ~EventLoop();
-
- int exec();
- void exit(int code = 0);
-
-private:
- libcamera::EventDispatcher *dispatcher_;
-
- std::atomic<bool> exit_;
- int exitCode_;
-};
-
-#endif /* __CAM_EVENT_LOOP_H__ */
diff --git a/src/cam/main.cpp b/src/cam/main.cpp
deleted file mode 100644
index 718740f4..00000000
--- a/src/cam/main.cpp
+++ /dev/null
@@ -1,385 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2019, Google Inc.
- *
- * main.cpp - cam - The libcamera swiss army knife
- */
-
-#include <iomanip>
-#include <iostream>
-#include <signal.h>
-#include <string.h>
-
-#include <libcamera/libcamera.h>
-#include <libcamera/property_ids.h>
-
-#include "capture.h"
-#include "event_loop.h"
-#include "main.h"
-#include "options.h"
-
-using namespace libcamera;
-
-class CamApp
-{
-public:
- CamApp();
- ~CamApp();
-
- static CamApp *instance();
-
- int init(int argc, char **argv);
- void cleanup();
-
- int exec();
- void quit();
-
-private:
- int parseOptions(int argc, char *argv[]);
- int prepareConfig();
- int listProperties();
- int infoConfiguration();
- int run();
-
- static CamApp *app_;
- OptionsParser::Options options_;
- CameraManager *cm_;
- std::shared_ptr<Camera> camera_;
- std::unique_ptr<libcamera::CameraConfiguration> config_;
- EventLoop *loop_;
-};
-
-CamApp *CamApp::app_ = nullptr;
-
-CamApp::CamApp()
- : cm_(nullptr), camera_(nullptr), config_(nullptr), loop_(nullptr)
-{
- CamApp::app_ = this;
-}
-
-CamApp::~CamApp()
-{
- delete cm_;
-}
-
-CamApp *CamApp::instance()
-{
- return CamApp::app_;
-}
-
-int CamApp::init(int argc, char **argv)
-{
- int ret;
-
- ret = parseOptions(argc, argv);
- if (ret < 0)
- return ret;
-
- cm_ = new CameraManager();
-
- ret = cm_->start();
- if (ret) {
- std::cout << "Failed to start camera manager: "
- << strerror(-ret) << std::endl;
- return ret;
- }
-
- if (options_.isSet(OptCamera)) {
- const std::string &cameraName = options_[OptCamera];
- char *endptr;
- unsigned long index = strtoul(cameraName.c_str(), &endptr, 10);
- if (*endptr == '\0' && index > 0 && index <= cm_->cameras().size())
- camera_ = cm_->cameras()[index - 1];
- else
- camera_ = cm_->get(cameraName);
-
- if (!camera_) {
- std::cout << "Camera "
- << std::string(options_[OptCamera])
- << " not found" << std::endl;
- cm_->stop();
- return -ENODEV;
- }
-
- if (camera_->acquire()) {
- std::cout << "Failed to acquire camera" << std::endl;
- camera_.reset();
- cm_->stop();
- return -EINVAL;
- }
-
- std::cout << "Using camera " << camera_->name() << std::endl;
-
- ret = prepareConfig();
- if (ret)
- return ret;
- }
-
- loop_ = new EventLoop(cm_->eventDispatcher());
-
- return 0;
-}
-
-void CamApp::cleanup()
-{
- delete loop_;
- loop_ = nullptr;
-
- if (camera_) {
- camera_->release();
- camera_.reset();
- }
-
- config_.reset();
-
- cm_->stop();
-}
-
-int CamApp::exec()
-{
- int ret;
-
- ret = run();
- cleanup();
-
- return ret;
-}
-
-void CamApp::quit()
-{
- if (loop_)
- loop_->exit();
-}
-
-int CamApp::parseOptions(int argc, char *argv[])
-{
- KeyValueParser streamKeyValue;
- streamKeyValue.addOption("role", OptionString,
- "Role for the stream (viewfinder, video, still, stillraw)",
- ArgumentRequired);
- streamKeyValue.addOption("width", OptionInteger, "Width in pixels",
- ArgumentRequired);
- streamKeyValue.addOption("height", OptionInteger, "Height in pixels",
- ArgumentRequired);
- streamKeyValue.addOption("pixelformat", OptionInteger, "Pixel format",
- ArgumentRequired);
-
- OptionsParser parser;
- parser.addOption(OptCamera, OptionString,
- "Specify which camera to operate on, by name or by index", "camera",
- ArgumentRequired, "camera");
- parser.addOption(OptCapture, OptionNone,
- "Capture until interrupted by user", "capture");
- parser.addOption(OptFile, OptionString,
- "Write captured frames to disk\n"
- "The first '#' character in the file name is expanded to the stream name and frame sequence number.\n"
- "The default file name is 'frame-#.bin'.",
- "file", ArgumentOptional, "filename");
- parser.addOption(OptStream, &streamKeyValue,
- "Set configuration of a camera stream", "stream", true);
- parser.addOption(OptHelp, OptionNone, "Display this help message",
- "help");
- parser.addOption(OptInfo, OptionNone,
- "Display information about stream(s)", "info");
- parser.addOption(OptList, OptionNone, "List all cameras", "list");
- parser.addOption(OptProps, OptionNone, "List cameras properties",
- "list-properties");
-
- options_ = parser.parse(argc, argv);
- if (!options_.valid())
- return -EINVAL;
-
- if (options_.empty() || options_.isSet(OptHelp)) {
- parser.usage();
- return options_.empty() ? -EINVAL : -EINTR;
- }
-
- return 0;
-}
-
-int CamApp::prepareConfig()
-{
- StreamRoles roles;
-
- if (options_.isSet(OptStream)) {
- const std::vector<OptionValue> &streamOptions =
- options_[OptStream].toArray();
-
- /* Use roles and get a default configuration. */
- for (auto const &value : streamOptions) {
- KeyValueParser::Options opt = value.toKeyValues();
-
- std::string role = opt.isSet("role")
- ? opt["role"].toString()
- : "viewfinder";
-
- if (role == "viewfinder") {
- roles.push_back(StreamRole::Viewfinder);
- } else if (role == "video") {
- roles.push_back(StreamRole::VideoRecording);
- } else if (role == "still") {
- roles.push_back(StreamRole::StillCapture);
- } else if (role == "stillraw") {
- roles.push_back(StreamRole::StillCaptureRaw);
- } else {
- std::cerr << "Unknown stream role "
- << role << std::endl;
- return -EINVAL;
- }
- }
- } else {
- /* If no configuration is provided assume a single video stream. */
- roles.push_back(StreamRole::VideoRecording);
- }
-
- config_ = camera_->generateConfiguration(roles);
- if (!config_ || config_->size() != roles.size()) {
- std::cerr << "Failed to get default stream configuration"
- << std::endl;
- return -EINVAL;
- }
-
- /* Apply configuration if explicitly requested. */
- if (options_.isSet(OptStream)) {
- const std::vector<OptionValue> &streamOptions =
- options_[OptStream].toArray();
-
- unsigned int i = 0;
- for (auto const &value : streamOptions) {
- KeyValueParser::Options opt = value.toKeyValues();
- StreamConfiguration &cfg = config_->at(i++);
-
- if (opt.isSet("width"))
- cfg.size.width = opt["width"];
-
- if (opt.isSet("height"))
- cfg.size.height = opt["height"];
-
- /* TODO: Translate 4CC string to ID. */
- if (opt.isSet("pixelformat"))
- cfg.pixelFormat = PixelFormat(opt["pixelformat"]);
- }
- }
-
- switch (config_->validate()) {
- case CameraConfiguration::Valid:
- break;
- case CameraConfiguration::Adjusted:
- std::cout << "Camera configuration adjusted" << std::endl;
- break;
- case CameraConfiguration::Invalid:
- std::cout << "Camera configuration invalid" << std::endl;
- config_.reset();
- return -EINVAL;
- }
-
- return 0;
-}
-
-int CamApp::listProperties()
-{
- if (!camera_) {
- std::cout << "Cannot list properties without a camera"
- << std::endl;
- return -EINVAL;
- }
-
- for (const auto &prop : camera_->properties()) {
- const ControlId *id = properties::properties.at(prop.first);
- const ControlValue &value = prop.second;
-
- std::cout << "Property: " << id->name() << " = "
- << value.toString() << std::endl;
- }
-
- return 0;
-}
-
-int CamApp::infoConfiguration()
-{
- if (!config_) {
- std::cout << "Cannot print stream information without a camera"
- << std::endl;
- return -EINVAL;
- }
-
- unsigned int index = 0;
- for (const StreamConfiguration &cfg : *config_) {
- std::cout << index << ": " << cfg.toString() << std::endl;
-
- const StreamFormats &formats = cfg.formats();
- for (PixelFormat pixelformat : formats.pixelformats()) {
- std::cout << " * Pixelformat: "
- << pixelformat.toString() << " "
- << formats.range(pixelformat).toString()
- << std::endl;
-
- for (const Size &size : formats.sizes(pixelformat))
- std::cout << " - " << size.toString()
- << std::endl;
- }
-
- index++;
- }
-
- return 0;
-}
-
-int CamApp::run()
-{
- int ret;
-
- if (options_.isSet(OptList)) {
- std::cout << "Available cameras:" << std::endl;
-
- unsigned int index = 1;
- for (const std::shared_ptr<Camera> &cam : cm_->cameras()) {
- std::cout << index << ": " << cam->name() << std::endl;
- index++;
- }
- }
-
- if (options_.isSet(OptProps)) {
- ret = listProperties();
- if (ret)
- return ret;
- }
-
- if (options_.isSet(OptInfo)) {
- ret = infoConfiguration();
- if (ret)
- return ret;
- }
-
- if (options_.isSet(OptCapture)) {
- Capture capture(camera_, config_.get());
- return capture.run(loop_, options_);
- }
-
- return 0;
-}
-
-void signalHandler(int signal)
-{
- std::cout << "Exiting" << std::endl;
- CamApp::instance()->quit();
-}
-
-int main(int argc, char **argv)
-{
- CamApp app;
- int ret;
-
- ret = app.init(argc, argv);
- if (ret)
- return ret == -EINTR ? 0 : EXIT_FAILURE;
-
- struct sigaction sa = {};
- sa.sa_handler = &signalHandler;
- sigaction(SIGINT, &sa, nullptr);
-
- if (app.exec())
- return EXIT_FAILURE;
-
- return 0;
-}
diff --git a/src/cam/main.h b/src/cam/main.h
deleted file mode 100644
index afcad435..00000000
--- a/src/cam/main.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2019, Google Inc.
- *
- * main.h - Cam application
- */
-#ifndef __CAM_MAIN_H__
-#define __CAM_MAIN_H__
-
-enum {
- OptCamera = 'c',
- OptCapture = 'C',
- OptFile = 'F',
- OptHelp = 'h',
- OptInfo = 'I',
- OptList = 'l',
- OptProps = 'p',
- OptStream = 's',
-};
-
-#endif /* __CAM_MAIN_H__ */
diff --git a/src/cam/meson.build b/src/cam/meson.build
deleted file mode 100644
index 2419d648..00000000
--- a/src/cam/meson.build
+++ /dev/null
@@ -1,11 +0,0 @@
-cam_sources = files([
- 'buffer_writer.cpp',
- 'capture.cpp',
- 'event_loop.cpp',
- 'main.cpp',
- 'options.cpp',
-])
-
-cam = executable('cam', cam_sources,
- dependencies : [ libatomic, libcamera_dep ],
- install : true)
diff --git a/src/cam/options.cpp b/src/cam/options.cpp
deleted file mode 100644
index 2c56eacf..00000000
--- a/src/cam/options.cpp
+++ /dev/null
@@ -1,537 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2019, Google Inc.
- *
- * options.cpp - cam - Options parsing
- */
-
-#include <assert.h>
-#include <getopt.h>
-#include <iomanip>
-#include <iostream>
-#include <string.h>
-
-#include "options.h"
-
-/* -----------------------------------------------------------------------------
- * Option
- */
-
-const char *Option::typeName() const
-{
- switch (type) {
- case OptionNone:
- return "none";
-
- case OptionInteger:
- return "integer";
-
- case OptionString:
- return "string";
-
- case OptionKeyValue:
- return "key=value";
- }
-
- return "unknown";
-}
-
-/* -----------------------------------------------------------------------------
- * OptionBase<T>
- */
-
-template<typename T>
-bool OptionsBase<T>::empty() const
-{
- return values_.empty();
-}
-
-template<typename T>
-bool OptionsBase<T>::valid() const
-{
- return valid_;
-}
-
-template<typename T>
-bool OptionsBase<T>::isSet(const T &opt) const
-{
- return values_.find(opt) != values_.end();
-}
-
-template<typename T>
-const OptionValue &OptionsBase<T>::operator[](const T &opt) const
-{
- return values_.find(opt)->second;
-}
-
-template<typename T>
-bool OptionsBase<T>::parseValue(const T &opt, const Option &option,
- const char *optarg)
-{
- OptionValue value;
-
- switch (option.type) {
- case OptionNone:
- break;
-
- case OptionInteger:
- unsigned int integer;
-
- if (optarg) {
- char *endptr;
- integer = strtoul(optarg, &endptr, 0);
- if (*endptr != '\0')
- return false;
- } else {
- integer = 0;
- }
-
- value = OptionValue(integer);
- break;
-
- case OptionString:
- value = OptionValue(optarg ? optarg : "");
- break;
-
- case OptionKeyValue:
- KeyValueParser *kvParser = option.keyValueParser;
- KeyValueParser::Options keyValues = kvParser->parse(optarg);
- if (!keyValues.valid())
- return false;
-
- value = OptionValue(keyValues);
- break;
- }
-
- if (option.isArray)
- values_[opt].addValue(value);
- else
- values_[opt] = value;
-
- return true;
-}
-
-template class OptionsBase<int>;
-template class OptionsBase<std::string>;
-
-/* -----------------------------------------------------------------------------
- * KeyValueParser
- */
-
-bool KeyValueParser::addOption(const char *name, OptionType type,
- const char *help, OptionArgument argument)
-{
- if (!name)
- return false;
- if (!help || help[0] == '\0')
- return false;
- if (argument != ArgumentNone && type == OptionNone)
- return false;
-
- /* Reject duplicate options. */
- if (optionsMap_.find(name) != optionsMap_.end())
- return false;
-
- optionsMap_[name] = Option({ 0, type, name, argument, nullptr,
- help, nullptr, false });
- return true;
-}
-
-KeyValueParser::Options KeyValueParser::parse(const char *arguments)
-{
- Options options;
-
- for (const char *pair = arguments; *arguments != '\0'; pair = arguments) {
- const char *comma = strchrnul(arguments, ',');
- size_t len = comma - pair;
-
- /* Skip over the comma. */
- arguments = *comma == ',' ? comma + 1 : comma;
-
- /* Skip to the next pair if the pair is empty. */
- if (!len)
- continue;
-
- std::string key;
- std::string value;
-
- const char *separator = static_cast<const char *>(memchr(pair, '=', len));
- if (!separator) {
- key = std::string(pair, len);
- value = "";
- } else {
- key = std::string(pair, separator - pair);
- value = std::string(separator + 1, comma - separator - 1);
- }
-
- /* The key is mandatory, the value might be optional. */
- if (key.empty())
- continue;
-
- if (optionsMap_.find(key) == optionsMap_.end()) {
- std::cerr << "Invalid option " << key << std::endl;
- return options;
- }
-
- OptionArgument arg = optionsMap_[key].argument;
- if (value.empty() && arg == ArgumentRequired) {
- std::cerr << "Option " << key << " requires an argument"
- << std::endl;
- return options;
- } else if (!value.empty() && arg == ArgumentNone) {
- std::cerr << "Option " << key << " takes no argument"
- << std::endl;
- return options;
- }
-
- const Option &option = optionsMap_[key];
- if (!options.parseValue(key, option, value.c_str())) {
- std::cerr << "Failed to parse '" << value << "' as "
- << option.typeName() << " for option " << key
- << std::endl;
- return options;
- }
- }
-
- options.valid_ = true;
- return options;
-}
-
-void KeyValueParser::usage(int indent)
-{
- unsigned int space = 0;
-
- for (auto const &iter : optionsMap_) {
- const Option &option = iter.second;
- unsigned int length = 14;
- if (option.argument != ArgumentNone)
- length += 1 + strlen(option.typeName());
- if (option.argument == ArgumentOptional)
- length += 2;
-
- if (length > space)
- space = length;
- }
-
- space = (space + 7) / 8 * 8;
-
- for (auto const &iter : optionsMap_) {
- const Option &option = iter.second;
- std::string argument = option.name;
-
- if (option.argument != ArgumentNone) {
- if (option.argument == ArgumentOptional)
- argument += "[=";
- else
- argument += "=";
- argument += option.typeName();
- if (option.argument == ArgumentOptional)
- argument += "]";
- }
-
- std::cerr << std::setw(indent) << std::right << " "
- << std::setw(space) << std::left << argument;
-
- for (const char *help = option.help, *end = help; end;) {
- end = strchr(help, '\n');
- if (end) {
- std::cerr << std::string(help, end - help + 1);
- std::cerr << std::setw(indent + space) << " ";
- help = end + 1;
- } else {
- std::cerr << help << std::endl;
- }
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * OptionValue
- */
-
-OptionValue::OptionValue()
- : type_(ValueNone), integer_(0)
-{
-}
-
-OptionValue::OptionValue(int value)
- : type_(ValueInteger), integer_(value)
-{
-}
-
-OptionValue::OptionValue(const char *value)
- : type_(ValueString), integer_(0), string_(value)
-{
-}
-
-OptionValue::OptionValue(const std::string &value)
- : type_(ValueString), integer_(0), string_(value)
-{
-}
-
-OptionValue::OptionValue(const KeyValueParser::Options &value)
- : type_(ValueKeyValue), integer_(0), keyValues_(value)
-{
-}
-
-void OptionValue::addValue(const OptionValue &value)
-{
- assert(type_ == ValueNone || type_ == ValueArray);
-
- type_ = ValueArray;
- array_.push_back(value);
-}
-
-OptionValue::operator int() const
-{
- return toInteger();
-}
-
-OptionValue::operator std::string() const
-{
- return toString();
-}
-
-OptionValue::operator KeyValueParser::Options() const
-{
- return toKeyValues();
-}
-
-OptionValue::operator std::vector<OptionValue>() const
-{
- return toArray();
-}
-
-int OptionValue::toInteger() const
-{
- if (type_ != ValueInteger)
- return 0;
-
- return integer_;
-}
-
-std::string OptionValue::toString() const
-{
- if (type_ != ValueString)
- return std::string();
-
- return string_;
-}
-
-KeyValueParser::Options OptionValue::toKeyValues() const
-{
- if (type_ != ValueKeyValue)
- return KeyValueParser::Options();
-
- return keyValues_;
-}
-
-std::vector<OptionValue> OptionValue::toArray() const
-{
- if (type_ != ValueArray)
- return std::vector<OptionValue>{};
-
- return array_;
-}
-
-/* -----------------------------------------------------------------------------
- * OptionsParser
- */
-
-bool OptionsParser::addOption(int opt, OptionType type, const char *help,
- const char *name, OptionArgument argument,
- const char *argumentName, bool array)
-{
- /*
- * Options must have at least a short or long name, and a text message.
- * If an argument is accepted, it must be described by argumentName.
- */
- if (!isalnum(opt) && !name)
- return false;
- if (!help || help[0] == '\0')
- return false;
- if (argument != ArgumentNone && !argumentName)
- return false;
-
- /* Reject duplicate options. */
- if (optionsMap_.find(opt) != optionsMap_.end())
- return false;
-
- options_.push_back(Option({ opt, type, name, argument, argumentName,
- help, nullptr, array }));
- optionsMap_[opt] = &options_.back();
- return true;
-}
-
-bool OptionsParser::addOption(int opt, KeyValueParser *parser, const char *help,
- const char *name, bool array)
-{
- if (!addOption(opt, OptionKeyValue, help, name, ArgumentRequired,
- "key=value[,key=value,...]", array))
- return false;
-
- options_.back().keyValueParser = parser;
- return true;
-}
-
-OptionsParser::Options OptionsParser::parse(int argc, char **argv)
-{
- OptionsParser::Options options;
-
- /*
- * Allocate short and long options arrays large enough to contain all
- * options.
- */
- char shortOptions[options_.size() * 3 + 2];
- struct option longOptions[options_.size() + 1];
- unsigned int ids = 0;
- unsigned int idl = 0;
-
- shortOptions[ids++] = ':';
-
- for (const Option &option : options_) {
- if (option.hasShortOption()) {
- shortOptions[ids++] = option.opt;
- if (option.argument != ArgumentNone)
- shortOptions[ids++] = ':';
- if (option.argument == ArgumentOptional)
- shortOptions[ids++] = ':';
- }
-
- if (option.hasLongOption()) {
- longOptions[idl].name = option.name;
-
- switch (option.argument) {
- case ArgumentNone:
- longOptions[idl].has_arg = no_argument;
- break;
- case ArgumentRequired:
- longOptions[idl].has_arg = required_argument;
- break;
- case ArgumentOptional:
- longOptions[idl].has_arg = optional_argument;
- break;
- }
-
- longOptions[idl].flag = 0;
- longOptions[idl].val = option.opt;
- idl++;
- }
- }
-
- shortOptions[ids] = '\0';
- memset(&longOptions[idl], 0, sizeof(longOptions[idl]));
-
- opterr = 0;
-
- while (true) {
- int c = getopt_long(argc, argv, shortOptions, longOptions, nullptr);
-
- if (c == -1)
- break;
-
- if (c == '?' || c == ':') {
- if (c == '?')
- std::cerr << "Invalid option ";
- else
- std::cerr << "Missing argument for option ";
- std::cerr << argv[optind - 1] << std::endl;
-
- usage();
- return options;
- }
-
- const Option &option = *optionsMap_[c];
- if (!options.parseValue(c, option, optarg)) {
- parseValueError(option);
- usage();
- return options;
- }
- }
-
- options.valid_ = true;
- return options;
-}
-
-void OptionsParser::usage()
-{
- std::cerr << "Options:" << std::endl;
-
- unsigned int indent = 0;
-
- for (const Option &option : options_) {
- unsigned int length = 14;
- if (option.hasLongOption())
- length += 2 + strlen(option.name);
- if (option.argument != ArgumentNone)
- length += 1 + strlen(option.argumentName);
- if (option.argument == ArgumentOptional)
- length += 2;
- if (option.isArray)
- length += 4;
-
- if (length > indent)
- indent = length;
- }
-
- indent = (indent + 7) / 8 * 8;
-
- for (const Option &option : options_) {
- std::string argument;
- if (option.hasShortOption())
- argument = std::string(" -")
- + static_cast<char>(option.opt);
- else
- argument = " ";
-
- if (option.hasLongOption()) {
- if (option.hasShortOption())
- argument += ", ";
- else
- argument += " ";
- argument += std::string("--") + option.name;
- }
-
- if (option.argument != ArgumentNone) {
- if (option.argument == ArgumentOptional)
- argument += "[=";
- else
- argument += " ";
- argument += option.argumentName;
- if (option.argument == ArgumentOptional)
- argument += "]";
- }
-
- if (option.isArray)
- argument += " ...";
-
- std::cerr << std::setw(indent) << std::left << argument;
-
- for (const char *help = option.help, *end = help; end; ) {
- end = strchr(help, '\n');
- if (end) {
- std::cerr << std::string(help, end - help + 1);
- std::cerr << std::setw(indent) << " ";
- help = end + 1;
- } else {
- std::cerr << help << std::endl;
- }
- }
-
- if (option.keyValueParser)
- option.keyValueParser->usage(indent);
- }
-}
-
-void OptionsParser::parseValueError(const Option &option)
-{
- std::string optionName;
-
- if (option.name)
- optionName = "--" + std::string(option.name);
- else
- optionName = "-" + std::string(1, option.opt);
-
- std::cerr << "Can't parse " << option.typeName()
- << " argument for option " << optionName << std::endl;
-}
diff --git a/src/cam/options.h b/src/cam/options.h
deleted file mode 100644
index 5e346b47..00000000
--- a/src/cam/options.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2019, Google Inc.
- *
- * options.h - cam - Options parsing
- */
-#ifndef __CAM_OPTIONS_H__
-#define __CAM_OPTIONS_H__
-
-#include <ctype.h>
-#include <list>
-#include <map>
-#include <vector>
-
-class KeyValueParser;
-class OptionValue;
-
-enum OptionArgument {
- ArgumentNone,
- ArgumentRequired,
- ArgumentOptional,
-};
-
-enum OptionType {
- OptionNone,
- OptionInteger,
- OptionString,
- OptionKeyValue,
-};
-
-struct Option {
- int opt;
- OptionType type;
- const char *name;
- OptionArgument argument;
- const char *argumentName;
- const char *help;
- KeyValueParser *keyValueParser;
- bool isArray;
-
- bool hasShortOption() const { return isalnum(opt); }
- bool hasLongOption() const { return name != nullptr; }
- const char *typeName() const;
-};
-
-template<typename T>
-class OptionsBase
-{
-public:
- OptionsBase() : valid_(false) {}
-
- bool empty() const;
- bool valid() const;
- bool isSet(const T &opt) const;
- const OptionValue &operator[](const T &opt) const;
-
-private:
- friend class KeyValueParser;
- friend class OptionsParser;
-
- bool parseValue(const T &opt, const Option &option, const char *value);
-
- std::map<T, OptionValue> values_;
- bool valid_;
-};
-
-class KeyValueParser
-{
-public:
- class Options : public OptionsBase<std::string>
- {
- };
-
- bool addOption(const char *name, OptionType type, const char *help,
- OptionArgument argument = ArgumentNone);
-
- Options parse(const char *arguments);
- void usage(int indent);
-
-private:
- std::map<std::string, Option> optionsMap_;
-};
-
-class OptionValue
-{
-public:
- enum ValueType {
- ValueNone,
- ValueInteger,
- ValueString,
- ValueKeyValue,
- ValueArray,
- };
-
- OptionValue();
- OptionValue(int value);
- OptionValue(const char *value);
- OptionValue(const std::string &value);
- OptionValue(const KeyValueParser::Options &value);
-
- void addValue(const OptionValue &value);
-
- ValueType type() const { return type_; }
-
- operator int() const;
- operator std::string() const;
- operator KeyValueParser::Options() const;
- operator std::vector<OptionValue>() const;
-
- int toInteger() const;
- std::string toString() const;
- KeyValueParser::Options toKeyValues() const;
- std::vector<OptionValue> toArray() const;
-
-private:
- ValueType type_;
- int integer_;
- std::string string_;
- KeyValueParser::Options keyValues_;
- std::vector<OptionValue> array_;
-};
-
-class OptionsParser
-{
-public:
- class Options : public OptionsBase<int>
- {
- };
-
- bool addOption(int opt, OptionType type, const char *help,
- const char *name = nullptr,
- OptionArgument argument = ArgumentNone,
- const char *argumentName = nullptr, bool array = false);
- bool addOption(int opt, KeyValueParser *parser, const char *help,
- const char *name = nullptr, bool array = false);
-
- Options parse(int argc, char *argv[]);
- void usage();
-
-private:
- void parseValueError(const Option &option);
-
- std::list<Option> options_;
- std::map<unsigned int, Option *> optionsMap_;
-};
-
-#endif /* __CAM_OPTIONS_H__ */