[libcamera-devel,v5,3/8] libcamera: raspberrypi: Switch to DelayedControls
diff mbox series

Message ID 20210116114805.905397-4-niklas.soderlund@ragnatech.se
State Accepted
Delegated to: Niklas Söderlund
Headers show
Series
  • libcamera: Add helper for controls that take effect with a delay
Related show

Commit Message

Niklas Söderlund Jan. 16, 2021, 11:48 a.m. UTC
Use the libcamera core helper DelayedControls instead of the local
StaggeredCtrl. The new helper is modeled after the StaggeredCtrl
implementation and behaves the same.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
* Changes since v4
- Rename IPA_ACTION_V4L2_SET_STAGGERED to IPA_ACTION_SET_DELAYED_CTRLS.
- Optimize copy of controls in PipelineHandlerRPi::start().
- Update comments and an error message.
---
 include/libcamera/ipa/raspberrypi.h           |  2 +-
 src/ipa/raspberrypi/raspberrypi.cpp           |  2 +-
 .../pipeline/raspberrypi/raspberrypi.cpp      | 57 ++++++++-----------
 3 files changed, 27 insertions(+), 34 deletions(-)

Patch
diff mbox series

diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h
index 01fe5abce9a6072c..c0516cbe786a1636 100644
--- a/include/libcamera/ipa/raspberrypi.h
+++ b/include/libcamera/ipa/raspberrypi.h
@@ -26,7 +26,7 @@  enum ConfigParameters {
 };
 
 enum Operations {
-	IPA_ACTION_V4L2_SET_STAGGERED = 1,
+	IPA_ACTION_SET_DELAYED_CTRLS = 1,
 	IPA_ACTION_V4L2_SET_ISP,
 	IPA_ACTION_STATS_METADATA_COMPLETE,
 	IPA_ACTION_RUN_ISP,
diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp
index 8af3d603a3ff64b9..2d8fd793654e402c 100644
--- a/src/ipa/raspberrypi/raspberrypi.cpp
+++ b/src/ipa/raspberrypi/raspberrypi.cpp
@@ -944,7 +944,7 @@  void IPARPi::processStats(unsigned int bufferId)
 		applyAGC(&agcStatus, ctrls);
 
 		IPAOperationData op;
-		op.operation = RPi::IPA_ACTION_V4L2_SET_STAGGERED;
+		op.operation = RPi::IPA_ACTION_SET_DELAYED_CTRLS;
 		op.controls.emplace_back(ctrls);
 		queueFrameAction.emit(0, op);
 	}
diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
index f121328ee9a9b6f2..3613671aded0a8fd 100644
--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
@@ -27,6 +27,7 @@ 
 #include "libcamera/internal/bayer_format.h"
 #include "libcamera/internal/buffer.h"
 #include "libcamera/internal/camera_sensor.h"
+#include "libcamera/internal/delayed_controls.h"
 #include "libcamera/internal/device_enumerator.h"
 #include "libcamera/internal/ipa_manager.h"
 #include "libcamera/internal/media_device.h"
@@ -37,7 +38,6 @@ 
 
 #include "dma_heaps.h"
 #include "rpi_stream.h"
-#include "staggered_ctrl.h"
 
 namespace libcamera {
 
@@ -178,8 +178,7 @@  public:
 	RPi::DmaHeap dmaHeap_;
 	FileDescriptor lsTable_;
 
-	RPi::StaggeredCtrl staggeredCtrl_;
-	uint32_t expectedSequence_;
+	std::unique_ptr<DelayedControls> delayedCtrls_;
 	bool sensorMetadata_;
 
 	/*
@@ -766,11 +765,9 @@  int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *cont
 	}
 
 	/* Apply any gain/exposure settings that the IPA may have passed back. */
-	ASSERT(data->staggeredCtrl_);
 	if (result.operation & RPi::IPA_CONFIG_SENSOR) {
-		const ControlList &ctrls = result.controls[0];
-		if (!data->staggeredCtrl_.set(ctrls))
-			LOG(RPI, Error) << "V4L2 staggered set failed";
+		ControlList &ctrls = result.controls[0];
+		data->unicam_[Unicam::Image].dev()->setControls(&ctrls);
 	}
 
 	if (result.operation & RPi::IPA_CONFIG_DROP_FRAMES) {
@@ -802,13 +799,10 @@  int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *cont
 	data->unicam_[Unicam::Image].dev()->setFrameStartEnabled(true);
 
 	/*
-	 * Write the last set of gain and exposure values to the camera before
-	 * starting. First check that the staggered ctrl has been initialised
-	 * by configure().
+	 * Reset the delayed controls with the gain and exposure values set by
+	 * the IPA.
 	 */
-	data->staggeredCtrl_.reset();
-	data->staggeredCtrl_.write();
-	data->expectedSequence_ = 0;
+	data->delayedCtrls_->reset();
 
 	data->state_ = RPiCameraData::State::Idle;
 
@@ -1147,7 +1141,7 @@  void RPiCameraData::frameStarted(uint32_t sequence)
 	LOG(RPI, Debug) << "frame start " << sequence;
 
 	/* Write any controls for the next frame as soon as we can. */
-	staggeredCtrl_.write();
+	delayedCtrls_->applyControls(sequence);
 }
 
 int RPiCameraData::loadIPA()
@@ -1227,21 +1221,24 @@  int RPiCameraData::configureIPA(const CameraConfiguration *config)
 	unsigned int resultIdx = 0;
 	if (result.operation & RPi::IPA_CONFIG_STAGGERED_WRITE) {
 		/*
-		 * Setup our staggered control writer with the sensor default
+		 * Setup our delayed control writer with the sensor default
 		 * gain and exposure delays.
 		 */
-		if (!staggeredCtrl_) {
-			staggeredCtrl_.init(unicam_[Unicam::Image].dev(),
-					    { { V4L2_CID_ANALOGUE_GAIN, result.data[resultIdx++] },
-					      { V4L2_CID_EXPOSURE, result.data[resultIdx++] } });
+		if (!delayedCtrls_) {
+			std::unordered_map<uint32_t, unsigned int> delays = {
+				{ V4L2_CID_ANALOGUE_GAIN, result.data[resultIdx++] },
+				{ V4L2_CID_EXPOSURE, result.data[resultIdx++] }
+			};
+
+			delayedCtrls_ = std::make_unique<DelayedControls>(unicam_[Unicam::Image].dev(), delays);
+
 			sensorMetadata_ = result.data[resultIdx++];
 		}
 	}
 
 	if (result.operation & RPi::IPA_CONFIG_SENSOR) {
-		const ControlList &ctrls = result.controls[0];
-		if (!staggeredCtrl_.set(ctrls))
-			LOG(RPI, Error) << "V4L2 staggered set failed";
+		ControlList &ctrls = result.controls[0];
+		unicam_[Unicam::Image].dev()->setControls(&ctrls);
 	}
 
 	/*
@@ -1268,10 +1265,10 @@  void RPiCameraData::queueFrameAction([[maybe_unused]] unsigned int frame,
 	 * a stopped state.
 	 */
 	switch (action.operation) {
-	case RPi::IPA_ACTION_V4L2_SET_STAGGERED: {
+	case RPi::IPA_ACTION_SET_DELAYED_CTRLS: {
 		const ControlList &controls = action.controls[0];
-		if (!staggeredCtrl_.set(controls))
-			LOG(RPI, Error) << "V4L2 staggered set failed";
+		if (!delayedCtrls_->push(controls))
+			LOG(RPI, Error) << "Failed to set delayed controls";
 		goto done;
 	}
 
@@ -1375,11 +1372,7 @@  void RPiCameraData::unicamBufferDequeue(FrameBuffer *buffer)
 	} else {
 		embeddedQueue_.push(buffer);
 
-		std::unordered_map<uint32_t, int32_t> ctrl;
-		int offset = buffer->metadata().sequence - expectedSequence_;
-		staggeredCtrl_.get(ctrl, offset);
-
-		expectedSequence_ = buffer->metadata().sequence + 1;
+		ControlList ctrl = delayedCtrls_->get(buffer->metadata().sequence);
 
 		/*
 		 * Sensor metadata is unavailable, so put the expected ctrl
@@ -1391,8 +1384,8 @@  void RPiCameraData::unicamBufferDequeue(FrameBuffer *buffer)
 			auto it = mappedEmbeddedBuffers_.find(bufferId);
 			if (it != mappedEmbeddedBuffers_.end()) {
 				uint32_t *mem = reinterpret_cast<uint32_t *>(it->second.maps()[0].data());
-				mem[0] = ctrl[V4L2_CID_EXPOSURE];
-				mem[1] = ctrl[V4L2_CID_ANALOGUE_GAIN];
+				mem[0] = ctrl.get(V4L2_CID_EXPOSURE).get<int32_t>();
+				mem[1] = ctrl.get(V4L2_CID_ANALOGUE_GAIN).get<int32_t>();
 			} else {
 				LOG(RPI, Warning) << "Failed to find embedded buffer "
 						  << bufferId;