[libcamera-devel] [PATCH v3 08/23] libcamera: camera_sensor: Initialize controls
Kieran Bingham
kieran.bingham at ideasonboard.com
Fri Jul 1 00:57:19 CEST 2022
Quoting Jacopo Mondi via libcamera-devel (2022-06-30 14:38:47)
> Initialize the control interface of the CameraSensor class by
> registering the control limits for controls::internal::ExposureTime,
> controls::internal::FrameDuration and controls::internal::AnalogueGain.
>
> Update the CameraSensor controls in the CameraSensor::updateControlInfo()
> function after having updated the subdevice V4L2 controls.
>
> Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
> ---
> include/libcamera/internal/camera_sensor.h | 3 +
> src/libcamera/camera_sensor/camera_sensor.cpp | 90 +++++++++++++++++++
> 2 files changed, 93 insertions(+)
>
> diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h
> index 2a850dedc0aa..1eab5e9d53f0 100644
> --- a/include/libcamera/internal/camera_sensor.h
> +++ b/include/libcamera/internal/camera_sensor.h
> @@ -63,6 +63,7 @@ public:
> V4L2Subdevice *device() { return subdev_.get(); }
>
> const ControlList &properties() const { return properties_; }
> + const ControlInfoMap &controls() const { return controls_; }
> int sensorInfo(IPACameraSensorInfo *info) const;
>
> void updateControlInfo();
> @@ -81,6 +82,7 @@ private:
> void initStaticProperties();
> void initTestPatternModes();
> int initProperties();
> + int updateControls();
> int applyTestPatternMode(controls::draft::TestPatternModeEnum mode);
> int discoverAncillaryDevices();
>
> @@ -104,6 +106,7 @@ private:
> const BayerFormat *bayerFormat_;
>
> ControlList properties_;
> + ControlInfoMap controls_;
>
> std::unique_ptr<CameraLens> focusLens_;
> std::unique_ptr<CameraSensorHelper> helper_;
> diff --git a/src/libcamera/camera_sensor/camera_sensor.cpp b/src/libcamera/camera_sensor/camera_sensor.cpp
> index 26cfa7d0f65a..976d34aaf876 100644
> --- a/src/libcamera/camera_sensor/camera_sensor.cpp
> +++ b/src/libcamera/camera_sensor/camera_sensor.cpp
> @@ -22,6 +22,7 @@
> #include "libcamera/internal/bayer_format.h"
> #include "libcamera/internal/camera_lens.h"
> #include "libcamera/internal/camera_sensor_properties.h"
> +#include "libcamera/internal/control_ids.h"
> #include "libcamera/internal/formats.h"
> #include "libcamera/internal/sysfs.h"
>
> @@ -180,6 +181,10 @@ int CameraSensor::init()
> return -ENODEV;
> }
>
> + ret = updateControls();
> + if (ret)
> + return ret;
> +
> ret = discoverAncillaryDevices();
> if (ret)
> return ret;
> @@ -455,6 +460,84 @@ int CameraSensor::initProperties()
> return 0;
> }
>
> +int CameraSensor::updateControls()
> +{
> + if (!bayerFormat_)
> + return 0;
> +
> + ControlInfoMap::Map controlsMap;
> +
> + /* The subdev driver has been validate already, the controls are there! */
/validate/validated/
> + ControlList subdevControls = subdev_->getControls({ V4L2_CID_PIXEL_RATE,
> + V4L2_CID_HBLANK });
> + uint64_t pixelRate = subdevControls.get(V4L2_CID_PIXEL_RATE).get<int64_t>();
> + uint32_t hblank = subdevControls.get(V4L2_CID_HBLANK).get<int32_t>();
> +
> + /* Assume the sensor has a single source pad #0. */
/* Assume/* Assume/
double space can be single.
> + V4L2SubdeviceFormat subdevFormat;
> + subdev_->getFormat(0, &subdevFormat);
> +
> + const ControlInfoMap &subdevControlsInfo = subdev_->controls();
> +
> + /*
> + * Compute controls::ExposureTime limits by using line length and pixel
> + * rate converted to microseconds. Use the V4L2_CID_EXPOSURE control to
> + * get exposure min, max and default and convert it from lines to
> + * microseconds.
> + */
> + uint32_t lineLength = subdevFormat.size.width + hblank;
> + double lineDuration = lineLength / (pixelRate / 1000000.0F);
> + const ControlInfo &v4l2Exposure = subdevControlsInfo.at(V4L2_CID_EXPOSURE);
> + int32_t minExposure = v4l2Exposure.min().get<int32_t>() * lineDuration;
> + int32_t maxExposure = v4l2Exposure.max().get<int32_t>() * lineDuration;
> + int32_t defExposure = v4l2Exposure.def().get<int32_t>() * lineDuration;
> +
> + controlsMap[&controls::internal::ExposureTime] =
> + ControlInfo(minExposure, maxExposure, defExposure);
> +
> + /*
> + * Compute the frame duration limits.
> + *
> + * The frame length is computed assuming a fixed line length combined
> + * with the vertical frame sizes.
> + */
> + const ControlInfo &v4l2VBlank = subdevControlsInfo.at(V4L2_CID_VBLANK);
Does this need to be refreshed from the subdev?
> + std::array<uint32_t, 3> frameHeights{
> + v4l2VBlank.min().get<int32_t>() + subdevFormat.size.height,
> + v4l2VBlank.max().get<int32_t>() + subdevFormat.size.height,
> + v4l2VBlank.def().get<int32_t>() + subdevFormat.size.height,
> + };
> +
> + std::array<int64_t, 3> frameDurations;
> + for (unsigned int i = 0; i < frameHeights.size(); ++i) {
> + uint64_t frameSize = lineLength * frameHeights[i];
> + frameDurations[i] = frameSize / (pixelRate / 1000000.0F);
> + }
> +
> + controlsMap[&controls::internal::FrameDuration] =
> + ControlInfo(frameDurations[0], frameDurations[1], frameDurations[2]);
> +
> + /*
> + * Analogue gain values.
> + *
> + * Translate the V4L2 analogue gain, expressed in sensor-specific
> + * gain codes, and translate them to analogue gain values.
> + *
> + * \todo: CameraSensorHelper returns a double; there's no ControlValue
> + * overload for the double type.
> + */
> + const ControlInfo &v4l2AGain = subdevControlsInfo.at(V4L2_CID_ANALOGUE_GAIN);
> + controlsMap[&controls::internal::AnalogueGain] =
> + ControlInfo(static_cast<float>(helper_->gain(v4l2AGain.min().get<int32_t>())),
> + static_cast<float>(helper_->gain(v4l2AGain.max().get<int32_t>())),
> + static_cast<float>(helper_->gain(v4l2AGain.def().get<int32_t>())));
> +
> + controls_ = ControlInfoMap(std::move(controlsMap),
> + controls::internal::controls);
> +
> + return 0;
> +}
> +
> /**
> * \brief Check for and initialise any ancillary devices
> *
> @@ -815,6 +898,12 @@ int CameraSensor::setV4L2Controls(ControlList *ctrls)
> * \return The list of camera sensor properties
> */
>
> +/**
> + * \fn CameraSensor::controls()
> + * \brief Retrieve the map of the camera sensor controls limits
> + * \return The map of camera sensor control information
> + */
> +
> /**
> * \brief Assemble and return the camera sensor info
> * \param[out] info The camera sensor info
> @@ -910,6 +999,7 @@ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const
> void CameraSensor::updateControlInfo()
> {
> subdev_->updateControlInfo();
> + updateControls();
Aha - that answers my vblank question I think...
Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> }
>
> /**
> --
> 2.36.1
>
More information about the libcamera-devel
mailing list