diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2024-02-28 14:40:13 +0200 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2024-03-15 13:00:58 +0200 |
commit | 284919ef2e509d8109b84eedcc6d5c2f78cddbef (patch) | |
tree | d3bd55984e7b6bbf445dd73f5943ff0fcf1b54c8 /src | |
parent | 58bcddbdeb7e7b40ba8e7eecc2fad385d85f23ce (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>
Diffstat (limited to 'src')
-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 |
3 files changed, 42 insertions, 55 deletions
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 |