summaryrefslogtreecommitdiff
path: root/src/ipa/rkisp1/meson.build
AgeCommit message (Expand)Author
2024-08-27ipa: rkisp1: Add ISP parameters abstraction classLaurent Pinchart
2024-08-07libcamera: Drop libcamera_generated_ipa_headers from sourcesLaurent Pinchart
2024-06-11meson: Group libipa and libipa_includes in a dependency objectLaurent Pinchart
2024-05-31ipa: rkisp1: Add a helper to convert floating-point to fixed-pointPaul Elder
2023-05-04ipa: meson: Allow nested IPA directory structuresNaushir Patuck
2022-06-29ipa: rkisp1: Add OV5640 tuning fileFlorian Sylvestre
2021-11-29ipa: rkisp1: Use the Algorithm classJean-Michel Hautbois
2021-11-29ipa: rkisp1: Introduce IPAContextJean-Michel Hautbois
2021-06-25libcamera/base: Validate internal headers as privateKieran Bingham
2021-02-16libcamera: IPAInterface: Replace C API with the new C++-only APIPaul Elder
2021-02-11meson: Fix coding style when declaring arraysLaurent Pinchart
2020-05-13licenses: License all meson files under CC0-1.0Laurent Pinchart
2020-04-30libcamera: Build IPA module signatures by defaultLaurent Pinchart
2020-04-29libcamera: Regenerate IPA module signatures at install timeLaurent Pinchart
2020-04-16libcamera: Make IPA module signing optionalLaurent Pinchart
2020-04-14libcamera: Add IPA module signing infrastructureLaurent Pinchart
2019-11-20ipa: Switch to the plain C APIJacopo Mondi
2019-10-11libcamera: ipa: rkisp1: Add basic control of auto exposureNiklas Söderlund
#n155'>155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
/* 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;

class CamApp
{
public:
	CamApp();

	static CamApp *instance();

	int init(int argc, char **argv);
	void cleanup();

	int exec();
	void quit();

private:
	int parseOptions(int argc, char *argv[]);
	int run();

	static CamApp *app_;
	OptionsParser::Options options_;
	CameraManager *cm_;
	std::shared_ptr<Camera> camera_;
	EventLoop *loop_;
};

CamApp *CamApp::app_ = nullptr;

CamApp::CamApp()
	: cm_(nullptr), camera_(nullptr), loop_(nullptr)
{
	CamApp::app_ = this;
}

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_ = CameraManager::instance();

	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;
	}

	loop_ = new EventLoop(cm_->eventDispatcher());

	return 0;
}

void CamApp::cleanup()
{
	delete loop_;
	loop_ = nullptr;

	if (camera_) {
		camera_->release();
		camera_.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)",
				 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(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 CamApp::run()
{
	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(OptCapture)) {
		Capture capture(camera_.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;
}