diff options
-rw-r--r-- | src/libcamera/pipeline/raspberrypi/raspberrypi.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 168bbcef..49d7ff23 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -272,6 +272,12 @@ public: unsigned int dropFrameCount_; + /* + * If set, this stores the value that represets a gain of one for + * the V4L2_CID_NOTIFY_GAINS control. + */ + std::optional<int32_t> notifyGainsUnity_; + private: void checkRequestCompleted(); void fillRequestMetadata(const ControlList &bufferControls, @@ -1249,6 +1255,15 @@ int PipelineHandlerRPi::registerCamera(MediaDevice *unicam, MediaDevice *isp, Me data->properties_ = data->sensor_->properties(); /* + * The V4L2_CID_NOTIFY_GAINS control, if present, is used to inform the + * sensor of the colour gains. It is defined to be a linear gain where + * the default value represents a gain of exactly one. + */ + auto it = data->sensor_->controls().find(V4L2_CID_NOTIFY_GAINS); + if (it != data->sensor_->controls().end()) + data->notifyGainsUnity_ = it->second.def().get<int32_t>(); + + /* * Set a default value for the ScalerCropMaximum property to show * that we support its use, however, initialise it to zero because * it's not meaningful until a camera mode has been chosen. @@ -1644,6 +1659,25 @@ void RPiCameraData::statsMetadataComplete(uint32_t bufferId, const ControlList & Request *request = requestQueue_.front(); request->metadata().merge(controls); + /* + * Inform the sensor of the latest colour gains if it has the + * V4L2_CID_NOTIFY_GAINS control (which means notifyGainsUnity_ is set). + */ + if (notifyGainsUnity_ && controls.contains(libcamera::controls::ColourGains)) { + libcamera::Span<const float> colourGains = controls.get(libcamera::controls::ColourGains); + /* The control wants linear gains in the order B, Gb, Gr, R. */ + ControlList ctrls(sensor_->controls()); + std::array<int32_t, 4> gains{ + static_cast<int32_t>(colourGains[1] * *notifyGainsUnity_), + *notifyGainsUnity_, + *notifyGainsUnity_, + static_cast<int32_t>(colourGains[0] * *notifyGainsUnity_) + }; + ctrls.set(V4L2_CID_NOTIFY_GAINS, Span<const int32_t>{ gains }); + + sensor_->setControls(&ctrls); + } + state_ = State::IpaComplete; handleState(); } |