summaryrefslogtreecommitdiff
path: root/src/libcamera/camera_sensor.cpp
diff options
context:
space:
mode:
authorJacopo Mondi <jacopo.mondi@ideasonboard.com>2022-11-24 10:10:26 +0100
committerJacopo Mondi <jacopo.mondi@ideasonboard.com>2023-01-30 11:04:29 +0100
commit1a614866a29ce1e3c185d72975ad9fc37c4f99bd (patch)
tree0b550b5af3f9e7d307485d9b867cb5ded4846eed /src/libcamera/camera_sensor.cpp
parente030bac39027cc960727ec3db99a68fcb01e0b2a (diff)
libcamera: camera_sensor: Validate Transform
The two pipeline handlers that currently support Transform (IPU3 and RaspberryPi) implement it by operating H/V flips on the image sensor. Centralize the code that validates a Transform request against the sensor rotation capabilities in the CameraSensor class. The implementation in the IPU3 pipeline handler was copied from the RaspberryPi implementation, and is now centralized in CameraSensor to make it easier for other platforms. The CameraSensor::validateTransform() implementation comes directly from the RaspberryPi pipeline handler, no functional changes intended. Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Diffstat (limited to 'src/libcamera/camera_sensor.cpp')
-rw-r--r--src/libcamera/camera_sensor.cpp72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
index 83ac075a..a8668547 100644
--- a/src/libcamera/camera_sensor.cpp
+++ b/src/libcamera/camera_sensor.cpp
@@ -16,6 +16,7 @@
#include <string.h>
#include <libcamera/property_ids.h>
+#include <libcamera/transform.h>
#include <libcamera/base/utils.h>
@@ -962,6 +963,77 @@ void CameraSensor::updateControlInfo()
* connected to the sensor
*/
+/**
+ * \brief Validate a transform request against the sensor capabilities
+ * \param[inout] transform The requested transformation, updated to match
+ * the sensor capabilities
+ *
+ * The input \a transform is the transform that the caller wants, and it is
+ * adjusted according to the capabilities of the sensor to represent the
+ * "nearest" transform that can actually be delivered.
+ *
+ * The returned Transform is the transform applied to the sensor in order to
+ * produce the input \a transform, It is also validated against the sensor's
+ * ability to perform horizontal and vertical flips.
+ *
+ * For example, if the requested \a transform is Transform::Identity and the
+ * sensor rotation is 180 degrees, the output transform will be
+ * Transform::Rot180 to correct the images so that they appear to have
+ * Transform::Identity, but only if the sensor can apply horizontal and vertical
+ * flips.
+ *
+ * \return A Transform instance that represents which transformation has been
+ * applied to the camera sensor
+ */
+Transform CameraSensor::validateTransform(Transform *transform) const
+{
+ /* Adjust the requested transform to compensate the sensor rotation. */
+ int32_t rotation = properties().get(properties::Rotation).value_or(0);
+ bool success;
+
+ Transform rotationTransform = transformFromRotation(rotation, &success);
+ if (!success)
+ LOG(CameraSensor, Warning) << "Invalid rotation of " << rotation
+ << " degrees - ignoring";
+
+ Transform combined = *transform * rotationTransform;
+
+ /*
+ * 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 the
+ * combined result too (as it's the last thing that happens),
+ * which is of course clearing it.
+ */
+ *transform ^= Transform::Transpose;
+ combined &= ~Transform::Transpose;
+ }
+
+ /*
+ * We also check if the sensor doesn't do h/vflips at all, in which
+ * case we clear them, and the application will have to do everything.
+ */
+ if (!supportFlips_ && !!combined) {
+ /*
+ * If the sensor can do no transforms, then combined must be
+ * changed to the identity. The only user transform that gives
+ * rise to this is the inverse of the rotation. (Recall that
+ * combined = transform * rotationTransform.)
+ */
+ *transform = -rotationTransform;
+ combined = Transform::Identity;
+ }
+
+ return combined;
+}
+
std::string CameraSensor::logPrefix() const
{
return "'" + entity_->name() + "'";