[libcamera-devel,05/20] libcamera: ipu3: Remove streams from generateConfiguration

Message ID 20200714104212.48683-6-jacopo@jmondi.org
State Accepted
Headers show
Series
  • libcamera: ipu3: Rework pipe configuration
Related show

Commit Message

Jacopo Mondi July 14, 2020, 10:41 a.m. UTC
Remove stream assignment from the IPU3 pipeline handler
generateConfiguration() implementation.

The function aims to provide a suitable default for the requested use
cases. Defer stream assignment to validation and only initialize sizes
and formats.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 src/libcamera/pipeline/ipu3/ipu3.cpp | 103 ++++++++-------------------
 1 file changed, 29 insertions(+), 74 deletions(-)

Patch

diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index eb00eecfd10a..f291fbb786af 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -31,6 +31,15 @@  namespace libcamera {
 
 LOG_DEFINE_CATEGORY(IPU3)
 
+static constexpr unsigned int IPU3_BUFFER_COUNT = 4;
+static constexpr unsigned int IPU3_MAX_STREAMS = 3;
+static const Size IMGU_OUTPUT_MIN_SIZE = { 2, 2 };
+static const Size IMGU_OUTPUT_MAX_SIZE = { 4480, 34004 };
+static constexpr unsigned int IMGU_OUTPUT_WIDTH_ALIGN = 64;
+static constexpr unsigned int IMGU_OUTPUT_HEIGHT_ALIGN = 4;
+static constexpr unsigned int IMGU_OUTPUT_WIDTH_MARGIN = 64;
+static constexpr unsigned int IMGU_OUTPUT_HEIGHT_MARGIN = 32;
+
 class IPU3CameraData : public CameraData
 {
 public:
@@ -61,9 +70,6 @@  public:
 	const std::vector<const Stream *> &streams() { return streams_; }
 
 private:
-	static constexpr unsigned int IPU3_BUFFER_COUNT = 4;
-	static constexpr unsigned int IPU3_MAX_STREAMS = 3;
-
 	void assignStreams();
 	void adjustStream(StreamConfiguration &cfg, bool scale);
 
@@ -299,94 +305,49 @@  CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,
 {
 	IPU3CameraData *data = cameraData(camera);
 	IPU3CameraConfiguration *config = new IPU3CameraConfiguration(camera, data);
-	std::set<Stream *> streams = {
-		&data->outStream_,
-		&data->vfStream_,
-		&data->rawStream_,
-	};
 
 	if (roles.empty())
 		return config;
 
+	Size sensorResolution = data->cio2_.sensor()->resolution();
 	for (const StreamRole role : roles) {
 		StreamConfiguration cfg = {};
-		Stream *stream = nullptr;
-
-		cfg.pixelFormat = formats::NV12;
 
 		switch (role) {
 		case StreamRole::StillCapture:
 			/*
-			 * Pick the output stream by default as the Viewfinder
-			 * and VideoRecording roles are not allowed on
-			 * the output stream.
-			 */
-			if (streams.find(&data->outStream_) != streams.end()) {
-				stream = &data->outStream_;
-			} else if (streams.find(&data->vfStream_) != streams.end()) {
-				stream = &data->vfStream_;
-			} else {
-				LOG(IPU3, Error)
-					<< "No stream available for requested role "
-					<< role;
-				break;
-			}
-
-			/*
-			 * FIXME: Soraka: the maximum resolution reported by
-			 * both sensors (2592x1944 for ov5670 and 4224x3136 for
-			 * ov13858) are returned as default configurations but
-			 * they're not correctly processed by the ImgU.
-			 * Resolutions up tp 2560x1920 have been validated.
-			 *
-			 * \todo Clarify ImgU alignment requirements.
+			 * Use the sensor resolution aligned to the ImgU
+			 * output constraints and required frame margin
+			 * by rounding down to the closest alignment.
 			 */
-			cfg.size = { 2560, 1920 };
+			cfg.size = sensorResolution.boundedTo(IMGU_OUTPUT_MAX_SIZE);
+			cfg.size.width = utils::alignDown(cfg.size.width - 1,
+							  IMGU_OUTPUT_WIDTH_MARGIN);
+			cfg.size.height = utils::alignDown(cfg.size.height - 1,
+							   IMGU_OUTPUT_HEIGHT_MARGIN);
+			cfg.pixelFormat = formats::NV12;
+			cfg.bufferCount = IPU3_BUFFER_COUNT;
 
 			break;
 
 		case StreamRole::StillCaptureRaw: {
-			if (streams.find(&data->rawStream_) == streams.end()) {
-				LOG(IPU3, Error)
-					<< "Multiple raw streams are not supported";
-				break;
-			}
-
-			stream = &data->rawStream_;
-
-			cfg.size = data->cio2_.sensor()->resolution();
+			cfg = data->cio2_.generateConfiguration(sensorResolution);
 
-			cfg = data->cio2_.generateConfiguration(cfg.size);
 			break;
 		}
 
 		case StreamRole::Viewfinder:
 		case StreamRole::VideoRecording: {
 			/*
-			 * We can't use the 'output' stream for viewfinder or
-			 * video capture roles.
-			 *
-			 * \todo This is an artificial limitation until we
-			 * figure out the exact capabilities of the hardware.
+			 * Default viewfinder and videorecording to 1280x720,
+			 * capped to the maximum sensor resolution and aligned
+			 * to the ImgU output constraints.
 			 */
-			if (streams.find(&data->vfStream_) == streams.end()) {
-				LOG(IPU3, Error)
-					<< "No stream available for requested role "
-					<< role;
-				break;
-			}
-
-			stream = &data->vfStream_;
-
-			/*
-			 * Align the default viewfinder size to the maximum
-			 * available sensor resolution and to the IPU3
-			 * alignment constraints.
-			 */
-			const Size &res = data->cio2_.sensor()->resolution();
-			unsigned int width = std::min(1280U, res.width);
-			unsigned int height = std::min(720U, res.height);
-			cfg.size = { width & ~7, height & ~3 };
+			cfg.size = sensorResolution.boundedTo({ 1280, 720 })
+						   .alignedDownTo(IMGU_OUTPUT_WIDTH_ALIGN,
+							          IMGU_OUTPUT_HEIGHT_ALIGN);
+			cfg.pixelFormat = formats::NV12;
+			cfg.bufferCount = IPU3_BUFFER_COUNT;
 
 			break;
 		}
@@ -394,16 +355,10 @@  CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,
 		default:
 			LOG(IPU3, Error)
 				<< "Requested stream role not supported: " << role;
-			break;
-		}
-
-		if (!stream) {
 			delete config;
 			return nullptr;
 		}
 
-		streams.erase(stream);
-
 		config->addConfiguration(cfg);
 	}