[libcamera-devel,v2,7/7] cam: add option to statically configure a pipeline

Message ID 20190125153340.2744-8-niklas.soderlund@ragnatech.se
State Superseded
Delegated to: Niklas Söderlund
Headers show
Series
  • libcamera: add basic support for Streams and format configuration
Related show

Commit Message

Niklas Söderlund Jan. 25, 2019, 3:33 p.m. UTC
Add a option to statically configure the first stream of a camera to a
fixed resolution. This should obviously be improved in the future but
for now serves as a good exercise for the Camera API towards an
application.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
---
 src/cam/main.cpp | 62 ++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 50 insertions(+), 12 deletions(-)

Patch

diff --git a/src/cam/main.cpp b/src/cam/main.cpp
index cb98d302dcf30331..b8c05d9079be3cb3 100644
--- a/src/cam/main.cpp
+++ b/src/cam/main.cpp
@@ -20,7 +20,8 @@  using namespace libcamera;
 OptionsParser::Options options;
 
 enum {
-	OptCamera = 'c',
+	OptCamera = 'C',
+	OptFormat = 'f',
 	OptHelp = 'h',
 	OptList = 'l',
 };
@@ -40,6 +41,7 @@  static int parseOptions(int argc, char *argv[])
 	parser.addOption(OptCamera, "Specify which camera to operate on",
 			 "camera", OptionsParser::ArgumentRequired,
 			 "camera");
+	parser.addOption(OptFormat, "Configure the first stream to 640x480", "format");
 	parser.addOption(OptHelp, "Display this help message", "help");
 	parser.addOption(OptList, "List all cameras", "list");
 
@@ -64,6 +66,8 @@  int main(int argc, char **argv)
 		return EXIT_FAILURE;
 
 	CameraManager *cm = CameraManager::instance();
+	std::shared_ptr<Camera> camera;
+	std::vector<Stream> streams;
 
 	ret = cm->start();
 	if (ret) {
@@ -72,31 +76,65 @@  int main(int argc, char **argv)
 		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> &camera : cm->cameras())
-			std::cout << "- " << camera->name() << std::endl;
+		for (const std::shared_ptr<Camera> &cam : cm->cameras())
+			std::cout << "- " << cam->name() << std::endl;
 	}
 
 	if (options.isSet(OptCamera)) {
-		std::shared_ptr<Camera> cam = cm->get(options[OptCamera]);
-
-		if (cam) {
-			std::cout << "Using camera " << cam->name() << std::endl;
-		} else {
+		camera = cm->get(options[OptCamera]);
+		if (!camera) {
 			std::cout << "Camera " << options[OptCamera]
 				  << " not found" << std::endl;
+			goto out;
+		}
+
+		streams = camera->streams();
+		if (streams.size() != 1) {
+			std::cout << "Camera have " << streams.size() <<
+				" streams, I only know how to work with 1" << 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;
 	}
 
-	loop = new EventLoop(cm->eventDispatcher());
+	if (options.isSet(OptFormat)) {
+		if (!camera) {
+			std::cout << "Can't configure stream, no camera selected" << std::endl;
+			goto out_camera;
+		}
 
-	struct sigaction sa = {};
-	sa.sa_handler = &signalHandler;
-	sigaction(SIGINT, &sa, nullptr);
+		StreamConfiguration config = StreamConfiguration(streams.front());
+		config.setDimension(640, 480);
+
+		std::vector<StreamConfiguration *> configs;
+		configs.push_back(&config);
+
+		if (camera->configure(configs))
+			std::cout << "Failed to configure camera" << std::endl;
+	}
 
 	ret = loop->exec();
 
+out_camera:
+	if (camera) {
+		camera->release();
+		camera.reset();
+	}
+out:
 	delete loop;
 
 	cm->stop();