summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2024-02-28 14:40:13 +0200
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2024-03-15 13:00:58 +0200
commit284919ef2e509d8109b84eedcc6d5c2f78cddbef (patch)
treed3bd55984e7b6bbf445dd73f5943ff0fcf1b54c8
parent58bcddbdeb7e7b40ba8e7eecc2fad385d85f23ce (diff)
libcamera: camera_sensor: Expose the Bayer order
Pipeline handlers may need to know the Bayer order produced by the sensor when a Transform is applied (horizontal or vertical flip). This is currently implemented manually in the Raspberry Pi pipeline handler. Move the implementation to the CameraSensor class to make it usable in other pipeline handlers. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
-rw-r--r--include/libcamera/internal/camera_sensor.h4
-rw-r--r--src/libcamera/pipeline/rpi/common/pipeline_base.cpp54
-rw-r--r--src/libcamera/pipeline/rpi/common/pipeline_base.h6
-rw-r--r--src/libcamera/sensor/camera_sensor.cpp37
4 files changed, 45 insertions, 56 deletions
diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h
index 750d6d72..d05f48eb 100644
--- a/include/libcamera/internal/camera_sensor.h
+++ b/include/libcamera/internal/camera_sensor.h
@@ -22,12 +22,12 @@
#include <libcamera/ipa/core_ipa_interface.h>
+#include "libcamera/internal/bayer_format.h"
#include "libcamera/internal/formats.h"
#include "libcamera/internal/v4l2_subdevice.h"
namespace libcamera {
-class BayerFormat;
class CameraLens;
class MediaEntity;
class SensorConfiguration;
@@ -69,6 +69,7 @@ public:
const ControlList &properties() const { return properties_; }
int sensorInfo(IPACameraSensorInfo *info) const;
Transform computeTransform(Orientation *orientation) const;
+ BayerFormat::Order bayerOrder(Transform t) const;
const ControlInfoMap &controls() const;
ControlList getControls(const std::vector<uint32_t> &ids);
@@ -114,6 +115,7 @@ private:
Rectangle activeArea_;
const BayerFormat *bayerFormat_;
bool supportFlips_;
+ bool flipsAlterBayerOrder_;
Orientation mountingOrientation_;
ControlList properties_;
diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
index 9449c3dc..7e420b3f 100644
--- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
+++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
@@ -235,24 +235,16 @@ CameraConfiguration::Status RPiCameraConfiguration::validate()
for (auto &raw : rawStreams_) {
StreamConfiguration *rawStream = raw.cfg;
- /* Adjust the RAW stream to match the computed sensor format. */
- BayerFormat sensorBayer = BayerFormat::fromMbusCode(sensorFormat_.code);
-
/*
- * Some sensors change their Bayer order when they are h-flipped
- * or v-flipped, according to the transform. If this one does, we
- * must advertise the transformed Bayer order in the raw stream.
- * Note how we must fetch the "native" (i.e. untransformed) Bayer
- * order, because the sensor may currently be flipped!
+ * Some sensors change their Bayer order when they are
+ * h-flipped or v-flipped, according to the transform. Adjust
+ * the RAW stream to match the computed sensor format by
+ * applying the sensor Bayer order resulting from the transform
+ * to the user request.
*/
- if (data_->flipsAlterBayerOrder_) {
- sensorBayer.order = data_->nativeBayerOrder_;
- sensorBayer = sensorBayer.transform(combinedTransform_);
- }
- /* Apply the sensor adjusted Bayer order to the user request. */
BayerFormat cfgBayer = BayerFormat::fromPixelFormat(rawStream->pixelFormat);
- cfgBayer.order = sensorBayer.order;
+ cfgBayer.order = data_->sensor_->bayerOrder(combinedTransform_);
if (rawStream->pixelFormat != cfgBayer.toPixelFormat()) {
rawStream->pixelFormat = cfgBayer.toPixelFormat();
@@ -840,40 +832,6 @@ int PipelineHandlerBase::registerCamera(std::unique_ptr<RPi::CameraData> &camera
*/
data->properties_.set(properties::ScalerCropMaximum, Rectangle{});
- /*
- * We cache two things about the sensor in relation to transforms
- * (meaning horizontal and vertical flips): if they affect the Bayer
- * ordering, and what the "native" Bayer order is, when no transforms
- * are applied.
- *
- * If flips are supported verify if they affect the Bayer ordering
- * and what the "native" Bayer order is, when no transforms are
- * applied.
- *
- * We note that the sensor's cached list of supported formats is
- * already in the "native" order, with any flips having been undone.
- */
- const V4L2Subdevice *sensor = data->sensor_->device();
- const struct v4l2_query_ext_ctrl *hflipCtrl = sensor->controlInfo(V4L2_CID_HFLIP);
- if (hflipCtrl) {
- /* We assume it will support vflips too... */
- data->flipsAlterBayerOrder_ = hflipCtrl->flags & V4L2_CTRL_FLAG_MODIFY_LAYOUT;
- }
-
- /* Look for a valid Bayer format. */
- BayerFormat bayerFormat;
- for (const auto &iter : data->sensorFormats_) {
- bayerFormat = BayerFormat::fromMbusCode(iter.first);
- if (bayerFormat.isValid())
- break;
- }
-
- if (!bayerFormat.isValid()) {
- LOG(RPI, Error) << "No Bayer format found";
- return -EINVAL;
- }
- data->nativeBayerOrder_ = bayerFormat.order;
-
ret = platformRegister(cameraData, frontend, backend);
if (ret)
return ret;
diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h
index 267eef11..0608bbe5 100644
--- a/src/libcamera/pipeline/rpi/common/pipeline_base.h
+++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h
@@ -48,7 +48,7 @@ class CameraData : public Camera::Private
public:
CameraData(PipelineHandler *pipe)
: Camera::Private(pipe), state_(State::Stopped),
- flipsAlterBayerOrder_(false), dropFrameCount_(0), buffersAllocated_(false),
+ dropFrameCount_(0), buffersAllocated_(false),
ispOutputCount_(0), ispOutputTotal_(0)
{
}
@@ -131,10 +131,6 @@ public:
std::queue<Request *> requestQueue_;
- /* Store the "native" Bayer order (that is, with no transforms applied). */
- bool flipsAlterBayerOrder_;
- BayerFormat::Order nativeBayerOrder_;
-
/* For handling digital zoom. */
IPACameraSensorInfo sensorInfo_;
Rectangle ispCrop_; /* crop in ISP (camera mode) pixels */
diff --git a/src/libcamera/sensor/camera_sensor.cpp b/src/libcamera/sensor/camera_sensor.cpp
index 40202556..5c4f3532 100644
--- a/src/libcamera/sensor/camera_sensor.cpp
+++ b/src/libcamera/sensor/camera_sensor.cpp
@@ -58,7 +58,7 @@ LOG_DEFINE_CATEGORY(CameraSensor)
CameraSensor::CameraSensor(const MediaEntity *entity)
: entity_(entity), pad_(UINT_MAX), staticProps_(nullptr),
bayerFormat_(nullptr), supportFlips_(false),
- properties_(properties::properties)
+ flipsAlterBayerOrder_(false), properties_(properties::properties)
{
}
@@ -271,9 +271,14 @@ int CameraSensor::validateSensorDriver()
const struct v4l2_query_ext_ctrl *hflipInfo = subdev_->controlInfo(V4L2_CID_HFLIP);
const struct v4l2_query_ext_ctrl *vflipInfo = subdev_->controlInfo(V4L2_CID_VFLIP);
if (hflipInfo && !(hflipInfo->flags & V4L2_CTRL_FLAG_READ_ONLY) &&
- vflipInfo && !(vflipInfo->flags & V4L2_CTRL_FLAG_READ_ONLY))
+ vflipInfo && !(vflipInfo->flags & V4L2_CTRL_FLAG_READ_ONLY)) {
supportFlips_ = true;
+ if (hflipInfo->flags & V4L2_CTRL_FLAG_MODIFY_LAYOUT ||
+ vflipInfo->flags & V4L2_CTRL_FLAG_MODIFY_LAYOUT)
+ flipsAlterBayerOrder_ = true;
+ }
+
if (!supportFlips_)
LOG(CameraSensor, Debug)
<< "Camera sensor does not support horizontal/vertical flip";
@@ -1042,6 +1047,34 @@ Transform CameraSensor::computeTransform(Orientation *orientation) const
}
/**
+ * \brief Compute the Bayer order that results from the given Transform
+ * \param[in] t The Transform to apply to the sensor
+ *
+ * Some sensors change their Bayer order when they are h-flipped or v-flipped.
+ * This function computes and returns the Bayer order that would result from the
+ * given transform applied to the sensor.
+ *
+ * This function is valid only when the sensor produces raw Bayer formats.
+ *
+ * \return The Bayer order produced by the sensor when the Transform is applied
+ */
+BayerFormat::Order CameraSensor::bayerOrder(Transform t) const
+{
+ /* Return a defined by meaningless value for non-Bayer sensors. */
+ if (!bayerFormat_)
+ return BayerFormat::Order::BGGR;
+
+ if (!flipsAlterBayerOrder_)
+ return bayerFormat_->order;
+
+ /*
+ * Apply the transform to the native (i.e. untransformed) Bayer order,
+ * using the rest of the Bayer format supplied by the caller.
+ */
+ return bayerFormat_->transform(t).order;
+}
+
+/**
* \brief Retrieve the supported V4L2 controls and their information
*
* Control information is updated automatically to reflect the current sensor