[v3,07/16] libcamera: delayed_controls: Add controlsAreQueued() helper
diff mbox series

Message ID 20240319120517.362082-8-stefan.klug@ideasonboard.com
State New
Headers show
Series
  • Preparation for per-frame-controls and initial tests
Related show

Commit Message

Stefan Klug March 19, 2024, 12:05 p.m. UTC
This gets used in the upcoming patches to decide if controls need to be queued
for a later frame, or if the controls can be skipped because they are already
queued.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
---
 include/libcamera/internal/delayed_controls.h |  2 ++
 src/libcamera/delayed_controls.cpp            | 34 +++++++++++++++++++
 2 files changed, 36 insertions(+)

Patch
diff mbox series

diff --git a/include/libcamera/internal/delayed_controls.h b/include/libcamera/internal/delayed_controls.h
index 0e28106a..ccbe7239 100644
--- a/include/libcamera/internal/delayed_controls.h
+++ b/include/libcamera/internal/delayed_controls.h
@@ -67,6 +67,8 @@  private:
 		}
 	};
 
+	bool controlsAreQueued(unsigned int frame, const ControlList &controls);
+
 	V4L2Device *device_;
 	/* \todo Evaluate if we should index on ControlId * or unsigned int */
 	std::unordered_map<const ControlId *, ControlParams> controlParams_;
diff --git a/src/libcamera/delayed_controls.cpp b/src/libcamera/delayed_controls.cpp
index 86571cd4..6c766ede 100644
--- a/src/libcamera/delayed_controls.cpp
+++ b/src/libcamera/delayed_controls.cpp
@@ -137,6 +137,40 @@  void DelayedControls::reset()
 	}
 }
 
+/**
+ * \brief Helper function to check if controls are already queued
+ * \param[in] sequence Sequence number to check
+ * \param[in] controls List of controls to compare against
+ *
+ * This function checks if the controls queued for frame \a sequence
+ * are equal to \a controls. This is helpful in cases where a control algorithm
+ * unconditionally queues controls for every frame, but always too late.
+ * In that case this can be used to check if incoming controls are already
+ * queued or need to be queued for a later frame.
+ *
+ * \returns true if \a controls are queued for the given sequence
+ */
+bool DelayedControls::controlsAreQueued(unsigned int sequence,
+					const ControlList &controls)
+{
+	const ControlIdMap &idmap = device_->controls().idmap();
+	for (const auto &[id, value] : controls) {
+		const auto &it = idmap.find(id);
+		if (it == idmap.end()) {
+			LOG(DelayedControls, Warning)
+				<< "Unknown control " << id;
+			return false;
+		}
+
+		const ControlId *ctrlId = it->second;
+
+		if (values_[ctrlId][sequence] != value)
+			return false;
+	}
+
+	return true;
+}
+
 /**
  * \brief Push a set of controls on the queue
  * \param[in] controls List of controls to add to the device queue