[libcamera-devel] [PATCH 1/1] libcamera: camera_sensor: Fix frame lengths calculated by sensorInfo()

David Plowman david.plowman at raspberrypi.com
Tue Mar 30 18:57:43 CEST 2021


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 refreshControls() method to perform
this function. Note that not all pipeline handlers invoke the
subdevice's setFormat method directly, so the new method must be made
publicly available.

Signed-off-by: David Plowman <david.plowman at raspberrypi.com>
---
 include/libcamera/internal/v4l2_device.h |  2 ++
 src/libcamera/camera_sensor.cpp          |  7 +++++++
 src/libcamera/v4l2_device.cpp            | 26 ++++++++++++++++++++++++
 3 files changed, 35 insertions(+)

diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h
index d006bf68..6efcb0db 100644
--- a/include/libcamera/internal/v4l2_device.h
+++ b/include/libcamera/internal/v4l2_device.h
@@ -41,6 +41,8 @@ public:
 	int setFrameStartEnabled(bool enable);
 	Signal<uint32_t> frameStart;
 
+	void refreshControls();
+
 protected:
 	V4L2Device(const std::string &deviceNode);
 	~V4L2Device();
diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
index f7ed91d9..9f99ce3e 100644
--- a/src/libcamera/camera_sensor.cpp
+++ b/src/libcamera/camera_sensor.cpp
@@ -796,6 +796,13 @@ int CameraSensor::sensorInfo(CameraSensorInfo *info) const
 	info->bitsPerPixel = format.bitsPerPixel();
 	info->outputSize = format.size;
 
+	/*
+	 * Some controls, specifically the vblanking, may have different min
+	 * or max values if the sensor format has been changed since it was
+	 * opened, so be sure to update them first.
+	 */
+	subdev_->refreshControls();
+
 	/*
 	 * Retrieve the pixel rate, line length and minimum/maximum frame
 	 * duration through V4L2 controls. Support for the V4L2_CID_PIXEL_RATE,
diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp
index decd19ef..6d396f89 100644
--- a/src/libcamera/v4l2_device.cpp
+++ b/src/libcamera/v4l2_device.cpp
@@ -514,6 +514,32 @@ void V4L2Device::listControls()
 	controls_ = std::move(ctrls);
 }
 
+/*
+ * \brief Update the control information that was previously stored by
+ * listControls(). Some parts of this information, such as min and max
+ * values of some controls, are liable to change when a new format is set.
+ */
+void V4L2Device::refreshControls()
+{
+	for (auto &controlId : controlIds_) {
+		unsigned int id = controlId->id();
+
+		struct v4l2_query_ext_ctrl ctrl = {};
+		ctrl.id = id;
+
+		if (ioctl(VIDIOC_QUERY_EXT_CTRL, &ctrl)) {
+			LOG(V4L2, Debug)
+				<< "Could not refresh control "
+				<< utils::hex(ctrl.id);
+			continue;
+		}
+
+		/* Assume these are present - listControls() made them. */
+		controlInfo_[id] = ctrl;
+		controls_.at(controlId.get()) = V4L2ControlInfo(ctrl);
+	}
+}
+
 /*
  * \brief Update the value of the first \a count V4L2 controls in \a ctrls using
  * values in \a v4l2Ctrls
-- 
2.20.1



More information about the libcamera-devel mailing list