[libcamera-devel] [PATCH v3 1/2] libcamera: camera_sensor: Fix frame lengths calculated by sensorInfo()
Kieran Bingham
kieran.bingham at ideasonboard.com
Wed May 5 16:13:49 CEST 2021
On 05/05/2021 14:54, David Plowman wrote:
> Hi
>
> On Wed, 5 May 2021 at 14:53, David Plowman
> <david.plowman at raspberrypi.com> wrote:
>>
>> The minimum and maximum vblanking can change when a new format is
>> applied to the sensor subdevice, so be sure to retrieve up-to-date
>> values.
>>
>> The V4L2Device acquires the new updateControlInfo() method to perform
>> this function, and which the CameraSensor calls automatically if its
>> setFormat method is used to update the sensor.
>>
>> However, not all pipeline handlers invoke the setFormat method
>> directly, so the new method must be made publicly available for
>> pipeline handlers to call if they need to.
>>
>> Signed-off-by: David Plowman <david.plowman at raspberrypi.com>
>> Reviewed-by: Jacopo Mondi <jacopo at jmondi.org>
>> Reviewed-by: Kieran Bingham <kieran.bingham at raspberrypi.com>
>
> Oops, typo here! Sorry Kieran. Can that be fixed up while applying please?
That depends, When will I receive my salary from RPi ;-)
(Otherwise, yes I think so :D)
--
Kieran
>
> Thanks
> David
>
>> ---
>> include/libcamera/internal/camera_sensor.h | 2 ++
>> include/libcamera/internal/v4l2_device.h | 2 ++
>> src/libcamera/camera_sensor.cpp | 32 ++++++++++++++++++-
>> src/libcamera/v4l2_device.cpp | 37 ++++++++++++++++++++++
>> 4 files changed, 72 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h
>> index 3e98f71b..6ce513b7 100644
>> --- a/include/libcamera/internal/camera_sensor.h
>> +++ b/include/libcamera/internal/camera_sensor.h
>> @@ -68,6 +68,8 @@ public:
>> const ControlList &properties() const { return properties_; }
>> int sensorInfo(CameraSensorInfo *info) const;
>>
>> + void updateControlInfo();
>> +
>> protected:
>> std::string logPrefix() const override;
>>
>> diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h
>> index 087f07e7..5ba9b23b 100644
>> --- a/include/libcamera/internal/v4l2_device.h
>> +++ b/include/libcamera/internal/v4l2_device.h
>> @@ -42,6 +42,8 @@ public:
>> int setFrameStartEnabled(bool enable);
>> Signal<uint32_t> frameStart;
>>
>> + void updateControlInfo();
>> +
>> protected:
>> V4L2Device(const std::string &deviceNode);
>> ~V4L2Device();
>> diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
>> index 2887bb69..322678c8 100644
>> --- a/src/libcamera/camera_sensor.cpp
>> +++ b/src/libcamera/camera_sensor.cpp
>> @@ -656,15 +656,30 @@ V4L2SubdeviceFormat CameraSensor::getFormat(const std::vector<unsigned int> &mbu
>> /**
>> * \brief Set the sensor output format
>> * \param[in] format The desired sensor output format
>> + *
>> + * The ranges of any controls associated with the sensor are also updated.
>> + *
>> * \return 0 on success or a negative error code otherwise
>> */
>> int CameraSensor::setFormat(V4L2SubdeviceFormat *format)
>> {
>> - return subdev_->setFormat(pad_, format);
>> + int ret = subdev_->setFormat(pad_, format);
>> + if (ret)
>> + return ret;
>> +
>> + updateControlInfo();
>> + return 0;
>> }
>>
>> /**
>> * \brief Retrieve the supported V4L2 controls and their information
>> + *
>> + * Control information is updated automatically to reflect the current sensor
>> + * configuration when the setFormat() function is called, without invalidating
>> + * any iterator on the ControlInfoMap. A manual update can also be forced by
>> + * calling the updateControlInfo() function for pipeline handlers that change
>> + * the sensor configuration wihtout using setFormat().
>> + *
>> * \return A map of the V4L2 controls supported by the sensor
>> */
>> const ControlInfoMap &CameraSensor::controls() const
>> @@ -750,6 +765,11 @@ int CameraSensor::setControls(ControlList *ctrls)
>> * Sensor information is only available for raw sensors. When called for a YUV
>> * sensor, this function returns -EINVAL.
>> *
>> + * Pipeline handlers that do not change the sensor format using the
>> + * CameraSensor::setFormat method may need to call
>> + * CameraSensor::updateControlInfo beforehand, to ensure all the control
>> + * ranges are up to date.
>> + *
>> * \return 0 on success, a negative error code otherwise
>> */
>> int CameraSensor::sensorInfo(CameraSensorInfo *info) const
>> @@ -821,6 +841,16 @@ int CameraSensor::sensorInfo(CameraSensorInfo *info) const
>> return 0;
>> }
>>
>> +/**
>> + * \fn void CameraSensor::updateControlInfo()
>> + * \brief Update the sensor's ControlInfoMap in case they have changed
>> + * \sa V4L2Device::updateControlInfo()
>> + */
>> +void CameraSensor::updateControlInfo()
>> +{
>> + subdev_->updateControlInfo();
>> +}
>> +
>> std::string CameraSensor::logPrefix() const
>> {
>> return "'" + entity_->name() + "'";
>> diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp
>> index 397029ac..515cbdfe 100644
>> --- a/src/libcamera/v4l2_device.cpp
>> +++ b/src/libcamera/v4l2_device.cpp
>> @@ -511,6 +511,43 @@ void V4L2Device::listControls()
>> controls_ = std::move(ctrls);
>> }
>>
>> +/**
>> +* \brief Update the information for all device controls
>> + *
>> + * The V4L2Device class caches information about all controls supported by the
>> + * device and exposes it through the controls() and controlInfo() functions.
>> + * Control information may change at runtime, for instance when formats on a
>> + * subdev are modified. When this occurs, this function can be used to refresh
>> + * control information. The information is refreshed in-place, all pointers to
>> + * v4l2_query_ext_ctrl instances previously returned by controlInfo() and
>> + * iterators to the ControlInfoMap returned by controls() remain valid.
>> + *
>> + * Note that control information isn't refreshed automatically is it may be an
>> + * expensive operation. The V4L2Device users are responsible for calling this
>> + * function when required, based on their usage pattern of the class.
>> + */
>> +void V4L2Device::updateControlInfo()
>> +{
>> + for (auto &[controlId, info] : controls_) {
>> + unsigned int id = controlId->id();
>> +
>> + /*
>> + * Assume controlInfo_ has a corresponding entry, as it has been
>> + * generated by listControls().
>> + */
>> + struct v4l2_query_ext_ctrl &ctrl = controlInfo_[id];
>> +
>> + if (ioctl(VIDIOC_QUERY_EXT_CTRL, &ctrl)) {
>> + LOG(V4L2, Debug)
>> + << "Could not refresh control "
>> + << utils::hex(id);
>> + continue;
>> + }
>> +
>> + info = V4L2ControlInfo(ctrl);
>> + }
>> +}
>> +
>> /*
>> * \brief Update the value of the first \a count V4L2 controls in \a ctrls using
>> * values in \a v4l2Ctrls
>> --
>> 2.20.1
>>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
>
--
Regards
--
Kieran
More information about the libcamera-devel
mailing list