[v2,4/5] libcamera: Add flash helpers for pipeline handlers
diff mbox series

Message ID 20250912-flash_reco-v2-4-d5bb80a2e619@emfend.at
State New
Headers show
Series
  • Support for v4l2 flash devices
Related show

Commit Message

Matthias Fend Sept. 12, 2025, 7:13 a.m. UTC
Add a set of helpers that pipeline handlers can use to deal with camera
flash devices. This mainly involves mapping controls to the flash device
and vice versa.

Signed-off-by: Matthias Fend <matthias.fend@emfend.at>
---
 include/libcamera/internal/flash_control.h |  23 +++++
 src/libcamera/flash_control.cpp            | 148 +++++++++++++++++++++++++++++
 src/libcamera/meson.build                  |   1 +
 3 files changed, 172 insertions(+)

Comments

Isaac Scott Sept. 16, 2025, 11:10 a.m. UTC | #1
Hi Matthias,

Thank you for the patch!

Quoting Matthias Fend (2025-09-12 08:13:23)
> Add a set of helpers that pipeline handlers can use to deal with camera
> flash devices. This mainly involves mapping controls to the flash device
> and vice versa.
> 
> Signed-off-by: Matthias Fend <matthias.fend@emfend.at>
> ---
>  include/libcamera/internal/flash_control.h |  23 +++++
>  src/libcamera/flash_control.cpp            | 148 +++++++++++++++++++++++++++++
>  src/libcamera/meson.build                  |   1 +
>  3 files changed, 172 insertions(+)
> 
> diff --git a/include/libcamera/internal/flash_control.h b/include/libcamera/internal/flash_control.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..d530dc24fd8ea2d5676d95ab5943a7dacee07617
> --- /dev/null
> +++ b/include/libcamera/internal/flash_control.h
> @@ -0,0 +1,23 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2025, matthias.fend@emfend.at
> + *
> + * Flash controls helpers for pipeline handlers
> + */
> +
> +#pragma once
> +
> +#include <libcamera/controls.h>
> +
> +#include "libcamera/internal/camera_flash.h"
> +
> +namespace libcamera {
> +
> +class FlashControl
> +{
> +public:
> +       static void updateFlashControls(CameraFlash *flash, ControlInfoMap::Map &controls);
> +       static void handleFlashControls(CameraFlash *flash, ControlList &controls, ControlList &metadata);
> +};

This looks good to me!

Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>

> +
> +} /* namespace libcamera */
> diff --git a/src/libcamera/flash_control.cpp b/src/libcamera/flash_control.cpp
> new file mode 100644
> index 0000000000000000000000000000000000000000..0a032b5d50c8c04696aea211f05222357432e7ed
> --- /dev/null
> +++ b/src/libcamera/flash_control.cpp
> @@ -0,0 +1,148 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2025, matthias.fend@emfend.at
> + *
> + * Flash controls helpers for pipeline handlers
> + */
> +
> +#include "libcamera/internal/flash_control.h"
> +
> +#include <libcamera/control_ids.h>
> +#include <libcamera/controls.h>
> +
> +namespace libcamera {
> +
> +void FlashControl::updateFlashControls(CameraFlash *flash, ControlInfoMap::Map &controls)
> +{
> +       if (!flash)
> +               return;
> +
> +       controls[&controls::FlashMode] = ControlInfo(controls::FlashModeValues, controls::FlashModeNone);
> +       controls[&controls::FlashIntensity] = flash->getFlashIntensityInfo();
> +       controls[&controls::FlashTimeout] = flash->getFlashTimeoutInfo();
> +       controls[&controls::FlashStrobeSource] = ControlInfo(controls::FlashStrobeSourceValues, controls::FlashStrobeSourceSoftware);
> +       controls[&controls::FlashStrobe] = ControlInfo(controls::FlashStrobeValues);
> +       controls[&controls::FlashTorchIntensity] = flash->getTorchIntensityInfo();
> +}
> +
> +void FlashControl::handleFlashControls(CameraFlash *flash, ControlList &controls, ControlList &metadata)
> +{
> +       if (!flash)
> +               return;
> +
> +       /* Handle controls */
> +
> +       const auto &flashMode = controls.get(controls::FlashMode);
> +       if (flashMode) {
> +               CameraFlash::Mode mode;
> +
> +               switch (*flashMode) {
> +               case controls::FlashModeFlash:
> +                       mode = CameraFlash::Mode::Flash;
> +                       break;
> +               case controls::FlashModeTorch:
> +                       mode = CameraFlash::Mode::Torch;
> +                       break;
> +               case controls::FlashModeNone:
> +               default:
> +                       mode = CameraFlash::Mode::None;
> +                       break;
> +               }
> +
> +               flash->setMode(mode);
> +       }
> +
> +       const auto &flashIntensity = controls.get<int32_t>(controls::FlashIntensity);
> +       if (flashIntensity)
> +               flash->setFlashIntensity(*flashIntensity);
> +
> +       const auto &flashTimeout = controls.get<int32_t>(controls::FlashTimeout);
> +       if (flashTimeout)
> +               flash->setFlashTimeout(*flashTimeout);
> +
> +       const auto &flashStrobeSource = controls.get(controls::FlashStrobeSource);
> +       if (flashStrobeSource) {
> +               CameraFlash::StrobeSource source;
> +
> +               switch (*flashStrobeSource) {
> +               case controls::FlashStrobeSourceExternal:
> +                       source = CameraFlash::StrobeSource::External;
> +                       break;
> +               case controls::FlashStrobeSourceSoftware:
> +               default:
> +                       source = CameraFlash::StrobeSource::Software;
> +                       break;
> +               }
> +
> +               flash->setStrobeSource(source);
> +       }
> +
> +       const auto &flashStrobe = controls.get(controls::FlashStrobe);
> +       if (flashStrobe) {
> +               switch (*flashStrobe) {
> +               case controls::FlashStrobeStart:
> +                       flash->startStrobe();
> +                       break;
> +               case controls::FlashStrobeStop:
> +                       flash->stopStrobe();
> +                       break;
> +               default:
> +                       break;
> +               }
> +       }
> +
> +       const auto &flashTorchIntensity = controls.get<int32_t>(controls::FlashTorchIntensity);
> +       if (flashTorchIntensity)
> +               flash->setTorchIntensity(*flashTorchIntensity);
> +
> +       /* Fill metadata */
> +
> +       const auto metaFlashMode = flash->getMode();
> +       if (metaFlashMode) {
> +               controls::FlashModeEnum mode;
> +
> +               switch (*metaFlashMode) {
> +               case CameraFlash::Mode::Flash:
> +                       mode = controls::FlashModeFlash;
> +                       break;
> +               case CameraFlash::Mode::Torch:
> +                       mode = controls::FlashModeTorch;
> +                       break;
> +               case CameraFlash::Mode::None:
> +               default:
> +                       mode = controls::FlashModeNone;
> +                       break;
> +               }
> +               metadata.set(controls::FlashMode, mode);
> +       }
> +
> +       const auto metaFlashIntensity = flash->getFlashIntensity();
> +       if (metaFlashIntensity)
> +               metadata.set(controls::FlashIntensity, *metaFlashIntensity);
> +
> +       auto metaFlashTimeout = flash->getFlashTimeout();
> +       if (metaFlashTimeout)
> +               metadata.set(controls::FlashTimeout, *metaFlashTimeout);
> +
> +       auto metaStrobeSource = flash->getStrobeSource();
> +       if (metaStrobeSource) {
> +               controls::FlashStrobeSourceEnum source;
> +
> +               switch (*metaStrobeSource) {
> +               case CameraFlash::StrobeSource::External:
> +                       source = controls::FlashStrobeSourceExternal;
> +                       break;
> +               case CameraFlash::StrobeSource::Software:
> +               default:
> +                       source = controls::FlashStrobeSourceSoftware;
> +                       break;
> +               }
> +               metadata.set(controls::FlashStrobeSource, source);
> +       }
> +
> +       auto metaTorchIntensity = flash->getTorchIntensity();
> +       if (metaTorchIntensity)
> +               metadata.set(controls::FlashTorchIntensity, *metaTorchIntensity);
> +}
> +
> +} /* namespace libcamera */
> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
> index 0f125661a51e2431c1febc353cef30a1219f9ce7..a68a49637db12f9e66b5bb38ee859aaac8c2fd1a 100644
> --- a/src/libcamera/meson.build
> +++ b/src/libcamera/meson.build
> @@ -31,6 +31,7 @@ libcamera_internal_sources = files([
>      'device_enumerator.cpp',
>      'device_enumerator_sysfs.cpp',
>      'dma_buf_allocator.cpp',
> +    'flash_control.cpp',
>      'formats.cpp',
>      'ipa_controls.cpp',
>      'ipa_data_serializer.cpp',
> 
> -- 
> 2.34.1
>

Patch
diff mbox series

diff --git a/include/libcamera/internal/flash_control.h b/include/libcamera/internal/flash_control.h
new file mode 100644
index 0000000000000000000000000000000000000000..d530dc24fd8ea2d5676d95ab5943a7dacee07617
--- /dev/null
+++ b/include/libcamera/internal/flash_control.h
@@ -0,0 +1,23 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2025, matthias.fend@emfend.at
+ *
+ * Flash controls helpers for pipeline handlers
+ */
+
+#pragma once
+
+#include <libcamera/controls.h>
+
+#include "libcamera/internal/camera_flash.h"
+
+namespace libcamera {
+
+class FlashControl
+{
+public:
+	static void updateFlashControls(CameraFlash *flash, ControlInfoMap::Map &controls);
+	static void handleFlashControls(CameraFlash *flash, ControlList &controls, ControlList &metadata);
+};
+
+} /* namespace libcamera */
diff --git a/src/libcamera/flash_control.cpp b/src/libcamera/flash_control.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0a032b5d50c8c04696aea211f05222357432e7ed
--- /dev/null
+++ b/src/libcamera/flash_control.cpp
@@ -0,0 +1,148 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2025, matthias.fend@emfend.at
+ *
+ * Flash controls helpers for pipeline handlers
+ */
+
+#include "libcamera/internal/flash_control.h"
+
+#include <libcamera/control_ids.h>
+#include <libcamera/controls.h>
+
+namespace libcamera {
+
+void FlashControl::updateFlashControls(CameraFlash *flash, ControlInfoMap::Map &controls)
+{
+	if (!flash)
+		return;
+
+	controls[&controls::FlashMode] = ControlInfo(controls::FlashModeValues, controls::FlashModeNone);
+	controls[&controls::FlashIntensity] = flash->getFlashIntensityInfo();
+	controls[&controls::FlashTimeout] = flash->getFlashTimeoutInfo();
+	controls[&controls::FlashStrobeSource] = ControlInfo(controls::FlashStrobeSourceValues, controls::FlashStrobeSourceSoftware);
+	controls[&controls::FlashStrobe] = ControlInfo(controls::FlashStrobeValues);
+	controls[&controls::FlashTorchIntensity] = flash->getTorchIntensityInfo();
+}
+
+void FlashControl::handleFlashControls(CameraFlash *flash, ControlList &controls, ControlList &metadata)
+{
+	if (!flash)
+		return;
+
+	/* Handle controls */
+
+	const auto &flashMode = controls.get(controls::FlashMode);
+	if (flashMode) {
+		CameraFlash::Mode mode;
+
+		switch (*flashMode) {
+		case controls::FlashModeFlash:
+			mode = CameraFlash::Mode::Flash;
+			break;
+		case controls::FlashModeTorch:
+			mode = CameraFlash::Mode::Torch;
+			break;
+		case controls::FlashModeNone:
+		default:
+			mode = CameraFlash::Mode::None;
+			break;
+		}
+
+		flash->setMode(mode);
+	}
+
+	const auto &flashIntensity = controls.get<int32_t>(controls::FlashIntensity);
+	if (flashIntensity)
+		flash->setFlashIntensity(*flashIntensity);
+
+	const auto &flashTimeout = controls.get<int32_t>(controls::FlashTimeout);
+	if (flashTimeout)
+		flash->setFlashTimeout(*flashTimeout);
+
+	const auto &flashStrobeSource = controls.get(controls::FlashStrobeSource);
+	if (flashStrobeSource) {
+		CameraFlash::StrobeSource source;
+
+		switch (*flashStrobeSource) {
+		case controls::FlashStrobeSourceExternal:
+			source = CameraFlash::StrobeSource::External;
+			break;
+		case controls::FlashStrobeSourceSoftware:
+		default:
+			source = CameraFlash::StrobeSource::Software;
+			break;
+		}
+
+		flash->setStrobeSource(source);
+	}
+
+	const auto &flashStrobe = controls.get(controls::FlashStrobe);
+	if (flashStrobe) {
+		switch (*flashStrobe) {
+		case controls::FlashStrobeStart:
+			flash->startStrobe();
+			break;
+		case controls::FlashStrobeStop:
+			flash->stopStrobe();
+			break;
+		default:
+			break;
+		}
+	}
+
+	const auto &flashTorchIntensity = controls.get<int32_t>(controls::FlashTorchIntensity);
+	if (flashTorchIntensity)
+		flash->setTorchIntensity(*flashTorchIntensity);
+
+	/* Fill metadata */
+
+	const auto metaFlashMode = flash->getMode();
+	if (metaFlashMode) {
+		controls::FlashModeEnum mode;
+
+		switch (*metaFlashMode) {
+		case CameraFlash::Mode::Flash:
+			mode = controls::FlashModeFlash;
+			break;
+		case CameraFlash::Mode::Torch:
+			mode = controls::FlashModeTorch;
+			break;
+		case CameraFlash::Mode::None:
+		default:
+			mode = controls::FlashModeNone;
+			break;
+		}
+		metadata.set(controls::FlashMode, mode);
+	}
+
+	const auto metaFlashIntensity = flash->getFlashIntensity();
+	if (metaFlashIntensity)
+		metadata.set(controls::FlashIntensity, *metaFlashIntensity);
+
+	auto metaFlashTimeout = flash->getFlashTimeout();
+	if (metaFlashTimeout)
+		metadata.set(controls::FlashTimeout, *metaFlashTimeout);
+
+	auto metaStrobeSource = flash->getStrobeSource();
+	if (metaStrobeSource) {
+		controls::FlashStrobeSourceEnum source;
+
+		switch (*metaStrobeSource) {
+		case CameraFlash::StrobeSource::External:
+			source = controls::FlashStrobeSourceExternal;
+			break;
+		case CameraFlash::StrobeSource::Software:
+		default:
+			source = controls::FlashStrobeSourceSoftware;
+			break;
+		}
+		metadata.set(controls::FlashStrobeSource, source);
+	}
+
+	auto metaTorchIntensity = flash->getTorchIntensity();
+	if (metaTorchIntensity)
+		metadata.set(controls::FlashTorchIntensity, *metaTorchIntensity);
+}
+
+} /* namespace libcamera */
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 0f125661a51e2431c1febc353cef30a1219f9ce7..a68a49637db12f9e66b5bb38ee859aaac8c2fd1a 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -31,6 +31,7 @@  libcamera_internal_sources = files([
     'device_enumerator.cpp',
     'device_enumerator_sysfs.cpp',
     'dma_buf_allocator.cpp',
+    'flash_control.cpp',
     'formats.cpp',
     'ipa_controls.cpp',
     'ipa_data_serializer.cpp',