[v2,1/5] libcamera: control_ids_core: Add flash controls
diff mbox series

Message ID 20250912-flash_reco-v2-1-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
Define a set of controls to control camera flash devices.

Signed-off-by: Matthias Fend <matthias.fend@emfend.at>
---
 src/libcamera/control_ids_core.yaml | 78 +++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

Comments

David Plowman Sept. 12, 2025, 10:21 a.m. UTC | #1
Hi Matthias

Thanks for the updated version.

On Fri, 12 Sept 2025 at 08:13, Matthias Fend <matthias.fend@emfend.at> wrote:
>
> Define a set of controls to control camera flash devices.
>
> Signed-off-by: Matthias Fend <matthias.fend@emfend.at>
> ---
>  src/libcamera/control_ids_core.yaml | 78 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 78 insertions(+)
>
> diff --git a/src/libcamera/control_ids_core.yaml b/src/libcamera/control_ids_core.yaml
> index eec4b4f937ee6a2d751bb747e3b2d79dc16b7a3a..ff002accd771918b2618694ab14cda386997bc12 100644
> --- a/src/libcamera/control_ids_core.yaml
> +++ b/src/libcamera/control_ids_core.yaml
> @@ -1284,4 +1284,82 @@ controls:
>
>          The FrameWallClock control can only be returned in metadata.
>
> +  - FlashMode:
> +      type: int32_t
> +      direction: inout
> +      description: |
> +        Flash operation mode.
> +      enum:
> +        - name: FlashModeNone
> +          value: 0
> +          description: |
> +            Flash is off and inactive.
> +        - name: FlashModeFlash
> +          value: 1
> +          description: |
> +            The flash is active, but will only be switched on for a short time
> +            by means of a trigger (software or external strobe). The maximum
> +            switch-on time is limited by the FlashTimeout setting.
> +        - name: FlashModeTorch
> +          value: 2
> +          description: |
> +            The flash is continuously on and active. Commonly referred to as
> +            torch or video light mode.

I wonder what the FlashMode should be when the AGC/AEC is driving the
flash - which I expect to be a common scenario in real life. Generally
I'm feeling there's a kind of "auto/manual" distinction, a bit like we
have elsewhere. When the flash is in "auto" mode, then it's the
AGC/AEC that's going to drive it. When it's in "manual" mode, you get
to set all these parameters, turn the flash on or off yourself. What
do you think?

> +
> +  - FlashIntensity:
> +      type: int32_t
> +      direction: inout
> +      description: |
> +        Flash intensity in mA. Used when the flash is operated in flash mode.

Still struggling a bit with the mA here!

I think that, as a user of the flash, my minimum requirement is that I
would have linear control over the flash intensity. That is, if I
double the intensity then I get double the pixel brightness (when
there is no ambient light, or double the increase in brightness when
there is ambient light). This allows you to fire the flash (at a
low-ish level), measure the response, and calculate what level of
flash you really need.

My belief is that the use of mA would preclude that. So I'm still
thinking I'd rather have an intensity that's (for example) a
percentage of maximum, that has been calibrated (in the driver, or a
flash_helper...) to behave linearly. Things like max current and so on
should still appear in the camera properties (or somewhere like that).

Nit-picking a little, mA is not a unit of intensity - perhaps if
someone wants direct control of the current, a FlashCurrent control
would be better? Though I'm not convinced by the need for a
FlashCurrent control if you already have FlashIntensity, though am
open to persuasion there!

> +
> +  - FlashTimeout:
> +      type: int32_t
> +      direction: inout
> +      description: |
> +        Flash timeout in us. Determines the maximum flash switch-on time. After
> +        this time has elapsed, the flash is switched off by the hardware, even
> +        if a strobe is still active.
> +
> +  - FlashStrobeSource:
> +      type: int32_t
> +      direction: inout
> +      description: |
> +        Flash strobe source.
> +      enum:
> +        - name: FlashStrobeSourceSoftware
> +          value: 0
> +          description: |
> +            The strobe signal is controlled via software using the FlashStrobe
> +            control.
> +        - name: FlashStrobeSourceExternal
> +          value: 1
> +          description: |
> +            The strobe signal is controlled by an external source. Typically,
> +            this is done on the hardware by connecting the strobe source
> +            directly to the flash controller.
> +
> +  - FlashStrobe:
> +      type: int32_t
> +      direction: in
> +      description: |
> +        Start/stop flash strobe. Only possible if FlashStrobeSourceSoftware is
> +        selcted as FlashStrobeSource.
> +
> +      enum:
> +        - name: FlashStrobeStart
> +          value: 0
> +          description: |
> +            Start flash strobe.
> +
> +        - name: FlashStrobeStop
> +          value: 1
> +          description: |
> +            Stop flash strobe.
> +
> +  - FlashTorchIntensity:
> +      type: int32_t
> +      direction: inout
> +      description: |
> +        Torch intensity in mA. Used when the flash is operated in torch mode.
> +

I'm also still wondering if it's possible to return metadata that
tells us about the flash status for any completed request. That is,
was the flash on or off, or "partially on" - does that sound possible?
I guess to some extent you could dead-reckon this sort of stuff if you
have a reasonable timestamp for when the flash goes on/off, but it's
still a bit fiddly (you have to worry about not only the frame's
timestamp, but the time before that when it started exposing, as well
as the read-out time of the final pixel, which may be earlier than the
frame length, of course). Maybe we should be nice and figure this out
for the users? Or is this a topic for another time?

Sorry for all the questions!

Best regards
David

>  ...
>
> --
> 2.34.1
>
Matthias Fend Sept. 12, 2025, 2:09 p.m. UTC | #2
Hi David,

thanks for your comments, questions, and thoughts on this.

Just to emphasize the note in the cover letter again (in case it got 
lost). Since the proposed API is considered too low-level, it will most 
likely not make it into libcamera in this form.

Am 12.09.2025 um 12:21 schrieb David Plowman:
> Hi Matthias
> 
> Thanks for the updated version.
> 
> On Fri, 12 Sept 2025 at 08:13, Matthias Fend <matthias.fend@emfend.at> wrote:
>>
>> Define a set of controls to control camera flash devices.
>>
>> Signed-off-by: Matthias Fend <matthias.fend@emfend.at>
>> ---
>>   src/libcamera/control_ids_core.yaml | 78 +++++++++++++++++++++++++++++++++++++
>>   1 file changed, 78 insertions(+)
>>
>> diff --git a/src/libcamera/control_ids_core.yaml b/src/libcamera/control_ids_core.yaml
>> index eec4b4f937ee6a2d751bb747e3b2d79dc16b7a3a..ff002accd771918b2618694ab14cda386997bc12 100644
>> --- a/src/libcamera/control_ids_core.yaml
>> +++ b/src/libcamera/control_ids_core.yaml
>> @@ -1284,4 +1284,82 @@ controls:
>>
>>           The FrameWallClock control can only be returned in metadata.
>>
>> +  - FlashMode:
>> +      type: int32_t
>> +      direction: inout
>> +      description: |
>> +        Flash operation mode.
>> +      enum:
>> +        - name: FlashModeNone
>> +          value: 0
>> +          description: |
>> +            Flash is off and inactive.
>> +        - name: FlashModeFlash
>> +          value: 1
>> +          description: |
>> +            The flash is active, but will only be switched on for a short time
>> +            by means of a trigger (software or external strobe). The maximum
>> +            switch-on time is limited by the FlashTimeout setting.
>> +        - name: FlashModeTorch
>> +          value: 2
>> +          description: |
>> +            The flash is continuously on and active. Commonly referred to as
>> +            torch or video light mode.
> 
> I wonder what the FlashMode should be when the AGC/AEC is driving the
> flash - which I expect to be a common scenario in real life. Generally
> I'm feeling there's a kind of "auto/manual" distinction, a bit like we
> have elsewhere. When the flash is in "auto" mode, then it's the
> AGC/AEC that's going to drive it. When it's in "manual" mode, you get
> to set all these parameters, turn the flash on or off yourself. What
> do you think?

All of these controls target the flash hardware device and not a higher 
level of flash support, such as automatically taking still images with 
flash.
Basically, you can do the same things as an application that uses the 
flash-v4l2 device. Currently, a libcamera application needs to handle a 
flash device separately via v4l2 controls.
With this series, libcamera automatically detects the correct v4l2 flash 
device, and the application can use libcamera controls. You no longer 
need to deal with v4l2. No more, no less.

When we talk about settings and modes that actually take care of all the 
flash handling and still image capture for an application, there are 
many more possibilities and details to consider. So just a few thoughts.

For videos (streaming or recording), only torch mode is actually 
suitable. Whether this should be used (and at what intensity) or not can 
really only be decided by the application.

The actual torch, as we know it from our cell phones, can also be a use 
case.

For still image capture, I also see various selectable modes (torch, 
flash with pre-flash, flash with multi-exposure, etc.), each of which 
has further configurations for things like intensity.

> 
>> +
>> +  - FlashIntensity:
>> +      type: int32_t
>> +      direction: inout
>> +      description: |
>> +        Flash intensity in mA. Used when the flash is operated in flash mode.
> 
> Still struggling a bit with the mA here!
> 
> I think that, as a user of the flash, my minimum requirement is that I
> would have linear control over the flash intensity. That is, if I
> double the intensity then I get double the pixel brightness (when
> there is no ambient light, or double the increase in brightness when
> there is ambient light). This allows you to fire the flash (at a
> low-ish level), measure the response, and calculate what level of
> flash you really need.
> 
> My belief is that the use of mA would preclude that. So I'm still
> thinking I'd rather have an intensity that's (for example) a
> percentage of maximum, that has been calibrated (in the driver, or a
> flash_helper...) to behave linearly. Things like max current and so on
> should still appear in the camera properties (or somewhere like that).
> 
> Nit-picking a little, mA is not a unit of intensity - perhaps if
> someone wants direct control of the current, a FlashCurrent control
> would be better? Though I'm not convinced by the need for a
> FlashCurrent control if you already have FlashIntensity, though am
> open to persuasion there!

This control also refers to a low level and corresponds fairly closely 
to the corresponding v4l2 control.
If you want to have a corresponding high-level control here that is 
supposed to reflect the actual intensity, then you will probably need a 
mapping in the tuning file.
I don't think that either the driver or a device helper (per driver as 
done for image sensor) has the necessary information to know how the 
current actually affects the intensity. At least for LEDs, this is 
typically not linear.

Another factor that should not be overlooked here is the influence of 
the scene.
If you take a picture with flash intensity set to 50% and 100% 
respectively, depending on the scene, the resulting image brightness 
will change as expected, remain completely the same, or somewhere in 
between.

> 
>> +
>> +  - FlashTimeout:
>> +      type: int32_t
>> +      direction: inout
>> +      description: |
>> +        Flash timeout in us. Determines the maximum flash switch-on time. After
>> +        this time has elapsed, the flash is switched off by the hardware, even
>> +        if a strobe is still active.
>> +
>> +  - FlashStrobeSource:
>> +      type: int32_t
>> +      direction: inout
>> +      description: |
>> +        Flash strobe source.
>> +      enum:
>> +        - name: FlashStrobeSourceSoftware
>> +          value: 0
>> +          description: |
>> +            The strobe signal is controlled via software using the FlashStrobe
>> +            control.
>> +        - name: FlashStrobeSourceExternal
>> +          value: 1
>> +          description: |
>> +            The strobe signal is controlled by an external source. Typically,
>> +            this is done on the hardware by connecting the strobe source
>> +            directly to the flash controller.
>> +
>> +  - FlashStrobe:
>> +      type: int32_t
>> +      direction: in
>> +      description: |
>> +        Start/stop flash strobe. Only possible if FlashStrobeSourceSoftware is
>> +        selcted as FlashStrobeSource.
>> +
>> +      enum:
>> +        - name: FlashStrobeStart
>> +          value: 0
>> +          description: |
>> +            Start flash strobe.
>> +
>> +        - name: FlashStrobeStop
>> +          value: 1
>> +          description: |
>> +            Stop flash strobe.
>> +
>> +  - FlashTorchIntensity:
>> +      type: int32_t
>> +      direction: inout
>> +      description: |
>> +        Torch intensity in mA. Used when the flash is operated in torch mode.
>> +
> 
> I'm also still wondering if it's possible to return metadata that
> tells us about the flash status for any completed request. That is,
> was the flash on or off, or "partially on" - does that sound possible?
> I guess to some extent you could dead-reckon this sort of stuff if you
> have a reasonable timestamp for when the flash goes on/off, but it's
> still a bit fiddly (you have to worry about not only the frame's
> timestamp, but the time before that when it started exposing, as well
> as the read-out time of the final pixel, which may be earlier than the
> frame length, of course). Maybe we should be nice and figure this out
> for the users? Or is this a topic for another time?

There is a corresponding v4l2 control to at least read the current 
strobe status (V4L2_CID_FLASH_STROBE_STATUS). This status could be added 
to the metadata.
However, I am not sure whether all drivers consistently provide the same 
information here (e.g., what is returned when the strobe signal is still 
active but a timeout has occurred) and whether the timing is reliable 
enough.

Perhaps it is also possible to estimate the actual lightning activity 
somehow from the brightness values of the frames.

> 
> Sorry for all the questions!

No, thank you very much for them. It's good to see that there is at 
least some discussion here.

Best regards
  ~Matthias

> 
> Best regards
> David
> 
>>   ...
>>
>> --
>> 2.34.1
>>

Patch
diff mbox series

diff --git a/src/libcamera/control_ids_core.yaml b/src/libcamera/control_ids_core.yaml
index eec4b4f937ee6a2d751bb747e3b2d79dc16b7a3a..ff002accd771918b2618694ab14cda386997bc12 100644
--- a/src/libcamera/control_ids_core.yaml
+++ b/src/libcamera/control_ids_core.yaml
@@ -1284,4 +1284,82 @@  controls:
 
         The FrameWallClock control can only be returned in metadata.
 
+  - FlashMode:
+      type: int32_t
+      direction: inout
+      description: |
+        Flash operation mode.
+      enum:
+        - name: FlashModeNone
+          value: 0
+          description: |
+            Flash is off and inactive.
+        - name: FlashModeFlash
+          value: 1
+          description: |
+            The flash is active, but will only be switched on for a short time
+            by means of a trigger (software or external strobe). The maximum
+            switch-on time is limited by the FlashTimeout setting.
+        - name: FlashModeTorch
+          value: 2
+          description: |
+            The flash is continuously on and active. Commonly referred to as
+            torch or video light mode.
+
+  - FlashIntensity:
+      type: int32_t
+      direction: inout
+      description: |
+        Flash intensity in mA. Used when the flash is operated in flash mode.
+
+  - FlashTimeout:
+      type: int32_t
+      direction: inout
+      description: |
+        Flash timeout in us. Determines the maximum flash switch-on time. After
+        this time has elapsed, the flash is switched off by the hardware, even
+        if a strobe is still active.
+
+  - FlashStrobeSource:
+      type: int32_t
+      direction: inout
+      description: |
+        Flash strobe source.
+      enum:
+        - name: FlashStrobeSourceSoftware
+          value: 0
+          description: |
+            The strobe signal is controlled via software using the FlashStrobe
+            control.
+        - name: FlashStrobeSourceExternal
+          value: 1
+          description: |
+            The strobe signal is controlled by an external source. Typically,
+            this is done on the hardware by connecting the strobe source
+            directly to the flash controller.
+
+  - FlashStrobe:
+      type: int32_t
+      direction: in
+      description: |
+        Start/stop flash strobe. Only possible if FlashStrobeSourceSoftware is
+        selcted as FlashStrobeSource.
+
+      enum:
+        - name: FlashStrobeStart
+          value: 0
+          description: |
+            Start flash strobe.
+
+        - name: FlashStrobeStop
+          value: 1
+          description: |
+            Stop flash strobe.
+
+  - FlashTorchIntensity:
+      type: int32_t
+      direction: inout
+      description: |
+        Torch intensity in mA. Used when the flash is operated in torch mode.
+
 ...