@@ -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_;
@@ -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;
@@ -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 */
@@ -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";
@@ -1041,6 +1046,34 @@ Transform CameraSensor::computeTransform(Orientation *orientation) const
return transform;
}
+/**
+ * \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
*