/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2019, Google Inc. * * main.cpp - cam - The libcamera swiss army knife */ #include #include #include #include #include "capture.h" #include "event_loop.h" #include "main.h" #include "options.h" using namespace libcamera; OptionsParser::Options options; std::shared_ptr 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 &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; }