diff options
-rw-r--r-- | include/libcamera/internal/camera_sensor.h | 4 | ||||
-rw-r--r-- | src/libcamera/pipeline/rpi/common/pipeline_base.cpp | 54 | ||||
-rw-r--r-- | src/libcamera/pipeline/rpi/common/pipeline_base.h | 6 | ||||
-rw-r--r-- | src/libcamera/sensor/camera_sensor.cpp | 37 |
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 |