[libcamera-devel] [PATCH v3 3/5] libcamera: raspberrypi: Set camera flips correctly from user transform
David Plowman
david.plowman at raspberrypi.com
Fri Aug 21 17:56:39 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 | 34 ++++++++++++++++---
1 file changed, 30 insertions(+), 4 deletions(-)
diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
index 236aa5c..a3f8438 100644
--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
@@ -324,6 +324,8 @@ public:
uint32_t expectedSequence_;
bool sensorMetadata_;
+ Transform transform_;
+
/*
* All the functions in this class are called from a single calling
* thread. So, we do not need to have any mutex to protect access to any
@@ -400,8 +402,27 @@ 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.
+ * Flipping the transpose bit in either input transform causes the
+ * corresponding bit in the combined result to flip.
+ */
+ if (!!(combined & Transform::Transpose)) {
+ transform ^= Transform::Transpose;
status = Adjusted;
}
@@ -610,6 +631,9 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config)
for (auto const stream : data->streams_)
stream->reset();
+ /* We will want to know the transform requested by the application. */
+ data->transform_ = config->transform;
+
Size maxSize, sensorSize;
unsigned int maxIndex = 0;
bool rawStream = false;
@@ -1174,8 +1198,10 @@ int RPiCameraData::configureIPA()
/* Configure the H/V flip controls based on the sensor rotation. */
ControlList ctrls(unicam_[Unicam::Image].dev()->controls());
int32_t rotation = 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));
+ /* The rotation was already checked in RPiCameraConfiguration::validate. */
+ Transform combined = transform_ * transformFromRotation(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)));
unicam_[Unicam::Image].dev()->setControls(&ctrls);
}
--
2.20.1
More information about the libcamera-devel
mailing list