[libcamera-devel,v4,30/31] HACK: src: cam: Play with streams combinations

Message ID 20190320163055.22056-31-jacopo@jmondi.org
State Superseded
Headers show
Series
  • libcamera: ipu3: Add ImgU support + multiple streams
Related show

Commit Message

Jacopo Mondi March 20, 2019, 4:30 p.m. UTC
Make the 'configureStreams()' method of the camera application accept a
map of stream configuration to be used to create and fill requests.

This allow to easily change which streams to capture from.
while at there, hardcode the viewfinder output size to 640x480 to
demostrate the two output can have different resolutions.

This commit is clearly an hack and shall be removed once it is possible
to specify per-stream configuration from the command line.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 src/cam/main.cpp | 48 ++++++++++++++++++++++++++++++++++++------------
 1 file changed, 36 insertions(+), 12 deletions(-)

Patch

diff --git a/src/cam/main.cpp b/src/cam/main.cpp
index a2364ef92bad..28ea0b7d76b2 100644
--- a/src/cam/main.cpp
+++ b/src/cam/main.cpp
@@ -75,26 +75,40 @@  static int parseOptions(int argc, char *argv[])
 	return 0;
 }
 
-static int configureStreams(Camera *camera, std::set<Stream *> &streams)
+static int configureStreams(Camera *camera, std::set<Stream *> &streams,
+			    std::map<Stream *, StreamConfiguration> &config)
 {
 	KeyValueParser::Options format = options[OptFormat];
-	Stream *id = *streams.begin();
+	auto it = streams.begin();
+	Stream *output = *it;
+	Stream *viewfinder = *(++it);
 
-	std::map<Stream *, StreamConfiguration> config =
+	std::map<Stream *, StreamConfiguration> defaultConfig =
 		camera->streamConfiguration(streams);
 
 	if (options.isSet(OptFormat)) {
 		if (format.isSet("width"))
-			config[id].width = format["width"];
+			defaultConfig[output].width = format["width"];
 
 		if (format.isSet("height"))
-			config[id].height = format["height"];
+			defaultConfig[output].height = format["height"];
 
 		/* TODO: Translate 4CC string to ID. */
 		if (format.isSet("pixelformat"))
-			config[id].pixelFormat = format["pixelformat"];
+			defaultConfig[output].pixelFormat = format["pixelformat"];
 	}
 
+	/* Configure the secondary output stream. */
+	defaultConfig[viewfinder].width = 640;
+	defaultConfig[viewfinder].height = 480;
+
+	/*
+	 * HACK: add output/viewfinder to 'config'
+	 * to play with stream combinations.
+	 */
+	config[output] = defaultConfig[output];
+	config[viewfinder] = defaultConfig[viewfinder];
+
 	return camera->configureStreams(config);
 }
 
@@ -145,17 +159,21 @@  static void requestComplete(Request *request,
 
 static int capture()
 {
+	std::set<Stream *> cameraStreams = camera->streams();
+	std::map<Stream *, StreamConfiguration> config;
 	int ret;
 
-	std::set<Stream *> streams = camera->streams();
-	std::vector<Request *> requests;
-
-	ret = configureStreams(camera.get(), streams);
+	ret = configureStreams(camera.get(), cameraStreams, config);
 	if (ret < 0) {
 		std::cout << "Failed to configure camera" << std::endl;
 		return ret;
 	}
 
+	if (config.empty()) {
+		std::cout << "Stream configuration is empty" << std::endl;
+		return ret;
+	}
+
 	ret = camera->allocateBuffers();
 	if (ret) {
 		std::cerr << "Failed to allocate buffers"
@@ -163,13 +181,19 @@  static int capture()
 		return ret;
 	}
 
+	/* Store only the active streams. */
+	std::set<Stream *> activeStreams;
+	for (const auto &iter : config)
+		activeStreams.insert(iter.first);
+
 	/*
 	 * Create the requests to be later enqueued.
 	 *
 	 * FIXME: Assume all streams have the same number of buffers: use
 	 * the first stream's buffer pool and create on request per buffer.
 	 */
-	unsigned int bufferCount = (*streams.begin())->bufferPool().count();
+	std::vector<Request *> requests;
+	unsigned int bufferCount = (*activeStreams.begin())->bufferPool().count();
 	for (unsigned int i = 0; i < bufferCount; ++i) {
 		Request *request = camera->createRequest();
 		if (!request) {
@@ -180,7 +204,7 @@  static int capture()
 
 		/* Provide to each request a stream to buffer association map. */
 		std::map<Stream *, Buffer *> requestMap;
-		for (Stream *stream : streams) {
+		for (Stream *stream : activeStreams) {
 			Buffer *buffer = &stream->bufferPool().buffers()[i];
 			requestMap[stream] = buffer;
 		}