[libcamera-devel] [PATCH 1/5] libcamera: camera_sensor: Validate driver support
paul.elder at ideasonboard.com
paul.elder at ideasonboard.com
Mon Dec 28 09:22:04 CET 2020
Hi Jacopo,
On Wed, Dec 23, 2020 at 07:45:12PM +0100, Jacopo Mondi wrote:
> The CameraSensor class requires the sensor driver to report
> information through V4L2 controls and through the V4L2 selection API,
> and uses those information to register Camera properties and to
> construct CameraSensorInfo class instances to provide them to the IPA.
>
> Currently, validation of the kernel support happens each time a
> feature is requested, with slighly similar debug/error messages
> output to the user in case a feature is not supported.
>
> Rationalize this by:
> - Validate the sensor driver requirements in a single function
> - Expand the debug output when a property gets defaulted to a value
> - Be more verbose when constructing CameraSensorInfo is not possible
>
> Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
Reviewed-by: Paul Elder <paul.elder at ideasonboard.com>
> ---
> include/libcamera/internal/camera_sensor.h | 1 +
> src/libcamera/camera_sensor.cpp | 106 +++++++++++++++++++--
> 2 files changed, 100 insertions(+), 7 deletions(-)
>
> diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h
> index f80d836161a5..aee10aa6e3c7 100644
> --- a/include/libcamera/internal/camera_sensor.h
> +++ b/include/libcamera/internal/camera_sensor.h
> @@ -69,6 +69,7 @@ protected:
>
> private:
> int generateId();
> + int validateSensorDriver();
> int initProperties();
>
> const MediaEntity *entity_;
> diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
> index bdf4415fda0e..3a65ac3de5bc 100644
> --- a/src/libcamera/camera_sensor.cpp
> +++ b/src/libcamera/camera_sensor.cpp
> @@ -207,6 +207,10 @@ int CameraSensor::init()
> */
> resolution_ = sizes_.back();
>
> + ret = validateSensorDriver();
> + if (ret)
> + return ret;
> +
> ret = initProperties();
> if (ret)
> return ret;
> @@ -214,6 +218,81 @@ int CameraSensor::init()
> return 0;
> }
>
> +int CameraSensor::validateSensorDriver()
> +{
> + /*
> + * Make sure the sensor driver supports the mandatory controls
> + * required by the CameraSensor class.
> + * - V4L2_CID_PIXEL_RATE is used to calculate the sensor timings
> + * - V4L2_CID_HBLANK is used to calculate the line length
> + */
> + const std::vector<uint32_t> mandatoryControls{
> + V4L2_CID_PIXEL_RATE,
> + V4L2_CID_HBLANK,
> + };
> +
> + ControlList ctrls = subdev_->getControls(mandatoryControls);
> + if (ctrls.empty()) {
> + LOG(CameraSensor, Error)
> + << "Mandatory V4L2 controls not available";
> + LOG(CameraSensor, Error)
> + << "Please consider upgrading the sensor driver";
> + return -EINVAL;
> + }
> +
> + int err = 0;
> + /*
> + * Optional controls are used to register optional sensor
> + * properties. If not present, some values will be defaulted.
> + */
> + const std::vector<uint32_t> optionalControls{
> + V4L2_CID_CAMERA_ORIENTATION,
> + V4L2_CID_CAMERA_SENSOR_ROTATION,
> + };
> +
> + ctrls = subdev_->getControls(optionalControls);
> + if (ctrls.empty()) {
> + LOG(CameraSensor, Info)
> + << "Optional V4L2 controls not supported";
> + err = -EINVAL;
> + }
> +
> + /*
> + * Make sure the required selection targets are supported.
> + *
> + * Failures in reading any of the targets are not deemed to be fatal,
> + * but some properties and features, like constructing a
> + * CameraSensorInfo for the IPA module, won't be supported.
> + */
> + Rectangle rect;
> + int ret = subdev_->getSelection(pad_, V4L2_SEL_TGT_CROP_BOUNDS, &rect);
> + if (ret) {
> + LOG(CameraSensor, Info)
> + << "Failed to retrieve the readable pixel area size";
> + err = -EINVAL;
> + }
> +
> + ret = subdev_->getSelection(pad_, V4L2_SEL_TGT_CROP_DEFAULT, &rect);
> + if (ret) {
> + LOG(CameraSensor, Info)
> + << "Failed to retrieve the active pixel area size";
> + err = -EINVAL;
> + }
> +
> + ret = subdev_->getSelection(pad_, V4L2_SEL_TGT_CROP, &rect);
> + if (ret) {
> + LOG(CameraSensor, Info)
> + << "Failed to retreive the sensor crop rectangle";
> + err = -EINVAL;
> + }
> +
> + if (err)
> + LOG(CameraSensor, Info)
> + << "Please consider upgrading the sensor driver";
> +
> + return 0;
> +}
> +
> int CameraSensor::initProperties()
> {
> /*
> @@ -278,21 +357,29 @@ int CameraSensor::initProperties()
> }
> } else {
> propertyValue = properties::CameraLocationFront;
> + LOG(CameraSensor, Debug)
> + << "Location property defaulted to 'Front Camera'";
> }
> properties_.set(properties::Location, propertyValue);
>
> /* Camera Rotation: default is 0 degrees. */
> const auto &rotationControl = controls.find(V4L2_CID_CAMERA_SENSOR_ROTATION);
> - if (rotationControl != controls.end())
> + if (rotationControl != controls.end()) {
> propertyValue = rotationControl->second.def().get<int32_t>();
> - else
> + } else {
> propertyValue = 0;
> + LOG(CameraSensor, Debug)
> + << "Rotation property defaulted to 0 degrees";
> + }
> properties_.set(properties::Rotation, propertyValue);
>
> Rectangle bounds;
> ret = subdev_->getSelection(pad_, V4L2_SEL_TGT_CROP_BOUNDS, &bounds);
> if (!ret)
> properties_.set(properties::PixelArraySize, bounds.size());
> + else
> + LOG(CameraSensor, Debug)
> + << "PixelArraySize property not registered";
>
> Rectangle crop;
> ret = subdev_->getSelection(pad_, V4L2_SEL_TGT_CROP_DEFAULT, &crop);
> @@ -306,6 +393,9 @@ int CameraSensor::initProperties()
> crop.x -= bounds.x;
> crop.y -= bounds.y;
> properties_.set(properties::PixelArrayActiveAreas, { crop });
> + } else {
> + LOG(CameraSensor, Debug)
> + << "PixelArrayActiveAreas property not registered";
> }
>
> /* Color filter array pattern, register only for RAW sensors. */
> @@ -571,6 +661,8 @@ int CameraSensor::sensorInfo(CameraSensorInfo *info) const
> LOG(CameraSensor, Error)
> << "Failed to construct camera sensor info: "
> << "the camera sensor does not report the active area";
> + LOG(CameraSensor, Error)
> + << "The IPA might not work correctly";
>
> return ret;
> }
> @@ -582,6 +674,8 @@ int CameraSensor::sensorInfo(CameraSensorInfo *info) const
> LOG(CameraSensor, Error)
> << "Failed to construct camera sensor info: "
> << "the camera sensor does not report the crop rectangle";
> + LOG(CameraSensor, Error)
> + << "The IPA might not work correctly";
> return ret;
> }
>
> @@ -603,16 +697,14 @@ int CameraSensor::sensorInfo(CameraSensorInfo *info) const
> info->bitsPerPixel = format.bitsPerPixel();
> info->outputSize = format.size;
>
> - /*
> - * Retrieve the pixel rate and the line length through V4L2 controls.
> - * Support for the V4L2_CID_PIXEL_RATE and V4L2_CID_HBLANK controls is
> - * mandatory.
> - */
> + /* Retrieve the pixel rate and the line length through V4L2 controls. */
> ControlList ctrls = subdev_->getControls({ V4L2_CID_PIXEL_RATE,
> V4L2_CID_HBLANK });
> if (ctrls.empty()) {
> LOG(CameraSensor, Error)
> << "Failed to retrieve camera info controls";
> + LOG(CameraSensor, Error)
> + << "The IPA might not work correctly";
> return -EINVAL;
> }
>
> --
> 2.29.2
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
More information about the libcamera-devel
mailing list