Patch Detail
Show a patch.
GET /api/1.1/patches/24254/?format=api
{ "id": 24254, "url": "https://patchwork.libcamera.org/api/1.1/patches/24254/?format=api", "web_url": "https://patchwork.libcamera.org/patch/24254/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20250828-flash-support-v1-2-4c5dc674a05b@emfend.at>", "date": "2025-08-28T13:09:39", "name": "[2/5] libcamera: Add support for camera flash devices", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "8bca6c3af04d9710c223e3cc8756e336bd40b4e8", "submitter": { "id": 134, "url": "https://patchwork.libcamera.org/api/1.1/people/134/?format=api", "name": "Matthias Fend", "email": "matthias.fend@emfend.at" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/24254/mbox/", "series": [ { "id": 5410, "url": "https://patchwork.libcamera.org/api/1.1/series/5410/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5410", "date": "2025-08-28T13:09:37", "name": "Support for v4l2 flash devices", "version": 1, "mbox": "https://patchwork.libcamera.org/series/5410/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/24254/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/24254/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 31689BD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 28 Aug 2025 13:09:52 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DC597692F8;\n\tThu, 28 Aug 2025 15:09:47 +0200 (CEST)", "from lx20.hoststar.hosting (lx20.hoststar.hosting [168.119.41.54])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 23A9F692E1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 28 Aug 2025 15:09:44 +0200 (CEST)", "from 194-208-208-245.tele.net ([194.208.208.245]:56023\n\thelo=[127.0.1.1]) by lx20.hoststar.hosting with esmtpsa (TLS1.3) tls\n\tTLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93)\n\t(envelope-from <matthias.fend@emfend.at>)\n\tid 1urcNq-00BORr-Lt; Thu, 28 Aug 2025 15:09:43 +0200" ], "Authentication-Results": "lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=emfend.at header.i=@emfend.at\n\theader.b=\"A64Ktvs2\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=emfend.at;\n\ts=mail;\n\th=Cc:To:In-Reply-To:References:Message-Id:Content-Transfer-Encoding:\n\tContent-Type:MIME-Version:Subject:Date:From:Sender:Reply-To:Content-ID:\n\tContent-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc\n\t:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe:\n\tList-Post:List-Owner:List-Archive;\n\tbh=AAuuYJIjlyUZSTXRpT052wDEQAn2HGC4nOuFufwxx08=;\n\tb=A64Ktvs2acqXZJbF950OGr6nOj\n\tn1pzHRZ5ouKgHl1qpQ9WlxVntomtMy860TSIs4xBOikaYLYpfW9nmaS7j5NcyOk5SLsUX1VyHk8ks\n\tqrzNXkP1Vhxm51JDBH4t9w8NA4TZJ86lk3T2ja5RU+4rnc7A5C97W/LNs34sF/Fs7R+E=;", "From": "Matthias Fend <matthias.fend@emfend.at>", "Date": "Thu, 28 Aug 2025 15:09:39 +0200", "Subject": "[PATCH 2/5] libcamera: Add support for camera flash devices", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "7bit", "Message-Id": "<20250828-flash-support-v1-2-4c5dc674a05b@emfend.at>", "References": "<20250828-flash-support-v1-0-4c5dc674a05b@emfend.at>", "In-Reply-To": "<20250828-flash-support-v1-0-4c5dc674a05b@emfend.at>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Matthias Fend <matthias.fend@emfend.at>", "X-Mailer": "b4 0.14.2", "X-Spam-Score": "-1.0", "X-Spam-Bar": "-", "X-Spam-Report": "Spam detection software,\n\trunning on the system \"lx20.hoststar.hosting\", \n\thas NOT identified this incoming email as spam. The original\n\tmessage has been attached to this so you can view it or label\n\tsimilar future email. If you have any questions, see\n\tthe administrator of that system for details.\n\tContent preview: Define a set of controls to control camera flash\n\tdevices.\n\tSigned-off-by: Matthias Fend <matthias.fend@emfend.at> ---\n\tsrc/libcamera/control_ids_draft.yaml\n\t| 69 ++++++++++++++++++++++++++++++++++++ 1 file changed,\n\t69 insertions(+)\n\tContent analysis details: (-1.0 points, 5.0 required)\n\tpts rule name description\n\t---- ----------------------\n\t--------------------------------------------------\n\t-1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP\n\t0.0 TVD_RCVD_IP Message was received from an IP address\n\t0.0 Local_hs1_NotHoststar Sender is not from hoststar.ch|de|com\n\t0.0 KAM_DMARC_STATUS Test Rule for DKIM or SPF Failure with Strict\n\tAlignment", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "Add a class to model camera flash devices. Currently, only v4l2 flash\ndevices are supported. The v4l2 flash devices are implemented similar to\nthe camera lenses.\n\nSigned-off-by: Matthias Fend <matthias.fend@emfend.at>\n---\n include/libcamera/internal/camera_flash.h | 75 ++++++++\n include/libcamera/internal/camera_sensor.h | 2 +\n src/libcamera/camera_flash.cpp | 248 ++++++++++++++++++++++++++\n src/libcamera/meson.build | 1 +\n src/libcamera/sensor/camera_sensor_legacy.cpp | 13 ++\n src/libcamera/sensor/camera_sensor_raw.cpp | 13 ++\n 6 files changed, 352 insertions(+)", "diff": "diff --git a/include/libcamera/internal/camera_flash.h b/include/libcamera/internal/camera_flash.h\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..e41afef2ab84852a340a12a012e3994f00cac27a\n--- /dev/null\n+++ b/include/libcamera/internal/camera_flash.h\n@@ -0,0 +1,75 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2025, matthias.fend@emfend.at\n+ *\n+ * Camera flash support\n+ */\n+#pragma once\n+\n+#include <memory>\n+#include <stdint.h>\n+#include <string>\n+\n+#include <libcamera/base/class.h>\n+#include <libcamera/base/log.h>\n+\n+#include <libcamera/controls.h>\n+\n+namespace libcamera {\n+\n+class MediaEntity;\n+class V4L2Subdevice;\n+\n+class CameraFlash : protected Loggable\n+{\n+public:\n+\tenum Mode {\n+\t\tNone,\n+\t\tFlash,\n+\t\tTorch,\n+\t};\n+\n+\tenum StrobeSource {\n+\t\tSoftware,\n+\t\tExternal,\n+\t};\n+\n+\texplicit CameraFlash(const MediaEntity *entity);\n+\t~CameraFlash();\n+\tint init();\n+\tMode getMode() const;\n+\tint setMode(Mode mode);\n+\tconst ControlInfo &getFlashIntensityInfo() const;\n+\tint32_t getFlashIntensity() const;\n+\tint setFlashIntensity(int32_t intensity);\n+\tconst ControlInfo &getFlashTimeoutInfo() const;\n+\tint32_t getFlashTimeout() const;\n+\tint setFlashTimeout(int32_t timeout_us);\n+\tStrobeSource getStrobeSource() const;\n+\tint setStrobeSource(StrobeSource source);\n+\tint startStrobe();\n+\tint stopStrobe();\n+\tconst ControlInfo &getTorchIntensityInfo() const;\n+\tint32_t getTorchIntensity() const;\n+\tint setTorchIntensity(int32_t intensity);\n+\n+\tconst std::string &model() const;\n+\tconst ControlInfoMap &controls() const;\n+\n+protected:\n+\tstd::string logPrefix() const override;\n+\n+private:\n+\tLIBCAMERA_DISABLE_COPY_AND_MOVE(CameraFlash)\n+\n+\tint32_t getSubdevControl(uint32_t id) const;\n+\tint setSubdevControl(uint32_t id, int32_t value);\n+\tint validateDriver();\n+\n+\tconst MediaEntity *entity_;\n+\tstd::unique_ptr<V4L2Subdevice> subdev_;\n+\tstd::string model_;\n+\tconst ControlInfoMap *controlInfoMap_ = nullptr;\n+};\n+\n+} /* namespace libcamera */\ndiff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h\nindex f6ef4df170d43500bc652762e9a575010a6c1cbd..faeecf244c8d42a43eca52ae04813e0c2f80e516 100644\n--- a/include/libcamera/internal/camera_sensor.h\n+++ b/include/libcamera/internal/camera_sensor.h\n@@ -28,6 +28,7 @@\n \n namespace libcamera {\n \n+class CameraFlash;\n class CameraLens;\n class MediaEntity;\n class SensorConfiguration;\n@@ -48,6 +49,7 @@ public:\n \tvirtual V4L2Subdevice *device() = 0;\n \n \tvirtual CameraLens *focusLens() = 0;\n+\tvirtual CameraFlash *flash() = 0;\n \n \tvirtual const std::vector<unsigned int> &mbusCodes() const = 0;\n \tvirtual std::vector<Size> sizes(unsigned int mbusCode) const = 0;\ndiff --git a/src/libcamera/camera_flash.cpp b/src/libcamera/camera_flash.cpp\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..4702c590c91e0bcb20d173e7ce03608e1ae6ecfd\n--- /dev/null\n+++ b/src/libcamera/camera_flash.cpp\n@@ -0,0 +1,248 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2025, matthias.fend@emfend.at\n+ *\n+ * Camera flash support\n+ */\n+\n+#include \"libcamera/internal/camera_flash.h\"\n+\n+#include <libcamera/base/utils.h>\n+\n+#include \"libcamera/internal/v4l2_subdevice.h\"\n+\n+namespace libcamera {\n+\n+LOG_DEFINE_CATEGORY(CameraFlash)\n+\n+CameraFlash::CameraFlash(const MediaEntity *entity)\n+\t: entity_(entity)\n+{\n+}\n+\n+CameraFlash::~CameraFlash() = default;\n+\n+int CameraFlash::init()\n+{\n+\tif (entity_->function() != MEDIA_ENT_F_FLASH) {\n+\t\tLOG(CameraFlash, Error)\n+\t\t\t<< \"Invalid flash function \"\n+\t\t\t<< utils::hex(entity_->function());\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tsubdev_ = std::make_unique<V4L2Subdevice>(entity_);\n+\tint ret = subdev_->open();\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tcontrolInfoMap_ = &subdev_->controls();\n+\n+\tret = validateDriver();\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tmodel_ = subdev_->model();\n+\n+\treturn 0;\n+}\n+\n+CameraFlash::Mode CameraFlash::getMode() const\n+{\n+\tMode m;\n+\n+\tswitch (getSubdevControl(V4L2_CID_FLASH_LED_MODE)) {\n+\tcase V4L2_FLASH_LED_MODE_FLASH:\n+\t\tm = Flash;\n+\t\tbreak;\n+\tcase V4L2_FLASH_LED_MODE_TORCH:\n+\t\tm = Torch;\n+\t\tbreak;\n+\tcase V4L2_FLASH_LED_MODE_NONE:\n+\tdefault:\n+\t\tm = None;\n+\t\tbreak;\n+\t}\n+\n+\treturn m;\n+}\n+\n+int CameraFlash::setMode(Mode mode)\n+{\n+\tint32_t m;\n+\n+\tswitch (mode) {\n+\tcase Flash:\n+\t\tm = V4L2_FLASH_LED_MODE_FLASH;\n+\t\tbreak;\n+\tcase Torch:\n+\t\tm = V4L2_FLASH_LED_MODE_TORCH;\n+\t\tbreak;\n+\tcase None:\n+\t\tm = V4L2_FLASH_LED_MODE_NONE;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn setSubdevControl(V4L2_CID_FLASH_LED_MODE, m);\n+}\n+\n+const ControlInfo &CameraFlash::getFlashIntensityInfo() const\n+{\n+\treturn controlInfoMap_->find(V4L2_CID_FLASH_INTENSITY)->second;\n+}\n+\n+int32_t CameraFlash::getFlashIntensity() const\n+{\n+\treturn getSubdevControl(V4L2_CID_FLASH_INTENSITY);\n+}\n+\n+int CameraFlash::setFlashIntensity(int32_t intensity)\n+{\n+\treturn setSubdevControl(V4L2_CID_FLASH_INTENSITY, intensity);\n+}\n+\n+const ControlInfo &CameraFlash::getFlashTimeoutInfo() const\n+{\n+\treturn controlInfoMap_->find(V4L2_CID_FLASH_TIMEOUT)->second;\n+}\n+\n+int32_t CameraFlash::getFlashTimeout() const\n+{\n+\treturn getSubdevControl(V4L2_CID_FLASH_TIMEOUT);\n+}\n+\n+int CameraFlash::setFlashTimeout(int32_t timeout)\n+{\n+\treturn setSubdevControl(V4L2_CID_FLASH_TIMEOUT, timeout);\n+}\n+\n+CameraFlash::StrobeSource CameraFlash::getStrobeSource() const\n+{\n+\tStrobeSource s;\n+\n+\tswitch (getSubdevControl(V4L2_CID_FLASH_STROBE_SOURCE)) {\n+\tcase V4L2_FLASH_STROBE_SOURCE_EXTERNAL:\n+\t\ts = External;\n+\t\tbreak;\n+\tcase V4L2_FLASH_STROBE_SOURCE_SOFTWARE:\n+\tdefault:\n+\t\ts = Software;\n+\t\tbreak;\n+\t}\n+\n+\treturn s;\n+}\n+\n+int CameraFlash::setStrobeSource(StrobeSource source)\n+{\n+\tint32_t s;\n+\n+\tswitch (source) {\n+\tcase External:\n+\t\ts = V4L2_FLASH_STROBE_SOURCE_EXTERNAL;\n+\t\tbreak;\n+\tcase Software:\n+\t\ts = V4L2_FLASH_STROBE_SOURCE_SOFTWARE;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn setSubdevControl(V4L2_CID_FLASH_STROBE_SOURCE, s);\n+}\n+\n+int CameraFlash::startStrobe()\n+{\n+\treturn setSubdevControl(V4L2_CID_FLASH_STROBE, 1);\n+}\n+\n+int CameraFlash::stopStrobe()\n+{\n+\treturn setSubdevControl(V4L2_CID_FLASH_STROBE_STOP, 1);\n+}\n+\n+const ControlInfo &CameraFlash::getTorchIntensityInfo() const\n+{\n+\treturn controlInfoMap_->find(V4L2_CID_FLASH_TORCH_INTENSITY)->second;\n+}\n+\n+int32_t CameraFlash::getTorchIntensity() const\n+{\n+\treturn getSubdevControl(V4L2_CID_FLASH_TORCH_INTENSITY);\n+}\n+\n+int CameraFlash::setTorchIntensity(int32_t intensity)\n+{\n+\treturn setSubdevControl(V4L2_CID_FLASH_TORCH_INTENSITY, intensity);\n+}\n+\n+const std::string &CameraFlash::model() const\n+{\n+\treturn model_;\n+}\n+\n+const ControlInfoMap &CameraFlash::controls() const\n+{\n+\treturn subdev_->controls();\n+}\n+\n+std::string CameraFlash::logPrefix() const\n+{\n+\treturn \"'\" + entity_->name() + \"'\";\n+}\n+\n+int32_t CameraFlash::getSubdevControl(uint32_t id) const\n+{\n+\tControlList controlList = subdev_->getControls(std::vector<uint32_t>{ id });\n+\n+\treturn controlList.get(id).get<int32_t>();\n+}\n+\n+int CameraFlash::setSubdevControl(uint32_t id, int32_t value)\n+{\n+\tControlList flashCtrls(subdev_->controls());\n+\n+\tflashCtrls.set(id, value);\n+\n+\tif (subdev_->setControls(&flashCtrls))\n+\t\treturn -EINVAL;\n+\n+\treturn 0;\n+}\n+\n+int CameraFlash::validateDriver()\n+{\n+\tint ret = 0;\n+\tstatic constexpr uint32_t mandatoryControls[] = {\n+\t\tV4L2_CID_FLASH_LED_MODE,\n+\t\tV4L2_CID_FLASH_STROBE_SOURCE,\n+\t\tV4L2_CID_FLASH_STROBE,\n+\t\tV4L2_CID_FLASH_TIMEOUT,\n+\t\tV4L2_CID_FLASH_INTENSITY,\n+\t\tV4L2_CID_FLASH_TORCH_INTENSITY,\n+\t};\n+\n+\tfor (uint32_t ctrl : mandatoryControls) {\n+\t\tif (!controlInfoMap_->count(ctrl)) {\n+\t\t\tLOG(CameraFlash, Error)\n+\t\t\t\t<< \"Mandatory V4L2 control \" << utils::hex(ctrl)\n+\t\t\t\t<< \" not available\";\n+\t\t\tret = -EINVAL;\n+\t\t}\n+\t}\n+\n+\tif (ret) {\n+\t\tLOG(CameraFlash, Error)\n+\t\t\t<< \"The flash kernel driver needs to be fixed\";\n+\t\tLOG(CameraFlash, Error)\n+\t\t\t<< \"See Documentation/flash_driver_requirements.rst in\"\n+\t\t\t<< \" the libcamera sources for more information\";\n+\t\treturn ret;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+} /* namespace libcamera */\ndiff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\nindex b3ca27f217da4ba3a896ef7cbfb5502fa82a4907..0f125661a51e2431c1febc353cef30a1219f9ce7 100644\n--- a/src/libcamera/meson.build\n+++ b/src/libcamera/meson.build\n@@ -20,6 +20,7 @@ libcamera_internal_sources = files([\n 'bayer_format.cpp',\n 'byte_stream_buffer.cpp',\n 'camera_controls.cpp',\n+ 'camera_flash.cpp',\n 'camera_lens.cpp',\n 'clock_recovery.cpp',\n 'control_serializer.cpp',\ndiff --git a/src/libcamera/sensor/camera_sensor_legacy.cpp b/src/libcamera/sensor/camera_sensor_legacy.cpp\nindex f9e685a9acc499fc91d51ed1d66780a0ad2d2a8f..632b66ea0aa15fcd654e7f0efb50c24cb9b973bf 100644\n--- a/src/libcamera/sensor/camera_sensor_legacy.cpp\n+++ b/src/libcamera/sensor/camera_sensor_legacy.cpp\n@@ -31,6 +31,7 @@\n #include <libcamera/ipa/core_ipa_interface.h>\n \n #include \"libcamera/internal/bayer_format.h\"\n+#include \"libcamera/internal/camera_flash.h\"\n #include \"libcamera/internal/camera_lens.h\"\n #include \"libcamera/internal/camera_sensor.h\"\n #include \"libcamera/internal/camera_sensor_properties.h\"\n@@ -68,6 +69,7 @@ public:\n \tV4L2Subdevice *device() override { return subdev_.get(); }\n \n \tCameraLens *focusLens() override { return focusLens_.get(); }\n+\tCameraFlash *flash() override { return flash_.get(); }\n \n \tconst std::vector<unsigned int> &mbusCodes() const override { return mbusCodes_; }\n \tstd::vector<Size> sizes(unsigned int mbusCode) const override;\n@@ -139,6 +141,7 @@ private:\n \tControlList properties_;\n \n \tstd::unique_ptr<CameraLens> focusLens_;\n+\tstd::unique_ptr<CameraFlash> flash_;\n };\n \n /**\n@@ -665,6 +668,16 @@ int CameraSensorLegacy::discoverAncillaryDevices()\n \t\t\t}\n \t\t\tbreak;\n \n+\t\tcase MEDIA_ENT_F_FLASH:\n+\t\t\tflash_ = std::make_unique<CameraFlash>(ancillary);\n+\t\t\tret = flash_->init();\n+\t\t\tif (ret) {\n+\t\t\t\tLOG(CameraSensor, Error)\n+\t\t\t\t\t<< \"Flash initialisation failed, flash disabled\";\n+\t\t\t\tflash_.reset();\n+\t\t\t}\n+\t\t\tbreak;\n+\n \t\tdefault:\n \t\t\tLOG(CameraSensor, Warning)\n \t\t\t\t<< \"Unsupported ancillary entity function \"\ndiff --git a/src/libcamera/sensor/camera_sensor_raw.cpp b/src/libcamera/sensor/camera_sensor_raw.cpp\nindex 8ea4423698cd8c1eaae43eb5ba8b5d524b94d515..9d533d814b9df453aa4009a87818c1558bcbd665 100644\n--- a/src/libcamera/sensor/camera_sensor_raw.cpp\n+++ b/src/libcamera/sensor/camera_sensor_raw.cpp\n@@ -32,6 +32,7 @@\n #include <libcamera/ipa/core_ipa_interface.h>\n \n #include \"libcamera/internal/bayer_format.h\"\n+#include \"libcamera/internal/camera_flash.h\"\n #include \"libcamera/internal/camera_lens.h\"\n #include \"libcamera/internal/camera_sensor.h\"\n #include \"libcamera/internal/camera_sensor_properties.h\"\n@@ -69,6 +70,7 @@ public:\n \tV4L2Subdevice *device() override { return subdev_.get(); }\n \n \tCameraLens *focusLens() override { return focusLens_.get(); }\n+\tCameraFlash *flash() override { return flash_.get(); }\n \n \tconst std::vector<unsigned int> &mbusCodes() const override { return mbusCodes_; }\n \tstd::vector<Size> sizes(unsigned int mbusCode) const override;\n@@ -150,6 +152,7 @@ private:\n \tControlList properties_;\n \n \tstd::unique_ptr<CameraLens> focusLens_;\n+\tstd::unique_ptr<CameraFlash> flash_;\n };\n \n /**\n@@ -513,6 +516,16 @@ std::optional<int> CameraSensorRaw::init()\n \t\t\t}\n \t\t\tbreak;\n \n+\t\tcase MEDIA_ENT_F_FLASH:\n+\t\t\tflash_ = std::make_unique<CameraFlash>(ancillary);\n+\t\t\tret = flash_->init();\n+\t\t\tif (ret) {\n+\t\t\t\tLOG(CameraSensor, Error)\n+\t\t\t\t\t<< \"Flash initialisation failed, flash disabled\";\n+\t\t\t\tflash_.reset();\n+\t\t\t}\n+\t\t\tbreak;\n+\n \t\tdefault:\n \t\t\tLOG(CameraSensor, Warning)\n \t\t\t\t<< \"Unsupported ancillary entity function \"\n", "prefixes": [ "2/5" ] }