[v1,21/33] libcamera: converter_dw100: Use vertex map
diff mbox series

Message ID 20250930122726.1837524-22-stefan.klug@ideasonboard.com
State New
Headers show
Series
  • Full dewarper support on imx8mp
Related show

Commit Message

Stefan Klug Sept. 30, 2025, 12:26 p.m. UTC
Use the new vertexmap class in the dw100 dewarper implementation.

As the dw100 kernel driver does not use the requests API, controls can
not be tied to a buffer. In the case that the dewarper has buffers
queued for which processing has not yet started, applying the dewarp map
would apply to an already queued buffer. Warn when this situation
occurs.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>

---

Changes in v0.9:
- Include requests support

Changes in v0.8:
- Added warning when queue is not empty
---
 .../internal/converter/converter_dw100.h      | 19 +++++++
 .../internal/converter/converter_v4l2_m2m.h   |  4 +-
 src/libcamera/converter/converter_dw100.cpp   | 56 +++++++++++++++++++
 3 files changed, 77 insertions(+), 2 deletions(-)

Patch
diff mbox series

diff --git a/include/libcamera/internal/converter/converter_dw100.h b/include/libcamera/internal/converter/converter_dw100.h
index deb0125a0dbc..dabd442fcc98 100644
--- a/include/libcamera/internal/converter/converter_dw100.h
+++ b/include/libcamera/internal/converter/converter_dw100.h
@@ -7,6 +7,7 @@ 
 
 #pragma once
 
+#include "libcamera/internal/converter/converter_dw100_vertexmap.h"
 #include "libcamera/internal/converter/converter_v4l2_m2m.h"
 
 namespace libcamera {
@@ -20,7 +21,25 @@  class ConverterDW100 : public V4L2M2MConverter
 public:
 	ConverterDW100(std::shared_ptr<MediaDevice> media);
 
+	int applyVertexMap(const Stream *stream, const V4L2Request *request = nullptr);
+	Dw100VertexMap &vertexMap(const Stream *stream);
+
 	void validateSize(Size *size) const;
+
+private:
+	std::unique_ptr<V4L2M2MStream> makeStream(const Stream *stream) override;
+	class DW100Stream : public V4L2M2MConverter::V4L2M2MStream
+	{
+	public:
+		DW100Stream(V4L2M2MConverter *converter, const Stream *stream);
+
+		int configure(const StreamConfiguration &inputCfg,
+			      const StreamConfiguration &outputCfg) override;
+
+		int applyVertexMap(const V4L2Request *request = nullptr);
+
+		Dw100VertexMap vertexMap_;
+	};
 };
 
 } /* namespace libcamera */
diff --git a/include/libcamera/internal/converter/converter_v4l2_m2m.h b/include/libcamera/internal/converter/converter_v4l2_m2m.h
index 033c4ba42292..41b4fcc4c853 100644
--- a/include/libcamera/internal/converter/converter_v4l2_m2m.h
+++ b/include/libcamera/internal/converter/converter_v4l2_m2m.h
@@ -89,8 +89,8 @@  protected:
 
 		bool isValid() const { return m2m_ != nullptr; }
 
-		int configure(const StreamConfiguration &inputCfg,
-			      const StreamConfiguration &outputCfg);
+		virtual int configure(const StreamConfiguration &inputCfg,
+				      const StreamConfiguration &outputCfg);
 		int exportBuffers(unsigned int count,
 				  std::vector<std::unique_ptr<FrameBuffer>> *buffers);
 
diff --git a/src/libcamera/converter/converter_dw100.cpp b/src/libcamera/converter/converter_dw100.cpp
index da1d88214a6e..994b31d44d47 100644
--- a/src/libcamera/converter/converter_dw100.cpp
+++ b/src/libcamera/converter/converter_dw100.cpp
@@ -7,9 +7,12 @@ 
 
 #include "libcamera/internal/converter/converter_dw100.h"
 
+#include <linux/dw100.h>
+
 #include <libcamera/base/log.h>
 
 #include <libcamera/geometry.h>
+#include <libcamera/stream.h>
 
 #include "libcamera/internal/media_device.h"
 #include "libcamera/internal/v4l2_videodevice.h"
@@ -34,10 +37,63 @@  ConverterDW100::ConverterDW100(std::shared_ptr<MediaDevice> media)
 {
 }
 
+int ConverterDW100::applyVertexMap(const Stream *stream, const V4L2Request *request)
+{
+	auto iter = streams_.find(stream);
+	if (iter == streams_.end())
+		return -EINVAL;
+
+	return dynamic_cast<DW100Stream *>(iter->second.get())->applyVertexMap(request);
+}
+
+Dw100VertexMap &ConverterDW100::vertexMap(const Stream *stream)
+{
+	auto iter = streams_.find(stream);
+	V4L2M2MConverter::V4L2M2MStream *s = iter->second.get();
+	ASSERT(s);
+	return dynamic_cast<DW100Stream *>(s)->vertexMap_;
+}
+
 void ConverterDW100::validateSize(Size *size) const
 {
 	if (size)
 		size->alignDownTo(8, 8);
 }
 
+std::unique_ptr<V4L2M2MConverter::V4L2M2MStream> ConverterDW100::makeStream(const Stream *stream)
+{
+	return std::unique_ptr<V4L2M2MConverter::V4L2M2MStream>(new DW100Stream(this, stream));
+}
+
+ConverterDW100::DW100Stream::DW100Stream(V4L2M2MConverter *converter,
+					 const Stream *stream)
+	: V4L2M2MConverter::V4L2M2MStream(converter, stream)
+{
+}
+
+int ConverterDW100::DW100Stream::configure(const StreamConfiguration &inputCfg,
+					   const StreamConfiguration &outputCfg)
+{
+	int ret;
+	ret = V4L2M2MConverter::V4L2M2MStream::configure(inputCfg, outputCfg);
+	if (ret)
+		return ret;
+
+	/* Todo: is that comment still valid?
+	 For actual dewarping we need the active area of the sensor mode here. */
+	vertexMap_.setInputSize(inputCfg.size);
+	vertexMap_.setOutputSize(outputCfg.size);
+	return 0;
+}
+
+int ConverterDW100::DW100Stream::applyVertexMap(const V4L2Request *request)
+{
+	std::vector<uint32_t> map = vertexMap_.getVertexMap();
+	auto value = Span<const int32_t>(reinterpret_cast<const int32_t *>(&map[0]), map.size());
+
+	ControlList ctrls;
+	ctrls.set(V4L2_CID_DW100_DEWARPING_16x16_VERTEX_MAP, value);
+	return applyControls(ctrls, request);
+}
+
 } /* namespace libcamera */