[v3,28/29] DNI libcamera: rkisp1: Implement dw100 specific features
diff mbox series

Message ID 20251125162851.2301793-29-stefan.klug@ideasonboard.com
State Superseded
Headers show
Series
  • Full dewarper support on imx8mp
Related show

Commit Message

Stefan Klug Nov. 25, 2025, 4:28 p.m. UTC
The dw100 allows more features implemented in the dw100 vertex map.
Implement these features for the rkisp1 pipeline.

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

---

Changes in v3:
- Move control handling from pipeline handler to the converter
  class
- Moved controls into core namespace

Changes in v2:
- Marked as DoNotIntegrate because the puplic interface needs further
  discussions
- Added Dw100EffectiveScale metadata
---
 .../converter/converter_dw100_vertexmap.h     |  2 +-
 src/libcamera/control_ids_core.yaml           | 50 +++++++++++++++++++
 src/libcamera/converter/converter_dw100.cpp   | 36 +++++++++++++
 3 files changed, 87 insertions(+), 1 deletion(-)

Comments

Kieran Bingham Nov. 25, 2025, 5:57 p.m. UTC | #1
Quoting Stefan Klug (2025-11-25 16:28:40)
> The dw100 allows more features implemented in the dw100 vertex map.
> Implement these features for the rkisp1 pipeline.
> 
> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
> 
> ---
> 
> Changes in v3:
> - Move control handling from pipeline handler to the converter
>   class
> - Moved controls into core namespace

Now that these are managed entirely in the dw100 component, I would
wonder if these can have a dw100 control namespace.

Unless we can generalise them for core...

But if they were in controls::dw100:: I'd think this patch could lose
it's DNI and be merged ....


> 
> Changes in v2:
> - Marked as DoNotIntegrate because the puplic interface needs further
>   discussions
> - Added Dw100EffectiveScale metadata
> ---
>  .../converter/converter_dw100_vertexmap.h     |  2 +-
>  src/libcamera/control_ids_core.yaml           | 50 +++++++++++++++++++
>  src/libcamera/converter/converter_dw100.cpp   | 36 +++++++++++++
>  3 files changed, 87 insertions(+), 1 deletion(-)
> 
> diff --git a/include/libcamera/internal/converter/converter_dw100_vertexmap.h b/include/libcamera/internal/converter/converter_dw100_vertexmap.h
> index 49ecc81678a0..f79274a6098a 100644
> --- a/include/libcamera/internal/converter/converter_dw100_vertexmap.h
> +++ b/include/libcamera/internal/converter/converter_dw100_vertexmap.h
> @@ -42,7 +42,7 @@ public:
>         const Transform &transform() const { return transform_; }
>  
>         void setScale(const float scale) { scale_ = scale; }
> -       float effectiveScale() const { return (effectiveScaleX_ + effectiveScaleY_) * 0.5; }
> +       std::array<float, 2> effectiveScale() const { return { static_cast<float>(effectiveScaleX_), static_cast<float>(effectiveScaleY_) }; }
>  
>         void setRotation(const float rotation) { rotation_ = rotation; }
>         float rotation() const { return rotation_; }
> diff --git a/src/libcamera/control_ids_core.yaml b/src/libcamera/control_ids_core.yaml
> index 3bcb475fd102..e03b570282ba 100644
> --- a/src/libcamera/control_ids_core.yaml
> +++ b/src/libcamera/control_ids_core.yaml
> @@ -1353,4 +1353,54 @@ controls:
>          Enable or disable lens dewarping. This control is only available if lens
>          dewarp parameters are configured in the tuning file.
>  
> +  - Dw100ScaleMode:
> +      type: int32_t
> +      direction: inout
> +      description: |
> +        Scale mode of the dewarper.
> +      enum:
> +        - name: Dw100ScaleModeFill
> +          value: 0
> +          description: |
> +            Fills the given output size with the largest rectangle possible.
> +            Aspect ratio is not preserved. Dw100Scale is ignored.
> +        - name: Dw100ScaleModeCrop
> +          value: 1
> +          description: |
> +            Crops to the given output size. The scale factor can be specified
> +            using Dw100Scale. Aspect ratio is preserved.
> +
> +  - Dw100Scale:
> +      type: float
> +      direction: inout
> +      description: |
> +        Scale factor applied to the image when Dw100ScaleMode is set to Crop.
> +        This value is clamped, so that all pixels have valid input data.
> +        Therefore a value of 0 always provides the largest possible field of
> +        view. Scaling happens centered around the center of the ScalerCrop +
> +        Dw10Offset.
> +
> +  - Dw100Rotation:
> +      type: float
> +      direction: inout
> +      description: |
> +        Rotates the image by the given angle in degrees in clockwise direction
> +        around the center of ScalerCrop + Dw100Offset
> +
> +  - Dw100Offset:
> +      type: Point
> +      direction: inout
> +      description: |
> +        Moves the image by the given values in x and y direction in sensor
> +        coordinate space. This is clamped, so that all output pixels contain
> +        valid data. The offset is therefore ignored when the Dw100Scale value is
> +        too small.
> +
> +  - Dw100EffectiveScale:
> +      type: float
> +      direction: out
> +      description: |
> +        Effective scale
> +      size: [2]
> +
>  ...
> diff --git a/src/libcamera/converter/converter_dw100.cpp b/src/libcamera/converter/converter_dw100.cpp
> index 7adad1b502f0..b39e4ab23cd6 100644
> --- a/src/libcamera/converter/converter_dw100.cpp
> +++ b/src/libcamera/converter/converter_dw100.cpp
> @@ -346,6 +346,13 @@ void ConverterDW100Module::updateControlInfos(const Stream *stream, ControlInfoM
>         if (dewarpParams_.has_value())
>                 controls[&controls::LensDewarpEnable] = ControlInfo(false, true, true);
>  
> +       controls[&controls::Dw100Scale] = ControlInfo(0.2f, 8.0f, 1.0f);
> +       controls[&controls::Dw100Rotation] = ControlInfo(-180.0f, 180.0f, 0.0f);
> +       controls[&controls::Dw100Offset] =
> +               ControlInfo(Point(-10000, -10000), Point(10000, 10000), Point(0, 0));
> +       controls[&controls::Dw100ScaleMode] =
> +               ControlInfo(controls::Dw100ScaleModeValues, controls::Dw100ScaleModeFill);
> +
>         if (!converter_.supportsRequests())
>                 LOG(Converter, Warning)
>                         << "dw100 kernel driver has no requests support."
> @@ -369,6 +376,30 @@ void ConverterDW100Module::setControls(const Stream *stream, const ControlList &
>         auto &info = vertexMaps_[stream];
>         auto &vertexMap = info.map;
>  
> +       const auto &scale = controls.get(controls::Dw100Scale);
> +       if (scale) {
> +               vertexMap.setScale(*scale);
> +               info.update = true;
> +       }
> +
> +       const auto &rotation = controls.get(controls::Dw100Rotation);
> +       if (rotation) {
> +               vertexMap.setRotation(*rotation);
> +               info.update = true;
> +       }
> +
> +       const auto &offset = controls.get(controls::Dw100Offset);
> +       if (offset) {
> +               vertexMap.setOffset(*offset);
> +               info.update = true;
> +       }
> +
> +       const auto &scaleMode = controls.get(controls::Dw100ScaleMode);
> +       if (scaleMode) {
> +               vertexMap.setMode(static_cast<Dw100VertexMap::ScaleMode>(*scaleMode));
> +               info.update = true;
> +       }
> +
>         const auto &lensDewarpEnable = controls.get(controls::LensDewarpEnable);
>         if (lensDewarpEnable) {
>                 vertexMap.setLensDewarpEnable(*lensDewarpEnable);
> @@ -402,6 +433,11 @@ void ConverterDW100Module::populateMetadata(const Stream *stream, ControlList &m
>  
>         auto &vertexMap = vertexMaps_[stream].map;
>  
> +       std::array<float, 2> effectiveScale = vertexMap.effectiveScale();
> +       meta.set(controls::Dw100EffectiveScale, effectiveScale);
> +       meta.set(controls::Dw100Scale, (effectiveScale[0] + effectiveScale[1]) / 2.0);
> +       meta.set(controls::Dw100Rotation, vertexMap.rotation());
> +       meta.set(controls::Dw100Offset, vertexMap.effectiveOffset());
>         meta.set(controls::ScalerCrop, vertexMap.effectiveScalerCrop());
>  
>         if (dewarpParams_.has_value())
> -- 
> 2.51.0
>

Patch
diff mbox series

diff --git a/include/libcamera/internal/converter/converter_dw100_vertexmap.h b/include/libcamera/internal/converter/converter_dw100_vertexmap.h
index 49ecc81678a0..f79274a6098a 100644
--- a/include/libcamera/internal/converter/converter_dw100_vertexmap.h
+++ b/include/libcamera/internal/converter/converter_dw100_vertexmap.h
@@ -42,7 +42,7 @@  public:
 	const Transform &transform() const { return transform_; }
 
 	void setScale(const float scale) { scale_ = scale; }
-	float effectiveScale() const { return (effectiveScaleX_ + effectiveScaleY_) * 0.5; }
+	std::array<float, 2> effectiveScale() const { return { static_cast<float>(effectiveScaleX_), static_cast<float>(effectiveScaleY_) }; }
 
 	void setRotation(const float rotation) { rotation_ = rotation; }
 	float rotation() const { return rotation_; }
diff --git a/src/libcamera/control_ids_core.yaml b/src/libcamera/control_ids_core.yaml
index 3bcb475fd102..e03b570282ba 100644
--- a/src/libcamera/control_ids_core.yaml
+++ b/src/libcamera/control_ids_core.yaml
@@ -1353,4 +1353,54 @@  controls:
         Enable or disable lens dewarping. This control is only available if lens
         dewarp parameters are configured in the tuning file.
 
+  - Dw100ScaleMode:
+      type: int32_t
+      direction: inout
+      description: |
+        Scale mode of the dewarper.
+      enum:
+        - name: Dw100ScaleModeFill
+          value: 0
+          description: |
+            Fills the given output size with the largest rectangle possible.
+            Aspect ratio is not preserved. Dw100Scale is ignored.
+        - name: Dw100ScaleModeCrop
+          value: 1
+          description: |
+            Crops to the given output size. The scale factor can be specified
+            using Dw100Scale. Aspect ratio is preserved.
+
+  - Dw100Scale:
+      type: float
+      direction: inout
+      description: |
+        Scale factor applied to the image when Dw100ScaleMode is set to Crop.
+        This value is clamped, so that all pixels have valid input data.
+        Therefore a value of 0 always provides the largest possible field of
+        view. Scaling happens centered around the center of the ScalerCrop +
+        Dw10Offset.
+
+  - Dw100Rotation:
+      type: float
+      direction: inout
+      description: |
+        Rotates the image by the given angle in degrees in clockwise direction
+        around the center of ScalerCrop + Dw100Offset
+
+  - Dw100Offset:
+      type: Point
+      direction: inout
+      description: |
+        Moves the image by the given values in x and y direction in sensor
+        coordinate space. This is clamped, so that all output pixels contain
+        valid data. The offset is therefore ignored when the Dw100Scale value is
+        too small.
+
+  - Dw100EffectiveScale:
+      type: float
+      direction: out
+      description: |
+        Effective scale
+      size: [2]
+
 ...
diff --git a/src/libcamera/converter/converter_dw100.cpp b/src/libcamera/converter/converter_dw100.cpp
index 7adad1b502f0..b39e4ab23cd6 100644
--- a/src/libcamera/converter/converter_dw100.cpp
+++ b/src/libcamera/converter/converter_dw100.cpp
@@ -346,6 +346,13 @@  void ConverterDW100Module::updateControlInfos(const Stream *stream, ControlInfoM
 	if (dewarpParams_.has_value())
 		controls[&controls::LensDewarpEnable] = ControlInfo(false, true, true);
 
+	controls[&controls::Dw100Scale] = ControlInfo(0.2f, 8.0f, 1.0f);
+	controls[&controls::Dw100Rotation] = ControlInfo(-180.0f, 180.0f, 0.0f);
+	controls[&controls::Dw100Offset] =
+		ControlInfo(Point(-10000, -10000), Point(10000, 10000), Point(0, 0));
+	controls[&controls::Dw100ScaleMode] =
+		ControlInfo(controls::Dw100ScaleModeValues, controls::Dw100ScaleModeFill);
+
 	if (!converter_.supportsRequests())
 		LOG(Converter, Warning)
 			<< "dw100 kernel driver has no requests support."
@@ -369,6 +376,30 @@  void ConverterDW100Module::setControls(const Stream *stream, const ControlList &
 	auto &info = vertexMaps_[stream];
 	auto &vertexMap = info.map;
 
+	const auto &scale = controls.get(controls::Dw100Scale);
+	if (scale) {
+		vertexMap.setScale(*scale);
+		info.update = true;
+	}
+
+	const auto &rotation = controls.get(controls::Dw100Rotation);
+	if (rotation) {
+		vertexMap.setRotation(*rotation);
+		info.update = true;
+	}
+
+	const auto &offset = controls.get(controls::Dw100Offset);
+	if (offset) {
+		vertexMap.setOffset(*offset);
+		info.update = true;
+	}
+
+	const auto &scaleMode = controls.get(controls::Dw100ScaleMode);
+	if (scaleMode) {
+		vertexMap.setMode(static_cast<Dw100VertexMap::ScaleMode>(*scaleMode));
+		info.update = true;
+	}
+
 	const auto &lensDewarpEnable = controls.get(controls::LensDewarpEnable);
 	if (lensDewarpEnable) {
 		vertexMap.setLensDewarpEnable(*lensDewarpEnable);
@@ -402,6 +433,11 @@  void ConverterDW100Module::populateMetadata(const Stream *stream, ControlList &m
 
 	auto &vertexMap = vertexMaps_[stream].map;
 
+	std::array<float, 2> effectiveScale = vertexMap.effectiveScale();
+	meta.set(controls::Dw100EffectiveScale, effectiveScale);
+	meta.set(controls::Dw100Scale, (effectiveScale[0] + effectiveScale[1]) / 2.0);
+	meta.set(controls::Dw100Rotation, vertexMap.rotation());
+	meta.set(controls::Dw100Offset, vertexMap.effectiveOffset());
 	meta.set(controls::ScalerCrop, vertexMap.effectiveScalerCrop());
 
 	if (dewarpParams_.has_value())