Files
external_libcamera/src/cam/main.cpp
Niklas Söderlund e741a5482c cam: capture: Break out capture to a new class
Reduce the complexity of main.cpp by compartmentalising the capture
logic into its own class. There is no functional change.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-05-25 14:27:55 +02:00

135 lines
3.2 KiB
C++

/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2019, Google Inc.
*
* main.cpp - cam - The libcamera swiss army knife
*/
#include <iostream>
#include <signal.h>
#include <string.h>
#include <libcamera/libcamera.h>
#include "capture.h"
#include "event_loop.h"
#include "main.h"
#include "options.h"
using namespace libcamera;
OptionsParser::Options options;
std::shared_ptr<Camera> camera;
EventLoop *loop;
void signalHandler(int signal)
{
std::cout << "Exiting" << std::endl;
loop->exit();
}
static int parseOptions(int argc, char *argv[])
{
KeyValueParser streamKeyValue;
streamKeyValue.addOption("role", OptionString,
"Role for the stream (viewfinder, video, still)",
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", "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(OptList, OptionNone, "List all cameras", "list");
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 main(int argc, char **argv)
{
int ret;
ret = parseOptions(argc, argv);
if (ret < 0)
return ret == -EINTR ? 0 : EXIT_FAILURE;
CameraManager *cm = CameraManager::instance();
ret = cm->start();
if (ret) {
std::cout << "Failed to start camera manager: "
<< strerror(-ret) << std::endl;
return EXIT_FAILURE;
}
loop = new EventLoop(cm->eventDispatcher());
struct sigaction sa = {};
sa.sa_handler = &signalHandler;
sigaction(SIGINT, &sa, nullptr);
if (options.isSet(OptList)) {
std::cout << "Available cameras:" << std::endl;
for (const std::shared_ptr<Camera> &cam : cm->cameras())
std::cout << "- " << cam->name() << std::endl;
}
if (options.isSet(OptCamera)) {
camera = cm->get(options[OptCamera]);
if (!camera) {
std::cout << "Camera "
<< std::string(options[OptCamera])
<< " not found" << std::endl;
goto out;
}
if (camera->acquire()) {
std::cout << "Failed to acquire camera" << std::endl;
goto out;
}
std::cout << "Using camera " << camera->name() << std::endl;
}
if (options.isSet(OptCapture)) {
Capture capture(camera.get());
ret = capture.run(loop, options);
}
if (camera) {
camera->release();
camera.reset();
}
out:
delete loop;
cm->stop();
return ret;
}