[libcamera-devel] [PATCH v2 26/30] cam: Reorganize run() function and merge the two event loops

Laurent Pinchart laurent.pinchart at ideasonboard.com
Mon Jul 12 23:56:41 CEST 2021


Reorganize the run() function to make it more readable, and merge the
two event loops into one as capture and hotplug monitoring don't have to
be mutually exclusive.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
---
 src/cam/main.cpp | 60 ++++++++++++++++++++++++------------------------
 1 file changed, 30 insertions(+), 30 deletions(-)

diff --git a/src/cam/main.cpp b/src/cam/main.cpp
index 380c14e02cf0..a3f19d0fa61b 100644
--- a/src/cam/main.cpp
+++ b/src/cam/main.cpp
@@ -5,6 +5,7 @@
  * main.cpp - cam - The libcamera swiss army knife
  */
 
+#include <atomic>
 #include <iomanip>
 #include <iostream>
 #include <signal.h>
@@ -48,6 +49,7 @@ private:
 
 	std::unique_ptr<CameraManager> cm_;
 
+	std::atomic_uint loopUsers_;
 	EventLoop loop_;
 };
 
@@ -164,14 +166,15 @@ void CamApp::cameraRemoved(std::shared_ptr<Camera> cam)
 
 void CamApp::captureDone()
 {
-	EventLoop::instance()->exit(0);
+	if (--loopUsers_ == 0)
+		EventLoop::instance()->exit(0);
 }
 
 int CamApp::run()
 {
-	std::unique_ptr<CameraSession> session;
 	int ret;
 
+	/* 1. List all cameras. */
 	if (options_.isSet(OptList)) {
 		std::cout << "Available cameras:" << std::endl;
 
@@ -182,6 +185,9 @@ int CamApp::run()
 		}
 	}
 
+	/* 2. Create the camera session. */
+	std::unique_ptr<CameraSession> session;
+
 	if (options_.isSet(OptCamera)) {
 		session = std::make_unique<CameraSession>(cm_.get(), options_);
 		if (!session->isValid()) {
@@ -195,36 +201,25 @@ int CamApp::run()
 		session->captureDone.connect(this, &CamApp::captureDone);
 	}
 
-	if (options_.isSet(OptListControls)) {
+	/* 3. Print camera information. */
+	if (options_.isSet(OptListControls) ||
+	    options_.isSet(OptListProperties) ||
+	    options_.isSet(OptInfo)) {
 		if (!session) {
-			std::cout << "Cannot list controls without a camera"
+			std::cout << "Cannot print camera information without a camera"
 				  << std::endl;
 			return -EINVAL;
 		}
 
-		session->listControls();
-	}
-
-	if (options_.isSet(OptListProperties)) {
-		if (!session) {
-			std::cout << "Cannot list properties without a camera"
-				  << std::endl;
-			return -EINVAL;
-		}
-
-		session->listProperties();
-	}
-
-	if (options_.isSet(OptInfo)) {
-		if (!session) {
-			std::cout << "Cannot print stream information without a camera"
-				  << std::endl;
-			return -EINVAL;
-		}
-
-		session->infoConfiguration();
+		if (options_.isSet(OptListControls))
+			session->listControls();
+		if (options_.isSet(OptListProperties))
+			session->listProperties();
+		if (options_.isSet(OptInfo))
+			session->infoConfiguration();
 	}
 
+	/* 4. Start capture. */
 	if (options_.isSet(OptCapture)) {
 		if (!session) {
 			std::cout << "Can't capture without a camera" << std::endl;
@@ -237,12 +232,10 @@ int CamApp::run()
 			return ret;
 		}
 
-		loop_.exec();
-
-		session->stop();
-		return 0;
+		loopUsers_++;
 	}
 
+	/* 5. Enable hotplug monitoring. */
 	if (options_.isSet(OptMonitor)) {
 		std::cout << "Monitoring new hotplug and unplug events" << std::endl;
 		std::cout << "Press Ctrl-C to interrupt" << std::endl;
@@ -250,9 +243,16 @@ int CamApp::run()
 		cm_->cameraAdded.connect(this, &CamApp::cameraAdded);
 		cm_->cameraRemoved.connect(this, &CamApp::cameraRemoved);
 
-		loop_.exec();
+		loopUsers_++;
 	}
 
+	if (loopUsers_)
+		loop_.exec();
+
+	/* 6. Stop capture. */
+	if (options_.isSet(OptCapture))
+		session->stop();
+
 	return 0;
 }
 
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list