[libcamera-devel] [PATCH v4 5/7] libcamera: raspberrypi: Set camera flips correctly from user transform

David Plowman david.plowman at raspberrypi.com
Fri Aug 28 16:41:08 CEST 2020


The Raspberry Pi pipeline handler allows all transforms except those
involving a transpose. The user transform is combined with any
inherent rotation of the camera, and the camera's H and V flip bits
are set accordingly.

Signed-off-by: David Plowman <david.plowman at raspberrypi.com>
---
 .../pipeline/raspberrypi/raspberrypi.cpp      | 42 +++++++++++++++----
 1 file changed, 34 insertions(+), 8 deletions(-)

diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
index dc36f53..6ea1432 100644
--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
@@ -400,20 +400,46 @@ CameraConfiguration::Status RPiCameraConfiguration::validate()
 	if (config_.empty())
 		return Invalid;
 
-	if (transform != Transform::Identity) {
-		transform = Transform::Identity;
+	/*
+	 * What if the platform has a non-90 degree rotation? We can't even
+	 * "adjust" the configuration and carry on. Alternatively, raising an
+	 * error means the platform can never run. Let's just print a warning
+	 * and continue regardless; the rotation is effectively set to zero.
+	 */
+	int32_t rotation = data_->sensor_->properties().get(properties::Rotation);
+	bool success;
+	Transform combined = transform * transformFromRotation(rotation, &success);
+	if (!success)
+		LOG(RPI, Warning) << "Invalid rotation of " << rotation
+				  << " degrees - ignoring";
+
+	/*
+	 * We combine the platform and user transform, but must "adjust away"
+	 * any combined result that includes a transform, as we can't do those.
+	 * In this case, flipping only the transpose bit is helpful to
+	 * applications - they either get the transform they requested, or have
+	 * to do a simple transpose themselves (they don't have to worry about
+	 * the other possible cases).
+	 */
+	if (!!(combined & Transform::Transpose)) {
+		/*
+		 * Flipping the transpose bit in "transform" flips it in
+		 * combined result too (as it's the last thing that happens).
+		 */
+		transform ^= Transform::Transpose;
+		combined ^= Transform::Transpose;
 		status = Adjusted;
 	}
 
 	/*
-	 * Configure the H/V flip controls based on the sensor rotation. We do
-	 * this here so that the sensor has the correct Bayer format that will
-	 * get advertised in the configuration of any raw streams.
+	 * Configure the H/V flip controls based on the combination of the
+	 * sensor rotation and the user transform. We do this here so that the
+	 * sensor has the correct Bayer format that will get advertised in the
+	 * configuration of any raw streams.
 	 */
 	ControlList ctrls(data_->unicam_[Unicam::Image].dev()->controls());
-	int32_t rotation = data_->sensor_->properties().get(properties::Rotation);
-	ctrls.set(V4L2_CID_HFLIP, static_cast<int32_t>(!!rotation));
-	ctrls.set(V4L2_CID_VFLIP, static_cast<int32_t>(!!rotation));
+	ctrls.set(V4L2_CID_HFLIP, static_cast<int32_t>(!!(combined & Transform::HFlip)));
+	ctrls.set(V4L2_CID_VFLIP, static_cast<int32_t>(!!(combined & Transform::VFlip)));
 	data_->unicam_[Unicam::Image].dev()->setControls(&ctrls);
 
 	unsigned int rawCount = 0, outCount = 0, count = 0, maxIndex = 0;
-- 
2.20.1



More information about the libcamera-devel mailing list